1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-08-06 06:02:40 +03:00

Simplify route error handling

This commit is contained in:
Quentin Gliech
2022-11-24 15:08:34 +01:00
parent 28bfce7e45
commit fcb6190a56
4 changed files with 45 additions and 128 deletions

View File

@@ -55,6 +55,19 @@ mod oauth2;
mod upstream_oauth2; mod upstream_oauth2;
mod views; mod views;
/// Implement `From<E>` for `RouteError`, for "internal server error" kind of
/// errors.
#[macro_export]
macro_rules! impl_from_error_for_route {
($error:ty) => {
impl From<$error> for self::RouteError {
fn from(e: $error) -> Self {
Self::InternalError(Box::new(e))
}
}
};
}
pub use mas_axum_utils::http_client_factory::HttpClientFactory; pub use mas_axum_utils::http_client_factory::HttpClientFactory;
pub use self::{app_state::AppState, compat::MatrixHomeserver, graphql::schema as graphql_schema}; pub use self::{app_state::AppState, compat::MatrixHomeserver, graphql::schema as graphql_schema};

View File

@@ -19,26 +19,21 @@ use axum::{
use axum_extra::extract::{cookie::Cookie, PrivateCookieJar}; use axum_extra::extract::{cookie::Cookie, PrivateCookieJar};
use hyper::StatusCode; use hyper::StatusCode;
use mas_axum_utils::http_client_factory::HttpClientFactory; use mas_axum_utils::http_client_factory::HttpClientFactory;
use mas_http::ClientInitError;
use mas_keystore::Encrypter; use mas_keystore::Encrypter;
use mas_oidc_client::{ use mas_oidc_client::requests::authorization_code::AuthorizationRequestData;
error::{AuthorizationError, DiscoveryError},
requests::authorization_code::AuthorizationRequestData,
};
use mas_router::UrlBuilder; use mas_router::UrlBuilder;
use mas_storage::{upstream_oauth2::lookup_provider, LookupResultExt}; use mas_storage::{upstream_oauth2::lookup_provider, LookupResultExt};
use sqlx::PgPool; use sqlx::PgPool;
use thiserror::Error; use thiserror::Error;
use ulid::Ulid; use ulid::Ulid;
use crate::impl_from_error_for_route;
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub(crate) enum RouteError { pub(crate) enum RouteError {
#[error("Provider not found")] #[error("Provider not found")]
ProviderNotFound, ProviderNotFound,
#[error(transparent)]
Authorization(#[from] AuthorizationError),
#[error(transparent)] #[error(transparent)]
InternalError(Box<dyn std::error::Error>), InternalError(Box<dyn std::error::Error>),
@@ -46,37 +41,16 @@ pub(crate) enum RouteError {
Anyhow(#[from] anyhow::Error), Anyhow(#[from] anyhow::Error),
} }
impl From<sqlx::Error> for RouteError { impl_from_error_for_route!(sqlx::Error);
fn from(e: sqlx::Error) -> Self { impl_from_error_for_route!(mas_http::ClientInitError);
Self::InternalError(Box::new(e)) impl_from_error_for_route!(mas_oidc_client::error::DiscoveryError);
} impl_from_error_for_route!(mas_oidc_client::error::AuthorizationError);
} impl_from_error_for_route!(mas_storage::upstream_oauth2::ProviderLookupError);
impl From<DiscoveryError> for RouteError {
fn from(e: DiscoveryError) -> Self {
Self::InternalError(Box::new(e))
}
}
impl From<mas_storage::upstream_oauth2::ProviderLookupError> for RouteError {
fn from(e: mas_storage::upstream_oauth2::ProviderLookupError) -> Self {
Self::InternalError(Box::new(e))
}
}
impl From<ClientInitError> for RouteError {
fn from(e: ClientInitError) -> Self {
Self::InternalError(Box::new(e))
}
}
impl IntoResponse for RouteError { impl IntoResponse for RouteError {
fn into_response(self) -> axum::response::Response { fn into_response(self) -> axum::response::Response {
match self { match self {
Self::ProviderNotFound => (StatusCode::NOT_FOUND, "Provider not found").into_response(), Self::ProviderNotFound => (StatusCode::NOT_FOUND, "Provider not found").into_response(),
Self::Authorization(e) => {
(StatusCode::INTERNAL_SERVER_ERROR, e.to_string()).into_response()
}
Self::InternalError(e) => { Self::InternalError(e) => {
(StatusCode::INTERNAL_SERVER_ERROR, e.to_string()).into_response() (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()).into_response()
} }

View File

@@ -19,17 +19,15 @@ use axum::{
use axum_extra::extract::PrivateCookieJar; use axum_extra::extract::PrivateCookieJar;
use hyper::StatusCode; use hyper::StatusCode;
use mas_axum_utils::http_client_factory::HttpClientFactory; use mas_axum_utils::http_client_factory::HttpClientFactory;
use mas_http::ClientInitError;
use mas_jose::claims::ClaimError; use mas_jose::claims::ClaimError;
use mas_keystore::{Encrypter, Keystore}; use mas_keystore::{Encrypter, Keystore};
use mas_oidc_client::{ use mas_oidc_client::requests::{
error::{DiscoveryError, JwksError, TokenAuthorizationCodeError}, authorization_code::AuthorizationValidationData, jose::JwtVerificationData,
requests::{authorization_code::AuthorizationValidationData, jose::JwtVerificationData},
}; };
use mas_router::{Route, UrlBuilder}; use mas_router::{Route, UrlBuilder};
use mas_storage::{ use mas_storage::{
upstream_oauth2::{add_link, complete_session, lookup_link_by_subject, lookup_session}, upstream_oauth2::{add_link, complete_session, lookup_link_by_subject, lookup_session},
GenericLookupError, LookupResultExt, LookupResultExt,
}; };
use oauth2_types::errors::ClientErrorCode; use oauth2_types::errors::ClientErrorCode;
use serde::Deserialize; use serde::Deserialize;
@@ -37,7 +35,8 @@ use sqlx::PgPool;
use thiserror::Error; use thiserror::Error;
use ulid::Ulid; use ulid::Ulid;
use super::{client_credentials_for_provider, ProviderCredentialsError}; use super::client_credentials_for_provider;
use crate::impl_from_error_for_route;
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct QueryParams { pub struct QueryParams {
@@ -100,53 +99,14 @@ pub(crate) enum RouteError {
Anyhow(#[from] anyhow::Error), Anyhow(#[from] anyhow::Error),
} }
impl From<GenericLookupError> for RouteError { impl_from_error_for_route!(mas_storage::GenericLookupError);
fn from(e: GenericLookupError) -> Self { impl_from_error_for_route!(mas_storage::upstream_oauth2::SessionLookupError);
Self::InternalError(Box::new(e)) impl_from_error_for_route!(mas_http::ClientInitError);
} impl_from_error_for_route!(sqlx::Error);
} impl_from_error_for_route!(mas_oidc_client::error::DiscoveryError);
impl_from_error_for_route!(mas_oidc_client::error::JwksError);
impl From<sqlx::Error> for RouteError { impl_from_error_for_route!(mas_oidc_client::error::TokenAuthorizationCodeError);
fn from(e: sqlx::Error) -> Self { impl_from_error_for_route!(super::ProviderCredentialsError);
Self::InternalError(Box::new(e))
}
}
impl From<DiscoveryError> for RouteError {
fn from(e: DiscoveryError) -> Self {
Self::InternalError(Box::new(e))
}
}
impl From<JwksError> for RouteError {
fn from(e: JwksError) -> Self {
Self::InternalError(Box::new(e))
}
}
impl From<TokenAuthorizationCodeError> for RouteError {
fn from(e: TokenAuthorizationCodeError) -> Self {
Self::InternalError(Box::new(e))
}
}
impl From<mas_storage::upstream_oauth2::SessionLookupError> for RouteError {
fn from(e: mas_storage::upstream_oauth2::SessionLookupError) -> Self {
Self::InternalError(Box::new(e))
}
}
impl From<ClientInitError> for RouteError {
fn from(e: ClientInitError) -> Self {
Self::InternalError(Box::new(e))
}
}
impl From<ProviderCredentialsError> for RouteError {
fn from(e: ProviderCredentialsError) -> Self {
Self::InternalError(Box::new(e))
}
}
impl IntoResponse for RouteError { impl IntoResponse for RouteError {
fn into_response(self) -> axum::response::Response { fn into_response(self) -> axum::response::Response {

View File

@@ -20,7 +20,7 @@ use axum::{
use axum_extra::extract::PrivateCookieJar; use axum_extra::extract::PrivateCookieJar;
use hyper::StatusCode; use hyper::StatusCode;
use mas_axum_utils::{ use mas_axum_utils::{
csrf::{CsrfError, CsrfExt, ProtectedForm}, csrf::{CsrfExt, ProtectedForm},
SessionInfoExt, SessionInfoExt,
}; };
use mas_keystore::Encrypter; use mas_keystore::Encrypter;
@@ -31,18 +31,17 @@ use mas_storage::{
}, },
user::{ user::{
authenticate_session_with_upstream, lookup_user, register_passwordless_user, start_session, authenticate_session_with_upstream, lookup_user, register_passwordless_user, start_session,
ActiveSessionLookupError, UserLookupError,
}, },
GenericLookupError, LookupResultExt, LookupResultExt,
};
use mas_templates::{
EmptyContext, TemplateContext, TemplateError, Templates, UpstreamExistingLinkContext,
}; };
use mas_templates::{EmptyContext, TemplateContext, Templates, UpstreamExistingLinkContext};
use serde::Deserialize; use serde::Deserialize;
use sqlx::PgPool; use sqlx::PgPool;
use thiserror::Error; use thiserror::Error;
use ulid::Ulid; use ulid::Ulid;
use crate::impl_from_error_for_route;
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub(crate) enum RouteError { pub(crate) enum RouteError {
/// Couldn't find the link specified in the URL /// Couldn't find the link specified in the URL
@@ -73,41 +72,12 @@ pub(crate) enum RouteError {
Anyhow(#[from] anyhow::Error), Anyhow(#[from] anyhow::Error),
} }
impl From<sqlx::Error> for RouteError { impl_from_error_for_route!(sqlx::Error);
fn from(e: sqlx::Error) -> Self { impl_from_error_for_route!(mas_templates::TemplateError);
Self::InternalError(Box::new(e)) impl_from_error_for_route!(mas_storage::GenericLookupError);
} impl_from_error_for_route!(mas_storage::user::ActiveSessionLookupError);
} impl_from_error_for_route!(mas_storage::user::UserLookupError);
impl_from_error_for_route!(mas_axum_utils::csrf::CsrfError);
impl From<TemplateError> for RouteError {
fn from(e: TemplateError) -> Self {
Self::InternalError(Box::new(e))
}
}
impl From<ActiveSessionLookupError> for RouteError {
fn from(e: ActiveSessionLookupError) -> Self {
Self::InternalError(Box::new(e))
}
}
impl From<CsrfError> for RouteError {
fn from(e: CsrfError) -> Self {
Self::InternalError(Box::new(e))
}
}
impl From<UserLookupError> for RouteError {
fn from(e: UserLookupError) -> Self {
Self::InternalError(Box::new(e))
}
}
impl From<GenericLookupError> for RouteError {
fn from(e: GenericLookupError) -> Self {
Self::InternalError(Box::new(e))
}
}
impl IntoResponse for RouteError { impl IntoResponse for RouteError {
fn into_response(self) -> axum::response::Response { fn into_response(self) -> axum::response::Response {