You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-29 22:01:14 +03:00
Cut down a lot on compilation time
This commit is contained in:
@ -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<dyn Reply>,)> {
|
||||
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<Postgres>) -> Result<impl Reply, Rejection> {
|
||||
async fn get(mut conn: PoolConnection<Postgres>) -> Result<Box<dyn Reply>, Rejection> {
|
||||
sqlx::query("SELECT $1")
|
||||
.bind(1_i64)
|
||||
.execute(&mut conn)
|
||||
@ -35,5 +35,9 @@ async fn get(mut conn: PoolConnection<Postgres>) -> Result<impl Reply, Rejection
|
||||
.await
|
||||
.wrap_error()?;
|
||||
|
||||
Ok(with_header("ok", CONTENT_TYPE, TEXT_PLAIN.to_string()))
|
||||
Ok(Box::new(with_header(
|
||||
"ok",
|
||||
CONTENT_TYPE,
|
||||
TEXT_PLAIN.to_string(),
|
||||
)))
|
||||
}
|
||||
|
@ -40,16 +40,25 @@ pub fn root(
|
||||
templates: &Templates,
|
||||
config: &RootConfig,
|
||||
) -> 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()
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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 = ¶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<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)))
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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,
|
||||
}))
|
||||
})))
|
||||
}
|
||||
|
@ -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<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
) -> BoxedFilter<(Box<dyn Reply>,)> {
|
||||
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)]
|
||||
|
@ -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<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
) -> BoxedFilter<(Box<dyn Reply>,)> {
|
||||
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<BrowserSession<PostgresqlBackend>>,
|
||||
) -> Result<impl Reply, Rejection> {
|
||||
) -> Result<Box<dyn Reply>, Rejection> {
|
||||
let ctx = IndexContext::new(discovery_url)
|
||||
.maybe_with_session(maybe_session)
|
||||
.with_csrf(csrf_token.form_value());
|
||||
|
@ -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<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
) -> BoxedFilter<(Box<dyn Reply>,)> {
|
||||
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(
|
||||
|
@ -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<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
) -> BoxedFilter<(Box<dyn Reply>,)> {
|
||||
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<PostgresqlBackend>,
|
||||
mut txn: Transaction<'_, Postgres>,
|
||||
_form: (),
|
||||
) -> Result<impl Reply, Rejection> {
|
||||
) -> Result<Box<dyn Reply>, 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"))))
|
||||
}
|
||||
|
@ -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<dyn Reply>,)> {
|
||||
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()
|
||||
}
|
||||
|
@ -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<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
) -> BoxedFilter<(Box<dyn Reply>,)> {
|
||||
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<PostgresqlBackend>,
|
||||
query: ReauthRequest<PostgresqlBackend>,
|
||||
) -> Result<impl Reply, Rejection> {
|
||||
) -> Result<Box<dyn Reply>, 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<PostgresqlBackend>,
|
||||
) -> Result<impl Reply, Rejection> {
|
||||
) -> Result<Box<dyn Reply>, 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()?))
|
||||
}
|
||||
|
@ -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<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
) -> BoxedFilter<(Box<dyn Reply>,)> {
|
||||
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<PostgresqlBackend>,
|
||||
) -> Result<impl Reply, Rejection> {
|
||||
) -> Result<Box<dyn Reply>, 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))
|
||||
}
|
||||
|
@ -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<impl Reply, Rejection> {
|
||||
pub async fn recover_unauthorized(rejection: Rejection) -> Result<Box<dyn Reply>, Rejection> {
|
||||
if rejection.find::<AuthenticationError>().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)
|
||||
|
Reference in New Issue
Block a user