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

storage: start unifying database errors

This commit is contained in:
Quentin Gliech
2022-12-07 16:04:46 +01:00
parent 12ce2a3d04
commit 1ddc05ff01
13 changed files with 143 additions and 62 deletions

View File

@ -18,29 +18,15 @@ use mas_iana::{jose::JsonWebSignatureAlg, oauth::OAuthClientAuthenticationMethod
use oauth2_types::scope::Scope;
use rand::Rng;
use sqlx::{PgExecutor, QueryBuilder};
use thiserror::Error;
use tracing::{info_span, Instrument};
use ulid::Ulid;
use uuid::Uuid;
use crate::{
pagination::{process_page, QueryBuilderExt},
Clock, DatabaseInconsistencyError, LookupError,
Clock, DatabaseError, DatabaseInconsistencyError2, LookupResultExt,
};
#[derive(Debug, Error)]
#[error("Failed to lookup upstream OAuth 2.0 provider")]
pub enum ProviderLookupError {
Driver(#[from] sqlx::Error),
Inconcistency(#[from] DatabaseInconsistencyError),
}
impl LookupError for ProviderLookupError {
fn not_found(&self) -> bool {
matches!(self, Self::Driver(sqlx::Error::RowNotFound))
}
}
#[derive(sqlx::FromRow)]
struct ProviderLookup {
upstream_oauth_provider_id: Uuid,
@ -54,22 +40,31 @@ struct ProviderLookup {
}
impl TryFrom<ProviderLookup> for UpstreamOAuthProvider {
type Error = DatabaseInconsistencyError;
type Error = DatabaseInconsistencyError2;
fn try_from(value: ProviderLookup) -> Result<Self, Self::Error> {
let id = value.upstream_oauth_provider_id.into();
let scope = value
.scope
.parse()
.map_err(|_| DatabaseInconsistencyError)?;
let token_endpoint_auth_method = value
.token_endpoint_auth_method
.parse()
.map_err(|_| DatabaseInconsistencyError)?;
let scope = value.scope.parse().map_err(|e| {
DatabaseInconsistencyError2::on("upstream_oauth_providers")
.column("scope")
.row(id)
.source(e)
})?;
let token_endpoint_auth_method = value.token_endpoint_auth_method.parse().map_err(|e| {
DatabaseInconsistencyError2::on("upstream_oauth_providers")
.column("token_endpoint_auth_method")
.row(id)
.source(e)
})?;
let token_endpoint_signing_alg = value
.token_endpoint_signing_alg
.map(|x| x.parse())
.transpose()
.map_err(|_| DatabaseInconsistencyError)?;
.map_err(|e| {
DatabaseInconsistencyError2::on("upstream_oauth_providers")
.column("token_endpoint_signing_alg")
.row(id)
.source(e)
})?;
Ok(UpstreamOAuthProvider {
id,
@ -92,7 +87,7 @@ impl TryFrom<ProviderLookup> for UpstreamOAuthProvider {
pub async fn lookup_provider(
executor: impl PgExecutor<'_>,
id: Ulid,
) -> Result<UpstreamOAuthProvider, ProviderLookupError> {
) -> Result<Option<UpstreamOAuthProvider>, DatabaseError> {
let res = sqlx::query_as!(
ProviderLookup,
r#"
@ -111,9 +106,15 @@ pub async fn lookup_provider(
Uuid::from(id),
)
.fetch_one(executor)
.await?;
.await
.to_option()?;
Ok(res.try_into()?)
let res = res
.map(UpstreamOAuthProvider::try_from)
.transpose()
.map_err(DatabaseError::from)?;
Ok(res)
}
#[tracing::instrument(