1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-11-20 12:02:22 +03:00

Cut down a lot on compilation time

This commit is contained in:
Quentin Gliech
2021-12-17 19:55:22 +01:00
parent 2f97ca685d
commit a55e8af2c8
17 changed files with 173 additions and 156 deletions

View File

@@ -62,6 +62,7 @@ use serde_json::Value;
use sqlx::{PgExecutor, PgPool, Postgres, Transaction};
use url::Url;
use warp::{
filters::BoxedFilter,
redirect::see_other,
reject::InvalidQuery,
reply::{html, with_header},
@@ -216,7 +217,7 @@ pub fn filter(
templates: &Templates,
oauth2_config: &OAuth2Config,
cookies_config: &CookiesConfig,
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
) -> BoxedFilter<(Box<dyn Reply>,)> {
let clients = oauth2_config.clients.clone();
let authorize = warp::path!("oauth2" / "authorize")
.and(warp::get())
@@ -243,6 +244,7 @@ pub fn filter(
.and(warp::any().map(move || clients.clone()))
.and(with_templates(templates))
.and_then(actually_reply)
.boxed()
}
async fn recover(rejection: Rejection) -> Result<ReplyOrBackToClient, Rejection> {
@@ -258,7 +260,7 @@ async fn actually_reply(
q: PartialParams,
clients: Vec<OAuth2ClientConfig>,
templates: Templates,
) -> Result<impl Reply, Rejection> {
) -> Result<Box<dyn Reply>, Rejection> {
let (redirect_uri, response_mode, state, params) = match rep {
ReplyOrBackToClient::Reply(r) => return Ok(r),
ReplyOrBackToClient::BackToClient {

View File

@@ -14,19 +14,15 @@
use std::collections::HashSet;
use hyper::Method;
use mas_config::OAuth2Config;
use mas_warp_utils::filters::cors::cors;
use oauth2_types::{
oidc::{Metadata, SigningAlgorithm},
pkce::CodeChallengeMethod,
requests::{ClientAuthenticationMethod, GrantType, ResponseMode},
};
use warp::{Filter, Rejection, Reply};
use warp::{filters::BoxedFilter, Filter, Reply};
pub(super) fn filter(
config: &OAuth2Config,
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
pub(super) fn filter(config: &OAuth2Config) -> BoxedFilter<(Box<dyn Reply>,)> {
let base = config.issuer.clone();
let response_modes_supported = Some({
@@ -97,9 +93,11 @@ pub(super) fn filter(
code_challenge_methods_supported,
};
warp::path!(".well-known" / "openid-configuration").and(
warp::get()
.map(move || warp::reply::json(&metadata))
.with(cors().allow_method(Method::GET)),
)
warp::path!(".well-known" / "openid-configuration")
.and(warp::get())
.map(move || {
let ret: Box<dyn Reply> = Box::new(warp::reply::json(&metadata));
ret
})
.boxed()
}

View File

@@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use hyper::Method;
use mas_config::{OAuth2ClientConfig, OAuth2Config};
use mas_data_model::TokenType;
use mas_storage::oauth2::{
@@ -20,33 +19,32 @@ use mas_storage::oauth2::{
};
use mas_warp_utils::{
errors::WrapError,
filters::{client::client_authentication, cors::cors, database::connection},
filters::{client::client_authentication, database::connection},
};
use oauth2_types::requests::{
ClientAuthenticationMethod, IntrospectionRequest, IntrospectionResponse, TokenTypeHint,
};
use sqlx::{pool::PoolConnection, PgPool, Postgres};
use tracing::{info, warn};
use warp::{Filter, Rejection, Reply};
use warp::{filters::BoxedFilter, Filter, Rejection, Reply};
pub fn filter(
pool: &PgPool,
oauth2_config: &OAuth2Config,
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
pub fn filter(pool: &PgPool, oauth2_config: &OAuth2Config) -> BoxedFilter<(Box<dyn Reply>,)> {
let audience = oauth2_config
.issuer
.join("/oauth2/introspect")
.unwrap()
.to_string();
warp::path!("oauth2" / "introspect").and(
warp::post()
.and(connection(pool))
.and(client_authentication(oauth2_config, audience))
.and_then(introspect)
.recover(recover)
.with(cors().allow_method(Method::POST)),
)
warp::path!("oauth2" / "introspect")
.and(
warp::post()
.and(connection(pool))
.and(client_authentication(oauth2_config, audience))
.and_then(introspect)
.recover(recover)
.unify(),
)
.boxed()
}
const INACTIVE: IntrospectionResponse = IntrospectionResponse {
@@ -69,12 +67,12 @@ async fn introspect(
auth: ClientAuthenticationMethod,
client: OAuth2ClientConfig,
params: IntrospectionRequest,
) -> Result<impl Reply, Rejection> {
) -> Result<Box<dyn Reply>, Rejection> {
// Token introspection is only allowed by confidential clients
if auth.public() {
warn!(?client, "Client tried to introspect");
// TODO: have a nice error here
return Ok(warp::reply::json(&INACTIVE));
return Ok(Box::new(warp::reply::json(&INACTIVE)));
}
let token = &params.token;
@@ -82,7 +80,7 @@ async fn introspect(
if let Some(hint) = params.token_type_hint {
if token_type != hint {
info!("Token type hint did not match");
return Ok(warp::reply::json(&INACTIVE));
return Ok(Box::new(warp::reply::json(&INACTIVE)));
}
}
@@ -130,13 +128,13 @@ async fn introspect(
}
};
Ok(warp::reply::json(&reply))
Ok(Box::new(warp::reply::json(&reply)))
}
async fn recover(rejection: Rejection) -> Result<impl Reply, Rejection> {
async fn recover(rejection: Rejection) -> Result<Box<dyn Reply>, Rejection> {
if rejection.is_not_found() {
Err(rejection)
} else {
Ok(warp::reply::json(&INACTIVE))
Ok(Box::new(warp::reply::json(&INACTIVE)))
}
}

View File

@@ -12,19 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use hyper::Method;
use mas_config::OAuth2Config;
use mas_warp_utils::filters::cors::cors;
use warp::{Filter, Rejection, Reply};
use warp::{filters::BoxedFilter, Filter, Reply};
pub(super) fn filter(
config: &OAuth2Config,
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
pub(super) fn filter(config: &OAuth2Config) -> BoxedFilter<(Box<dyn Reply>,)> {
let jwks = config.keys.to_public_jwks();
warp::path!("oauth2" / "keys.json").and(
warp::get()
.map(move || warp::reply::json(&jwks))
.with(cors().allow_method(Method::GET)),
)
warp::path!("oauth2" / "keys.json")
.and(warp::get().map(move || {
let ret: Box<dyn Reply> = Box::new(warp::reply::json(&jwks));
ret
}))
.boxed()
}

View File

@@ -12,8 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use hyper::Method;
use mas_config::{CookiesConfig, OAuth2Config};
use mas_templates::Templates;
use mas_warp_utils::filters::cors::cors;
use sqlx::PgPool;
use warp::{filters::BoxedFilter, Filter, Reply};
@@ -37,16 +39,28 @@ pub fn filter(
oauth2_config: &OAuth2Config,
cookies_config: &CookiesConfig,
) -> BoxedFilter<(impl Reply,)> {
discovery(oauth2_config)
.or(keys(oauth2_config))
.or(authorization(
pool,
templates,
oauth2_config,
cookies_config,
))
.or(userinfo(pool, oauth2_config))
.or(introspection(pool, oauth2_config))
.or(token(pool, oauth2_config))
let discovery = discovery(oauth2_config);
let keys = keys(oauth2_config);
let authorization = authorization(pool, templates, oauth2_config, cookies_config);
let userinfo = userinfo(pool, oauth2_config);
let introspection = introspection(pool, oauth2_config);
let token = token(pool, oauth2_config);
let filter = discovery
.or(keys)
.unify()
.boxed()
.or(userinfo)
.unify()
.boxed()
.or(token)
.unify()
.boxed()
.or(introspection)
.unify()
.boxed()
.with(cors().allow_methods([Method::POST, Method::GET]))
.boxed();
filter.or(authorization).boxed()
}

View File

@@ -16,7 +16,7 @@ use anyhow::Context;
use chrono::{DateTime, Duration, Utc};
use data_encoding::BASE64URL_NOPAD;
use headers::{CacheControl, Pragma};
use hyper::{Method, StatusCode};
use hyper::StatusCode;
use jwt_compact::{Claims, Header, TimeOptions};
use mas_config::{KeySet, OAuth2ClientConfig, OAuth2Config};
use mas_data_model::{AuthorizationGrantStage, TokenType};
@@ -30,7 +30,7 @@ use mas_storage::{
};
use mas_warp_utils::{
errors::WrapError,
filters::{client::client_authentication, cors::cors, database::connection, with_keys},
filters::{client::client_authentication, database::connection, with_keys},
reply::with_typed_header,
};
use oauth2_types::{
@@ -49,6 +49,7 @@ use sqlx::{pool::PoolConnection, Acquire, PgPool, Postgres};
use tracing::debug;
use url::Url;
use warp::{
filters::BoxedFilter,
reject::Reject,
reply::{json, with_status},
Filter, Rejection, Reply,
@@ -88,10 +89,7 @@ where
Err(Error { json, status }.into())
}
pub fn filter(
pool: &PgPool,
oauth2_config: &OAuth2Config,
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
pub fn filter(pool: &PgPool, oauth2_config: &OAuth2Config) -> BoxedFilter<(Box<dyn Reply>,)> {
let audience = oauth2_config
.issuer
.join("/oauth2/token")
@@ -99,21 +97,23 @@ pub fn filter(
.to_string();
let issuer = oauth2_config.issuer.clone();
warp::path!("oauth2" / "token").and(
warp::post()
.and(client_authentication(oauth2_config, audience))
.and(with_keys(oauth2_config))
.and(warp::any().map(move || issuer.clone()))
.and(connection(pool))
.and_then(token)
.recover(recover)
.with(cors().allow_method(Method::POST)),
)
warp::path!("oauth2" / "token")
.and(
warp::post()
.and(client_authentication(oauth2_config, audience))
.and(with_keys(oauth2_config))
.and(warp::any().map(move || issuer.clone()))
.and(connection(pool))
.and_then(token)
.recover(recover)
.unify(),
)
.boxed()
}
async fn recover(rejection: Rejection) -> Result<impl Reply, Rejection> {
async fn recover(rejection: Rejection) -> Result<Box<dyn Reply>, Rejection> {
if let Some(Error { json, status }) = rejection.find::<Error>() {
Ok(with_status(warp::reply::json(json), *status))
Ok(Box::new(with_status(warp::reply::json(json), *status)))
} else {
Err(rejection)
}
@@ -126,7 +126,7 @@ async fn token(
keys: KeySet,
issuer: Url,
mut conn: PoolConnection<Postgres>,
) -> Result<impl Reply, Rejection> {
) -> Result<Box<dyn Reply>, Rejection> {
let reply = match req {
AccessTokenRequest::AuthorizationCode(grant) => {
let reply = authorization_code_grant(&grant, &client, &keys, issuer, &mut conn).await?;
@@ -144,7 +144,7 @@ async fn token(
let reply = with_typed_header(CacheControl::new().with_no_store(), reply);
let reply = with_typed_header(Pragma::no_cache(), reply);
Ok(reply)
Ok(Box::new(reply))
}
fn hash<H: Digest>(mut hasher: H, token: &str) -> anyhow::Result<String> {

View File

@@ -12,17 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use hyper::Method;
use mas_config::OAuth2Config;
use mas_data_model::{AccessToken, Session};
use mas_storage::PostgresqlBackend;
use mas_warp_utils::filters::{
authenticate::{authentication, recover_unauthorized},
cors::cors,
};
use mas_warp_utils::filters::authenticate::{authentication, recover_unauthorized};
use serde::Serialize;
use sqlx::PgPool;
use warp::{Filter, Rejection, Reply};
use warp::{filters::BoxedFilter, Filter, Rejection, Reply};
#[derive(Serialize)]
struct UserInfo {
@@ -30,28 +26,27 @@ struct UserInfo {
username: String,
}
pub(super) fn filter(
pool: &PgPool,
_config: &OAuth2Config,
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
warp::path!("oauth2" / "userinfo").and(
warp::get()
.or(warp::post())
.unify()
.and(authentication(pool))
.and_then(userinfo)
.recover(recover_unauthorized)
.with(cors().allow_methods([Method::GET, Method::POST])),
)
pub(super) fn filter(pool: &PgPool, _config: &OAuth2Config) -> BoxedFilter<(Box<dyn Reply>,)> {
warp::path!("oauth2" / "userinfo")
.and(
warp::get()
.or(warp::post())
.unify()
.and(authentication(pool))
.and_then(userinfo)
.recover(recover_unauthorized)
.unify(),
)
.boxed()
}
async fn userinfo(
_token: AccessToken<PostgresqlBackend>,
session: Session<PostgresqlBackend>,
) -> Result<impl Reply, Rejection> {
) -> Result<Box<dyn Reply>, Rejection> {
let user = session.browser_session.user;
Ok(warp::reply::json(&UserInfo {
Ok(Box::new(warp::reply::json(&UserInfo {
sub: user.sub,
username: user.username,
}))
})))
}