From a55e8af2c8643e956fab377d9ca7898caaa70ff9 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Fri, 17 Dec 2021 19:55:22 +0100 Subject: [PATCH] Cut down a lot on compilation time --- crates/handlers/src/health.rs | 10 +++-- crates/handlers/src/lib.rs | 31 +++++++++----- crates/handlers/src/oauth2/authorization.rs | 6 ++- crates/handlers/src/oauth2/discovery.rs | 20 +++++----- crates/handlers/src/oauth2/introspection.rs | 40 +++++++++---------- crates/handlers/src/oauth2/keys.rs | 19 ++++----- crates/handlers/src/oauth2/mod.rs | 36 ++++++++++++----- crates/handlers/src/oauth2/token.rs | 40 +++++++++---------- crates/handlers/src/oauth2/userinfo.rs | 39 ++++++++---------- crates/handlers/src/views/account.rs | 18 +++------ crates/handlers/src/views/index.rs | 7 ++-- crates/handlers/src/views/login.rs | 6 +-- crates/handlers/src/views/logout.rs | 9 +++-- crates/handlers/src/views/mod.rs | 20 ++++++---- crates/handlers/src/views/reauth.rs | 14 +++---- crates/handlers/src/views/register.rs | 10 ++--- crates/warp-utils/src/filters/authenticate.rs | 4 +- 17 files changed, 173 insertions(+), 156 deletions(-) diff --git a/crates/handlers/src/health.rs b/crates/handlers/src/health.rs index 54c81942..13c49457 100644 --- a/crates/handlers/src/health.rs +++ b/crates/handlers/src/health.rs @@ -19,7 +19,7 @@ use sqlx::{pool::PoolConnection, PgPool, Postgres}; use tracing::{info_span, Instrument}; use warp::{filters::BoxedFilter, reply::with_header, Filter, Rejection, Reply}; -pub fn filter(pool: &PgPool) -> BoxedFilter<(impl Reply,)> { +pub fn filter(pool: &PgPool) -> BoxedFilter<(Box,)> { warp::path!("health") .and(warp::get()) .and(connection(pool)) @@ -27,7 +27,7 @@ pub fn filter(pool: &PgPool) -> BoxedFilter<(impl Reply,)> { .boxed() } -async fn get(mut conn: PoolConnection) -> Result { +async fn get(mut conn: PoolConnection) -> Result, Rejection> { sqlx::query("SELECT $1") .bind(1_i64) .execute(&mut conn) @@ -35,5 +35,9 @@ async fn get(mut conn: PoolConnection) -> Result BoxedFilter<(impl Reply,)> { - health(pool) - .or(oauth2(pool, templates, &config.oauth2, &config.cookies)) - .or(views( - pool, - templates, - &config.oauth2, - &config.csrf, - &config.cookies, - )) - .or(static_files(config.http.web_root.clone())) - .with(warp::log(module_path!())) + let health = health(pool); + let oauth2 = oauth2(pool, templates, &config.oauth2, &config.cookies); + let views = views( + pool, + templates, + &config.oauth2, + &config.csrf, + &config.cookies, + ); + let static_files = static_files(config.http.web_root.clone()); + + let filter = health + .or(views) + .unify() + .or(static_files) + .unify() .boxed() + .or(oauth2) + .boxed(); + + filter.with(warp::log(module_path!())).boxed() } diff --git a/crates/handlers/src/oauth2/authorization.rs b/crates/handlers/src/oauth2/authorization.rs index 675493f3..7c658335 100644 --- a/crates/handlers/src/oauth2/authorization.rs +++ b/crates/handlers/src/oauth2/authorization.rs @@ -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 + Clone + Send + Sync + 'static { +) -> BoxedFilter<(Box,)> { 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 { @@ -258,7 +260,7 @@ async fn actually_reply( q: PartialParams, clients: Vec, templates: Templates, -) -> Result { +) -> Result, Rejection> { let (redirect_uri, response_mode, state, params) = match rep { ReplyOrBackToClient::Reply(r) => return Ok(r), ReplyOrBackToClient::BackToClient { diff --git a/crates/handlers/src/oauth2/discovery.rs b/crates/handlers/src/oauth2/discovery.rs index 5ec8b906..de36c479 100644 --- a/crates/handlers/src/oauth2/discovery.rs +++ b/crates/handlers/src/oauth2/discovery.rs @@ -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 + Clone + Send + Sync + 'static { +pub(super) fn filter(config: &OAuth2Config) -> BoxedFilter<(Box,)> { 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 = Box::new(warp::reply::json(&metadata)); + ret + }) + .boxed() } diff --git a/crates/handlers/src/oauth2/introspection.rs b/crates/handlers/src/oauth2/introspection.rs index 846def5c..8a043b6d 100644 --- a/crates/handlers/src/oauth2/introspection.rs +++ b/crates/handlers/src/oauth2/introspection.rs @@ -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 + Clone + Send + Sync + 'static { +pub fn filter(pool: &PgPool, oauth2_config: &OAuth2Config) -> BoxedFilter<(Box,)> { 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 { +) -> Result, 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 = ¶ms.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 { +async fn recover(rejection: Rejection) -> Result, Rejection> { if rejection.is_not_found() { Err(rejection) } else { - Ok(warp::reply::json(&INACTIVE)) + Ok(Box::new(warp::reply::json(&INACTIVE))) } } diff --git a/crates/handlers/src/oauth2/keys.rs b/crates/handlers/src/oauth2/keys.rs index 15263880..8cec8607 100644 --- a/crates/handlers/src/oauth2/keys.rs +++ b/crates/handlers/src/oauth2/keys.rs @@ -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 + Clone + Send + Sync + 'static { +pub(super) fn filter(config: &OAuth2Config) -> BoxedFilter<(Box,)> { 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 = Box::new(warp::reply::json(&jwks)); + ret + })) + .boxed() } diff --git a/crates/handlers/src/oauth2/mod.rs b/crates/handlers/src/oauth2/mod.rs index 9631caf4..eaa60998 100644 --- a/crates/handlers/src/oauth2/mod.rs +++ b/crates/handlers/src/oauth2/mod.rs @@ -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() } diff --git a/crates/handlers/src/oauth2/token.rs b/crates/handlers/src/oauth2/token.rs index 4708ff16..538f8cc1 100644 --- a/crates/handlers/src/oauth2/token.rs +++ b/crates/handlers/src/oauth2/token.rs @@ -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 + Clone + Send + Sync + 'static { +pub fn filter(pool: &PgPool, oauth2_config: &OAuth2Config) -> BoxedFilter<(Box,)> { 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 { +async fn recover(rejection: Rejection) -> Result, Rejection> { if let Some(Error { json, status }) = rejection.find::() { - 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, -) -> Result { +) -> Result, 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(mut hasher: H, token: &str) -> anyhow::Result { diff --git a/crates/handlers/src/oauth2/userinfo.rs b/crates/handlers/src/oauth2/userinfo.rs index 713873f0..63e6eb19 100644 --- a/crates/handlers/src/oauth2/userinfo.rs +++ b/crates/handlers/src/oauth2/userinfo.rs @@ -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 + 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,)> { + 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, session: Session, -) -> Result { +) -> Result, 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, - })) + }))) } diff --git a/crates/handlers/src/views/account.rs b/crates/handlers/src/views/account.rs index 86ac20bc..0e274932 100644 --- a/crates/handlers/src/views/account.rs +++ b/crates/handlers/src/views/account.rs @@ -32,23 +32,20 @@ use mas_warp_utils::{ }; use serde::Deserialize; use sqlx::{pool::PoolConnection, PgExecutor, PgPool, Postgres, Transaction}; -use warp::{reply::html, Filter, Rejection, Reply}; +use warp::{filters::BoxedFilter, reply::html, Filter, Rejection, Reply}; pub(super) fn filter( pool: &PgPool, templates: &Templates, csrf_config: &CsrfConfig, cookies_config: &CookiesConfig, -) -> impl Filter + Clone + Send + Sync + 'static { +) -> BoxedFilter<(Box,)> { let get = with_templates(templates) .and(encrypted_cookie_saver(cookies_config)) .and(updated_csrf_token(cookies_config, csrf_config)) .and(session(pool, cookies_config)) .and(connection(pool)) - .and_then(get) - .with(warp::filters::trace::trace(|_info| { - tracing::info_span!("GET /account") - })); + .and_then(get); let post = with_templates(templates) .and(encrypted_cookie_saver(cookies_config)) @@ -56,14 +53,11 @@ pub(super) fn filter( .and(session(pool, cookies_config)) .and(transaction(pool)) .and(protected_form(cookies_config)) - .and_then(post) - .with(warp::filters::trace::trace(|_info| { - tracing::info_span!("POST /account") - })); + .and_then(post); - let filter = warp::get().and(get).or(warp::post().and(post)); + let filter = warp::get().and(get).or(warp::post().and(post)).unify(); - warp::path!("account").and(filter) + warp::path!("account").and(filter).boxed() } #[derive(Deserialize)] diff --git a/crates/handlers/src/views/index.rs b/crates/handlers/src/views/index.rs index 24c2d1ef..cf49758c 100644 --- a/crates/handlers/src/views/index.rs +++ b/crates/handlers/src/views/index.rs @@ -24,7 +24,7 @@ use mas_warp_utils::filters::{ }; use sqlx::PgPool; use url::Url; -use warp::{reply::html, Filter, Rejection, Reply}; +use warp::{filters::BoxedFilter, reply::html, Filter, Rejection, Reply}; pub(super) fn filter( pool: &PgPool, @@ -32,7 +32,7 @@ pub(super) fn filter( oauth2_config: &OAuth2Config, csrf_config: &CsrfConfig, cookies_config: &CookiesConfig, -) -> impl Filter + Clone + Send + Sync + 'static { +) -> BoxedFilter<(Box,)> { let discovery_url = oauth2_config.discovery_url(); warp::path::end() .and(warp::get()) @@ -42,6 +42,7 @@ pub(super) fn filter( .and(updated_csrf_token(cookies_config, csrf_config)) .and(optional_session(pool, cookies_config)) .and_then(get) + .boxed() } async fn get( @@ -50,7 +51,7 @@ async fn get( cookie_saver: EncryptedCookieSaver, csrf_token: CsrfToken, maybe_session: Option>, -) -> Result { +) -> Result, Rejection> { let ctx = IndexContext::new(discovery_url) .maybe_with_session(maybe_session) .with_csrf(csrf_token.form_value()); diff --git a/crates/handlers/src/views/login.rs b/crates/handlers/src/views/login.rs index 35192f2a..eaeda5d4 100644 --- a/crates/handlers/src/views/login.rs +++ b/crates/handlers/src/views/login.rs @@ -29,7 +29,7 @@ use mas_warp_utils::{ }; use serde::Deserialize; use sqlx::{pool::PoolConnection, PgPool, Postgres}; -use warp::{reply::html, Filter, Rejection, Reply}; +use warp::{filters::BoxedFilter, reply::html, Filter, Rejection, Reply}; use super::{shared::PostAuthAction, RegisterRequest}; @@ -94,7 +94,7 @@ pub(super) fn filter( templates: &Templates, csrf_config: &CsrfConfig, cookies_config: &CookiesConfig, -) -> impl Filter + Clone + Send + Sync + 'static { +) -> BoxedFilter<(Box,)> { let get = warp::get() .and(with_templates(templates)) .and(connection(pool)) @@ -113,7 +113,7 @@ pub(super) fn filter( .and(warp::query()) .and_then(post); - warp::path!("login").and(get.or(post)) + warp::path!("login").and(get.or(post).unify()).boxed() } async fn get( diff --git a/crates/handlers/src/views/logout.rs b/crates/handlers/src/views/logout.rs index 733db519..5526bc71 100644 --- a/crates/handlers/src/views/logout.rs +++ b/crates/handlers/src/views/logout.rs @@ -20,27 +20,28 @@ use mas_warp_utils::{ filters::{csrf::protected_form, database::transaction, session::session}, }; use sqlx::{PgPool, Postgres, Transaction}; -use warp::{hyper::Uri, Filter, Rejection, Reply}; +use warp::{filters::BoxedFilter, hyper::Uri, Filter, Rejection, Reply}; pub(super) fn filter( pool: &PgPool, cookies_config: &CookiesConfig, -) -> impl Filter + Clone + Send + Sync + 'static { +) -> BoxedFilter<(Box,)> { warp::path!("logout") .and(warp::post()) .and(session(pool, cookies_config)) .and(transaction(pool)) .and(protected_form(cookies_config)) .and_then(post) + .boxed() } async fn post( session: BrowserSession, mut txn: Transaction<'_, Postgres>, _form: (), -) -> Result { +) -> Result, Rejection> { end_session(&mut txn, &session).await.wrap_error()?; txn.commit().await.wrap_error()?; - Ok(warp::redirect(Uri::from_static("/login"))) + Ok(Box::new(warp::redirect(Uri::from_static("/login")))) } diff --git a/crates/handlers/src/views/mod.rs b/crates/handlers/src/views/mod.rs index cc2994a6..5f1a417b 100644 --- a/crates/handlers/src/views/mod.rs +++ b/crates/handlers/src/views/mod.rs @@ -39,12 +39,16 @@ pub(super) fn filter( oauth2_config: &OAuth2Config, csrf_config: &CsrfConfig, cookies_config: &CookiesConfig, -) -> BoxedFilter<(impl Reply,)> { - index(pool, templates, oauth2_config, csrf_config, cookies_config) - .or(account(pool, templates, csrf_config, cookies_config)) - .or(login(pool, templates, csrf_config, cookies_config)) - .or(register(pool, templates, csrf_config, cookies_config)) - .or(logout(pool, cookies_config)) - .or(reauth(pool, templates, csrf_config, cookies_config)) - .boxed() +) -> BoxedFilter<(Box,)> { + let index = index(pool, templates, oauth2_config, csrf_config, cookies_config); + let account = account(pool, templates, csrf_config, cookies_config); + let login = login(pool, templates, csrf_config, cookies_config); + let register = register(pool, templates, csrf_config, cookies_config); + let logout = logout(pool, cookies_config); + let reauth = reauth(pool, templates, csrf_config, cookies_config); + + let f1 = index.or(account).unify().boxed(); + let f2 = login.or(register).unify().boxed(); + let f3 = logout.or(reauth).unify().boxed(); + f1.or(f2).unify().or(f3).unify().boxed() } diff --git a/crates/handlers/src/views/reauth.rs b/crates/handlers/src/views/reauth.rs index 9be387ac..37132ee9 100644 --- a/crates/handlers/src/views/reauth.rs +++ b/crates/handlers/src/views/reauth.rs @@ -29,7 +29,7 @@ use mas_warp_utils::{ }; use serde::Deserialize; use sqlx::{pool::PoolConnection, PgPool, Postgres, Transaction}; -use warp::{hyper::Uri, reply::html, Filter, Rejection, Reply}; +use warp::{filters::BoxedFilter, hyper::Uri, reply::html, Filter, Rejection, Reply}; use super::PostAuthAction; @@ -93,7 +93,7 @@ pub(super) fn filter( templates: &Templates, csrf_config: &CsrfConfig, cookies_config: &CookiesConfig, -) -> impl Filter + Clone + Send + Sync + 'static { +) -> BoxedFilter<(Box,)> { let get = warp::get() .and(with_templates(templates)) .and(connection(pool)) @@ -110,7 +110,7 @@ pub(super) fn filter( .and(warp::query()) .and_then(post); - warp::path!("reauth").and(get.or(post)) + warp::path!("reauth").and(get.or(post).unify()).boxed() } async fn get( @@ -120,7 +120,7 @@ async fn get( csrf_token: CsrfToken, session: BrowserSession, query: ReauthRequest, -) -> Result { +) -> Result, Rejection> { let ctx = ReauthContext::default(); let ctx = match query.post_auth_action { Some(next) => { @@ -134,7 +134,7 @@ async fn get( let content = templates.render_reauth(&ctx).await?; let reply = html(content); let reply = cookie_saver.save_encrypted(&csrf_token, reply)?; - Ok(reply) + Ok(Box::new(reply)) } async fn post( @@ -142,12 +142,12 @@ async fn post( mut txn: Transaction<'_, Postgres>, form: ReauthForm, query: ReauthRequest, -) -> Result { +) -> Result, Rejection> { // TODO: recover from errors here authenticate_session(&mut txn, &mut session, form.password) .await .wrap_error()?; txn.commit().await.wrap_error()?; - Ok(query.redirect()?) + Ok(Box::new(query.redirect()?)) } diff --git a/crates/handlers/src/views/register.rs b/crates/handlers/src/views/register.rs index 1c7b6aa2..76146f07 100644 --- a/crates/handlers/src/views/register.rs +++ b/crates/handlers/src/views/register.rs @@ -33,7 +33,7 @@ use mas_warp_utils::{ }; use serde::Deserialize; use sqlx::{pool::PoolConnection, PgPool, Postgres, Transaction}; -use warp::{reply::html, Filter, Rejection, Reply}; +use warp::{filters::BoxedFilter, reply::html, Filter, Rejection, Reply}; use super::{LoginRequest, PostAuthAction}; @@ -100,7 +100,7 @@ pub(super) fn filter( templates: &Templates, csrf_config: &CsrfConfig, cookies_config: &CookiesConfig, -) -> impl Filter + Clone + Send + Sync + 'static { +) -> BoxedFilter<(Box,)> { let get = warp::get() .and(with_templates(templates)) .and(connection(pool)) @@ -117,7 +117,7 @@ pub(super) fn filter( .and(warp::query()) .and_then(post); - warp::path!("register").and(get.or(post)) + warp::path!("register").and(get.or(post).unify()).boxed() } async fn get( @@ -154,7 +154,7 @@ async fn post( cookie_saver: EncryptedCookieSaver, form: RegisterForm, query: RegisterRequest, -) -> Result { +) -> Result, Rejection> { // TODO: display nice form errors if form.password != form.password_confirm { return Err(anyhow::anyhow!("password mismatch")).wrap_error(); @@ -172,5 +172,5 @@ async fn post( let session_cookie = SessionCookie::from_session(&session_info); let reply = query.redirect()?; let reply = cookie_saver.save_encrypted(&session_cookie, reply)?; - Ok(reply) + Ok(Box::new(reply)) } diff --git a/crates/warp-utils/src/filters/authenticate.rs b/crates/warp-utils/src/filters/authenticate.rs index af728fbc..6d09159d 100644 --- a/crates/warp-utils/src/filters/authenticate.rs +++ b/crates/warp-utils/src/filters/authenticate.rs @@ -136,13 +136,13 @@ async fn recover( /// per [RFC6750]. This is not intended for user-facing endpoints. /// /// [RFC6750]: https://www.rfc-editor.org/rfc/rfc6750.html -pub async fn recover_unauthorized(rejection: Rejection) -> Result { +pub async fn recover_unauthorized(rejection: Rejection) -> Result, Rejection> { if rejection.find::().is_some() { // TODO: have the issuer/realm here let reply = "invalid token"; let reply = with_status(reply, StatusCode::UNAUTHORIZED); let reply = with_header(reply, "WWW-Authenticate", r#"Bearer error="invalid_token""#); - return Ok(reply); + return Ok(Box::new(reply)); } Err(rejection)