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

storage: unify most of the remaining errors

This commit is contained in:
Quentin Gliech
2022-12-08 12:19:28 +01:00
parent 102571512e
commit a836cc864a
14 changed files with 238 additions and 133 deletions

View File

@@ -47,6 +47,9 @@ pub enum RouteError {
#[error(transparent)]
Anyhow(#[from] anyhow::Error),
#[error("authorization grant was not found")]
NotFound,
#[error("authorization grant is not in a pending state")]
NotPending,
}
@@ -55,6 +58,9 @@ impl IntoResponse for RouteError {
fn into_response(self) -> axum::response::Response {
// TODO: better error pages
match self {
RouteError::NotFound => {
(StatusCode::NOT_FOUND, "authorization grant was not found").into_response()
}
RouteError::NotPending => (
StatusCode::BAD_REQUEST,
"authorization grant not in a pending state",
@@ -88,10 +94,12 @@ pub(crate) async fn get(
let maybe_session = session_info.load_session(&mut txn).await?;
let grant = get_grant_by_id(&mut txn, grant_id).await?;
let grant = get_grant_by_id(&mut txn, grant_id)
.await?
.ok_or(RouteError::NotFound)?;
let callback_destination = CallbackDestination::try_from(&grant)?;
let continue_grant = PostAuthAction::continue_grant(grant_id);
let continue_grant = PostAuthAction::continue_grant(grant.id);
let session = if let Some(session) = maybe_session {
session
@@ -143,6 +151,7 @@ pub enum GrantCompletionError {
}
impl_from_error_for_route!(GrantCompletionError: sqlx::Error);
impl_from_error_for_route!(GrantCompletionError: mas_storage::DatabaseError);
impl_from_error_for_route!(GrantCompletionError: super::callback::IntoCallbackDestinationError);
pub(crate) async fn complete(

View File

@@ -14,7 +14,6 @@
use std::sync::Arc;
use anyhow::Context;
use axum::{
extract::{Form, Path, State},
response::{Html, IntoResponse, Response},
@@ -38,12 +37,33 @@ use sqlx::PgPool;
use thiserror::Error;
use ulid::Ulid;
use crate::impl_from_error_for_route;
#[derive(Debug, Error)]
pub enum RouteError {
#[error(transparent)]
Internal(Box<dyn std::error::Error + Send + Sync>),
#[error(transparent)]
Anyhow(#[from] anyhow::Error),
#[error(transparent)]
Csrf(#[from] mas_axum_utils::csrf::CsrfError),
#[error("Authorization grant not found")]
GrantNotFound,
#[error("Authorization grant already used")]
GrantNotPending,
#[error("Policy violation")]
PolicyViolation,
}
impl_from_error_for_route!(sqlx::Error);
impl_from_error_for_route!(mas_templates::TemplateError);
impl_from_error_for_route!(mas_storage::DatabaseError);
impl IntoResponse for RouteError {
fn into_response(self) -> axum::response::Response {
StatusCode::INTERNAL_SERVER_ERROR.into_response()
@@ -58,22 +78,18 @@ pub(crate) async fn get(
Path(grant_id): Path<Ulid>,
) -> Result<Response, RouteError> {
let (clock, mut rng) = crate::rng_and_clock()?;
let mut conn = pool
.acquire()
.await
.context("failed to acquire db connection")?;
let mut conn = pool.acquire().await?;
let (session_info, cookie_jar) = cookie_jar.session_info();
let maybe_session = session_info
.load_session(&mut conn)
.await
.context("could not load session")?;
let maybe_session = session_info.load_session(&mut conn).await?;
let grant = get_grant_by_id(&mut conn, grant_id).await?;
let grant = get_grant_by_id(&mut conn, grant_id)
.await?
.ok_or(RouteError::GrantNotFound)?;
if !matches!(grant.stage, AuthorizationGrantStage::Pending) {
return Err(anyhow::anyhow!("authorization grant not pending").into());
return Err(RouteError::GrantNotPending);
}
if let Some(session) = maybe_session {
@@ -89,10 +105,7 @@ pub(crate) async fn get(
.with_session(session)
.with_csrf(csrf_token.form_value());
let content = templates
.render_consent(&ctx)
.await
.context("failed to render template")?;
let content = templates.render_consent(&ctx).await?;
Ok((cookie_jar, Html(content)).into_response())
} else {
@@ -100,10 +113,7 @@ pub(crate) async fn get(
.with_session(session)
.with_csrf(csrf_token.form_value());
let content = templates
.render_policy_violation(&ctx)
.await
.context("failed to render template")?;
let content = templates.render_policy_violation(&ctx).await?;
Ok((cookie_jar, Html(content)).into_response())
}
@@ -121,23 +131,17 @@ pub(crate) async fn post(
Form(form): Form<ProtectedForm<()>>,
) -> Result<Response, RouteError> {
let (clock, mut rng) = crate::rng_and_clock()?;
let mut txn = pool
.begin()
.await
.context("failed to begin db transaction")?;
let mut txn = pool.begin().await?;
cookie_jar
.verify_form(clock.now(), form)
.context("csrf verification failed")?;
cookie_jar.verify_form(clock.now(), form)?;
let (session_info, cookie_jar) = cookie_jar.session_info();
let maybe_session = session_info
.load_session(&mut txn)
.await
.context("could not load session")?;
let maybe_session = session_info.load_session(&mut txn).await?;
let grant = get_grant_by_id(&mut txn, grant_id).await?;
let grant = get_grant_by_id(&mut txn, grant_id)
.await?
.ok_or(RouteError::GrantNotFound)?;
let next = PostAuthAction::continue_grant(grant_id);
let session = if let Some(session) = maybe_session {
@@ -153,7 +157,7 @@ pub(crate) async fn post(
.await?;
if !res.valid() {
return Err(anyhow::anyhow!("policy violation").into());
return Err(RouteError::PolicyViolation);
}
// Do not consent for the "urn:matrix:org.matrix.msc2967.client:device:*" scope
@@ -173,11 +177,9 @@ pub(crate) async fn post(
)
.await?;
let _grant = give_consent_to_grant(&mut txn, grant)
.await
.context("failed to give consent to grant")?;
let _grant = give_consent_to_grant(&mut txn, grant).await?;
txn.commit().await.context("could not commit txn")?;
txn.commit().await?;
Ok((cookie_jar, next.go_next()).into_response())
}

View File

@@ -98,6 +98,9 @@ pub(crate) enum RouteError {
#[error("could not verify client credentials")]
ClientCredentialsVerification(#[from] CredentialsVerificationError),
#[error("grant not found")]
GrantNotFound,
#[error("invalid grant")]
InvalidGrant,
@@ -131,7 +134,7 @@ impl IntoResponse for RouteError {
StatusCode::UNAUTHORIZED,
Json(ClientError::from(ClientErrorCode::UnauthorizedClient)),
),
Self::InvalidGrant => (
Self::InvalidGrant | Self::GrantNotFound => (
StatusCode::BAD_REQUEST,
Json(ClientError::from(ClientErrorCode::InvalidGrant)),
),
@@ -207,7 +210,9 @@ async fn authorization_code_grant(
// TODO: there is a bunch of unnecessary cloning here
// TODO: handle "not found" cases
let authz_grant = lookup_grant_by_code(&mut txn, &grant.code).await?;
let authz_grant = lookup_grant_by_code(&mut txn, &grant.code)
.await?
.ok_or(RouteError::GrantNotFound)?;
let now = clock.now();