1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-07-31 09:24:31 +03:00

storage: finish cleaning up the errors

This commit is contained in:
Quentin Gliech
2022-12-08 15:09:54 +01:00
parent bd93074076
commit 56d43b0166
13 changed files with 111 additions and 157 deletions

View File

@ -16,7 +16,7 @@ use axum::{extract::State, response::IntoResponse, Json, TypedHeader};
use headers::{authorization::Bearer, Authorization}; use headers::{authorization::Bearer, Authorization};
use hyper::StatusCode; use hyper::StatusCode;
use mas_data_model::TokenType; use mas_data_model::TokenType;
use mas_storage::{compat::compat_logout, Clock, LookupError}; use mas_storage::{compat::compat_logout, Clock};
use sqlx::PgPool; use sqlx::PgPool;
use thiserror::Error; use thiserror::Error;
@ -82,13 +82,9 @@ pub(crate) async fn post(
return Err(RouteError::InvalidAuthorization); return Err(RouteError::InvalidAuthorization);
} }
compat_logout(&mut conn, &clock, token).await.map_err(|e| { if !compat_logout(&mut conn, &clock, token).await? {
if e.not_found() { return Err(RouteError::LogoutFailed);
RouteError::LogoutFailed }
} else {
RouteError::Internal(Box::new(e))
}
})?;
Ok(Json(serde_json::json!({}))) Ok(Json(serde_json::json!({})))
} }

View File

@ -31,7 +31,6 @@ 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,
}, },
LookupResultExt,
}; };
use mas_templates::{ use mas_templates::{
EmptyContext, TemplateContext, Templates, UpstreamExistingLinkContext, UpstreamRegister, EmptyContext, TemplateContext, Templates, UpstreamExistingLinkContext, UpstreamRegister,
@ -71,7 +70,6 @@ pub(crate) enum RouteError {
impl_from_error_for_route!(sqlx::Error); impl_from_error_for_route!(sqlx::Error);
impl_from_error_for_route!(mas_templates::TemplateError); impl_from_error_for_route!(mas_templates::TemplateError);
impl_from_error_for_route!(mas_storage::GenericLookupError);
impl_from_error_for_route!(mas_axum_utils::csrf::CsrfError); impl_from_error_for_route!(mas_axum_utils::csrf::CsrfError);
impl_from_error_for_route!(super::cookie::UpstreamSessionNotFound); impl_from_error_for_route!(super::cookie::UpstreamSessionNotFound);
impl_from_error_for_route!(mas_storage::DatabaseError); impl_from_error_for_route!(mas_storage::DatabaseError);
@ -115,8 +113,7 @@ pub(crate) async fn get(
// This checks that we're in a browser session which is allowed to consume this // This checks that we're in a browser session which is allowed to consume this
// link: the upstream auth session should have been started in this browser. // link: the upstream auth session should have been started in this browser.
let upstream_session = lookup_session_on_link(&mut txn, &link, session_id) let upstream_session = lookup_session_on_link(&mut txn, &link, session_id)
.await .await?
.to_option()?
.ok_or(RouteError::SessionNotFound)?; .ok_or(RouteError::SessionNotFound)?;
if upstream_session.consumed() { if upstream_session.consumed() {
@ -217,8 +214,7 @@ pub(crate) async fn post(
// This checks that we're in a browser session which is allowed to consume this // This checks that we're in a browser session which is allowed to consume this
// link: the upstream auth session should have been started in this browser. // link: the upstream auth session should have been started in this browser.
let upstream_session = lookup_session_on_link(&mut txn, &link, session_id) let upstream_session = lookup_session_on_link(&mut txn, &link, session_id)
.await .await?
.to_option()?
.ok_or(RouteError::SessionNotFound)?; .ok_or(RouteError::SessionNotFound)?;
if upstream_session.consumed() { if upstream_session.consumed() {

View File

@ -30,7 +30,7 @@ use uuid::Uuid;
use crate::{ use crate::{
pagination::{process_page, QueryBuilderExt}, pagination::{process_page, QueryBuilderExt},
user::lookup_user_by_username, user::lookup_user_by_username,
Clock, DatabaseError, DatabaseInconsistencyError2, LookupResultExt, Clock, DatabaseError, DatabaseInconsistencyError, LookupResultExt,
}; };
struct CompatAccessTokenLookup { struct CompatAccessTokenLookup {
@ -119,7 +119,7 @@ pub async fn lookup_active_compat_access_token(
}), }),
(None, None, None, None) => None, (None, None, None, None) => None,
_ => { _ => {
return Err(DatabaseInconsistencyError2::on("compat_sessions") return Err(DatabaseInconsistencyError::on("compat_sessions")
.column("user_id") .column("user_id")
.row(user_id) .row(user_id)
.into()) .into())
@ -135,7 +135,7 @@ pub async fn lookup_active_compat_access_token(
let id = res.compat_session_id.into(); let id = res.compat_session_id.into();
let device = Device::try_from(res.compat_session_device_id).map_err(|e| { let device = Device::try_from(res.compat_session_device_id).map_err(|e| {
DatabaseInconsistencyError2::on("compat_sessions") DatabaseInconsistencyError::on("compat_sessions")
.column("device_id") .column("device_id")
.row(id) .row(id)
.source(e) .source(e)
@ -251,7 +251,7 @@ pub async fn lookup_active_compat_refresh_token(
}), }),
(None, None, None, None) => None, (None, None, None, None) => None,
_ => { _ => {
return Err(DatabaseInconsistencyError2::on("users") return Err(DatabaseInconsistencyError::on("users")
.column("primary_user_email_id") .column("primary_user_email_id")
.row(user_id) .row(user_id)
.into()) .into())
@ -267,7 +267,7 @@ pub async fn lookup_active_compat_refresh_token(
let session_id = res.compat_session_id.into(); let session_id = res.compat_session_id.into();
let device = Device::try_from(res.compat_session_device_id).map_err(|e| { let device = Device::try_from(res.compat_session_device_id).map_err(|e| {
DatabaseInconsistencyError2::on("compat_sessions") DatabaseInconsistencyError::on("compat_sessions")
.column("device_id") .column("device_id")
.row(session_id) .row(session_id)
.source(e) .source(e)
@ -501,10 +501,10 @@ pub async fn compat_logout(
executor: impl PgExecutor<'_>, executor: impl PgExecutor<'_>,
clock: &Clock, clock: &Clock,
token: &str, token: &str,
) -> Result<(), sqlx::Error> { ) -> Result<bool, sqlx::Error> {
let finished_at = clock.now(); let finished_at = clock.now();
// TODO: this does not check for token expiration // TODO: this does not check for token expiration
let compat_session_id = sqlx::query_scalar!( let res = sqlx::query_scalar!(
r#" r#"
UPDATE compat_sessions cs UPDATE compat_sessions cs
SET finished_at = $2 SET finished_at = $2
@ -518,14 +518,18 @@ pub async fn compat_logout(
finished_at, finished_at,
) )
.fetch_one(executor) .fetch_one(executor)
.await?; .await
.to_option()?;
tracing::Span::current().record( if let Some(compat_session_id) = res {
"compat_session.id", tracing::Span::current().record(
tracing::field::display(compat_session_id), "compat_session.id",
); tracing::field::display(compat_session_id),
);
Ok(()) Ok(true)
} else {
Ok(false)
}
} }
#[tracing::instrument( #[tracing::instrument(
@ -620,12 +624,12 @@ struct CompatSsoLoginLookup {
} }
impl TryFrom<CompatSsoLoginLookup> for CompatSsoLogin { impl TryFrom<CompatSsoLoginLookup> for CompatSsoLogin {
type Error = DatabaseInconsistencyError2; type Error = DatabaseInconsistencyError;
fn try_from(res: CompatSsoLoginLookup) -> Result<Self, Self::Error> { fn try_from(res: CompatSsoLoginLookup) -> Result<Self, Self::Error> {
let id = res.compat_sso_login_id.into(); let id = res.compat_sso_login_id.into();
let redirect_uri = Url::parse(&res.compat_sso_login_redirect_uri).map_err(|e| { let redirect_uri = Url::parse(&res.compat_sso_login_redirect_uri).map_err(|e| {
DatabaseInconsistencyError2::on("compat_sso_logins") DatabaseInconsistencyError::on("compat_sso_logins")
.column("redirect_uri") .column("redirect_uri")
.row(id) .row(id)
.source(e) .source(e)
@ -645,7 +649,7 @@ impl TryFrom<CompatSsoLoginLookup> for CompatSsoLogin {
}), }),
(None, None, None, None) => None, (None, None, None, None) => None,
_ => { _ => {
return Err(DatabaseInconsistencyError2::on("users").column("primary_user_email_id")) return Err(DatabaseInconsistencyError::on("users").column("primary_user_email_id"))
} }
}; };
@ -661,7 +665,7 @@ impl TryFrom<CompatSsoLoginLookup> for CompatSsoLogin {
} }
(None, None, None) => None, (None, None, None) => None,
_ => return Err(DatabaseInconsistencyError2::on("compat_sessions").column("user_id")), _ => return Err(DatabaseInconsistencyError::on("compat_sessions").column("user_id")),
}; };
let session = match ( let session = match (
@ -674,7 +678,7 @@ impl TryFrom<CompatSsoLoginLookup> for CompatSsoLogin {
(Some(id), Some(device_id), Some(created_at), finished_at, Some(user)) => { (Some(id), Some(device_id), Some(created_at), finished_at, Some(user)) => {
let id = id.into(); let id = id.into();
let device = Device::try_from(device_id).map_err(|e| { let device = Device::try_from(device_id).map_err(|e| {
DatabaseInconsistencyError2::on("compat_sessions") DatabaseInconsistencyError::on("compat_sessions")
.column("device") .column("device")
.row(id) .row(id)
.source(e) .source(e)
@ -689,7 +693,7 @@ impl TryFrom<CompatSsoLoginLookup> for CompatSsoLogin {
} }
(None, None, None, None, None) => None, (None, None, None, None, None) => None,
_ => { _ => {
return Err(DatabaseInconsistencyError2::on("compat_sso_logins") return Err(DatabaseInconsistencyError::on("compat_sso_logins")
.column("compat_session_id") .column("compat_session_id")
.row(id)) .row(id))
} }
@ -712,7 +716,7 @@ impl TryFrom<CompatSsoLoginLookup> for CompatSsoLogin {
session, session,
} }
} }
_ => return Err(DatabaseInconsistencyError2::on("compat_sso_logins").row(id)), _ => return Err(DatabaseInconsistencyError::on("compat_sso_logins").row(id)),
}; };
Ok(CompatSsoLogin { Ok(CompatSsoLogin {

View File

@ -34,55 +34,21 @@ use sqlx::{migrate::Migrator, postgres::PgQueryResult};
use thiserror::Error; use thiserror::Error;
use ulid::Ulid; use ulid::Ulid;
#[derive(Debug, Error)] trait LookupResultExt {
#[error("failed to lookup {what}")]
pub struct GenericLookupError {
what: &'static str,
source: sqlx::Error,
}
impl GenericLookupError {
#[must_use]
pub fn what(what: &'static str) -> Box<dyn Fn(sqlx::Error) -> Self> {
Box::new(move |source: sqlx::Error| Self { what, source })
}
}
impl LookupError for GenericLookupError {
fn not_found(&self) -> bool {
matches!(self.source, sqlx::Error::RowNotFound)
}
}
impl LookupError for sqlx::Error {
fn not_found(&self) -> bool {
matches!(self, sqlx::Error::RowNotFound)
}
}
pub trait LookupError {
fn not_found(&self) -> bool;
}
pub trait LookupResultExt {
type Error;
type Output; type Output;
/// Transform a [`Result`] with a [`LookupError`] to transform "not /// Transform a [`Result`] from a sqlx query to transform "not found" errors
/// found" errors into [`None`] /// into [`None`]
fn to_option(self) -> Result<Option<Self::Output>, Self::Error>; fn to_option(self) -> Result<Option<Self::Output>, sqlx::Error>;
} }
impl<T, E> LookupResultExt for Result<T, E> impl<T> LookupResultExt for Result<T, sqlx::Error> {
where
E: LookupError,
{
type Output = T; type Output = T;
type Error = E;
fn to_option(self) -> Result<Option<Self::Output>, Self::Error> { fn to_option(self) -> Result<Option<Self::Output>, sqlx::Error> {
match self { match self {
Ok(v) => Ok(Some(v)), Ok(v) => Ok(Some(v)),
Err(e) if e.not_found() => Ok(None), Err(sqlx::Error::RowNotFound) => Ok(None),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
@ -96,7 +62,7 @@ pub enum DatabaseError {
Driver(#[from] sqlx::Error), Driver(#[from] sqlx::Error),
/// An error which occured while converting the data from the database /// An error which occured while converting the data from the database
Inconsistency(#[from] DatabaseInconsistencyError2), Inconsistency(#[from] DatabaseInconsistencyError),
/// An error which occured while generating the paginated query /// An error which occured while generating the paginated query
Pagination(#[from] InvalidPagination), Pagination(#[from] InvalidPagination),
@ -140,7 +106,7 @@ impl DatabaseError {
} }
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub struct DatabaseInconsistencyError2 { pub struct DatabaseInconsistencyError {
table: &'static str, table: &'static str,
column: Option<&'static str>, column: Option<&'static str>,
row: Option<Ulid>, row: Option<Ulid>,
@ -149,7 +115,7 @@ pub struct DatabaseInconsistencyError2 {
source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>, source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
} }
impl std::fmt::Display for DatabaseInconsistencyError2 { impl std::fmt::Display for DatabaseInconsistencyError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Database inconsistency on table {}", self.table)?; write!(f, "Database inconsistency on table {}", self.table)?;
if let Some(column) = self.column { if let Some(column) = self.column {
@ -163,7 +129,7 @@ impl std::fmt::Display for DatabaseInconsistencyError2 {
} }
} }
impl DatabaseInconsistencyError2 { impl DatabaseInconsistencyError {
#[must_use] #[must_use]
pub(crate) const fn on(table: &'static str) -> Self { pub(crate) const fn on(table: &'static str) -> Self {
Self { Self {
@ -209,10 +175,6 @@ impl Clock {
} }
} }
#[derive(Debug, Error)]
#[error("database query returned an inconsistent state")]
pub struct DatabaseInconsistencyError;
pub mod compat; pub mod compat;
pub mod oauth2; pub mod oauth2;
pub(crate) mod pagination; pub(crate) mod pagination;

View File

@ -20,7 +20,7 @@ use ulid::Ulid;
use uuid::Uuid; use uuid::Uuid;
use super::client::lookup_client; use super::client::lookup_client;
use crate::{Clock, DatabaseError, DatabaseInconsistencyError2}; use crate::{Clock, DatabaseError, DatabaseInconsistencyError};
#[tracing::instrument( #[tracing::instrument(
skip_all, skip_all,
@ -156,7 +156,7 @@ pub async fn lookup_active_access_token(
let client = lookup_client(&mut *conn, res.oauth2_client_id.into()) let client = lookup_client(&mut *conn, res.oauth2_client_id.into())
.await? .await?
.ok_or_else(|| { .ok_or_else(|| {
DatabaseInconsistencyError2::on("oauth2_sessions") DatabaseInconsistencyError::on("oauth2_sessions")
.column("client_id") .column("client_id")
.row(session_id) .row(session_id)
})?; })?;
@ -176,7 +176,7 @@ pub async fn lookup_active_access_token(
}), }),
(None, None, None, None) => None, (None, None, None, None) => None,
_ => { _ => {
return Err(DatabaseInconsistencyError2::on("users") return Err(DatabaseInconsistencyError::on("users")
.column("primary_user_email_id") .column("primary_user_email_id")
.row(user_id) .row(user_id)
.into()) .into())
@ -199,7 +199,7 @@ pub async fn lookup_active_access_token(
id: id.into(), id: id.into(),
created_at, created_at,
}), }),
_ => return Err(DatabaseInconsistencyError2::on("user_session_authentications").into()), _ => return Err(DatabaseInconsistencyError::on("user_session_authentications").into()),
}; };
let browser_session = BrowserSession { let browser_session = BrowserSession {
@ -210,7 +210,7 @@ pub async fn lookup_active_access_token(
}; };
let scope = res.scope.parse().map_err(|e| { let scope = res.scope.parse().map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_sessions") DatabaseInconsistencyError::on("oauth2_sessions")
.column("scope") .column("scope")
.row(session_id) .row(session_id)
.source(e) .source(e)

View File

@ -28,7 +28,7 @@ use url::Url;
use uuid::Uuid; use uuid::Uuid;
use super::client::lookup_client; use super::client::lookup_client;
use crate::{Clock, DatabaseError, DatabaseInconsistencyError2, LookupResultExt}; use crate::{Clock, DatabaseError, DatabaseInconsistencyError, LookupResultExt};
#[tracing::instrument( #[tracing::instrument(
skip_all, skip_all,
@ -170,7 +170,7 @@ impl GrantLookup {
) -> Result<AuthorizationGrant, DatabaseError> { ) -> Result<AuthorizationGrant, DatabaseError> {
let id = self.oauth2_authorization_grant_id.into(); let id = self.oauth2_authorization_grant_id.into();
let scope: Scope = self.oauth2_authorization_grant_scope.parse().map_err(|e| { let scope: Scope = self.oauth2_authorization_grant_scope.parse().map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_authorization_grants") DatabaseInconsistencyError::on("oauth2_authorization_grants")
.column("scope") .column("scope")
.row(id) .row(id)
.source(e) .source(e)
@ -180,7 +180,7 @@ impl GrantLookup {
let client = lookup_client(executor, self.oauth2_client_id.into()) let client = lookup_client(executor, self.oauth2_client_id.into())
.await? .await?
.ok_or_else(|| { .ok_or_else(|| {
DatabaseInconsistencyError2::on("oauth2_authorization_grants") DatabaseInconsistencyError::on("oauth2_authorization_grants")
.column("client_id") .column("client_id")
.row(id) .row(id)
})?; })?;
@ -194,9 +194,7 @@ impl GrantLookup {
created_at, created_at,
}), }),
(None, None) => None, (None, None) => None,
_ => { _ => return Err(DatabaseInconsistencyError::on("user_session_authentications").into()),
return Err(DatabaseInconsistencyError2::on("user_session_authentications").into())
}
}; };
let primary_email = match ( let primary_email = match (
@ -213,7 +211,7 @@ impl GrantLookup {
}), }),
(None, None, None, None) => None, (None, None, None, None) => None,
_ => { _ => {
return Err(DatabaseInconsistencyError2::on("users") return Err(DatabaseInconsistencyError::on("users")
.column("primary_user_email_id") .column("primary_user_email_id")
.into()) .into())
} }
@ -267,7 +265,7 @@ impl GrantLookup {
(None, None, None, None, None, None, None) => None, (None, None, None, None, None, None, None) => None,
_ => { _ => {
return Err( return Err(
DatabaseInconsistencyError2::on("oauth2_authorization_grants") DatabaseInconsistencyError::on("oauth2_authorization_grants")
.column("oauth2_session_id") .column("oauth2_session_id")
.row(id) .row(id)
.into(), .into(),
@ -298,7 +296,7 @@ impl GrantLookup {
} }
_ => { _ => {
return Err( return Err(
DatabaseInconsistencyError2::on("oauth2_authorization_grants") DatabaseInconsistencyError::on("oauth2_authorization_grants")
.column("stage") .column("stage")
.row(id) .row(id)
.into(), .into(),
@ -323,7 +321,7 @@ impl GrantLookup {
(None, None) => None, (None, None) => None,
_ => { _ => {
return Err( return Err(
DatabaseInconsistencyError2::on("oauth2_authorization_grants") DatabaseInconsistencyError::on("oauth2_authorization_grants")
.column("code_challenge_method") .column("code_challenge_method")
.row(id) .row(id)
.into(), .into(),
@ -340,7 +338,7 @@ impl GrantLookup {
(true, Some(code), pkce) => Some(AuthorizationCode { code, pkce }), (true, Some(code), pkce) => Some(AuthorizationCode { code, pkce }),
_ => { _ => {
return Err( return Err(
DatabaseInconsistencyError2::on("oauth2_authorization_grants") DatabaseInconsistencyError::on("oauth2_authorization_grants")
.column("authorization_code") .column("authorization_code")
.row(id) .row(id)
.into(), .into(),
@ -352,7 +350,7 @@ impl GrantLookup {
.oauth2_authorization_grant_redirect_uri .oauth2_authorization_grant_redirect_uri
.parse() .parse()
.map_err(|e| { .map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_authorization_grants") DatabaseInconsistencyError::on("oauth2_authorization_grants")
.column("redirect_uri") .column("redirect_uri")
.row(id) .row(id)
.source(e) .source(e)
@ -362,7 +360,7 @@ impl GrantLookup {
.oauth2_authorization_grant_response_mode .oauth2_authorization_grant_response_mode
.parse() .parse()
.map_err(|e| { .map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_authorization_grants") DatabaseInconsistencyError::on("oauth2_authorization_grants")
.column("response_mode") .column("response_mode")
.row(id) .row(id)
.source(e) .source(e)
@ -373,7 +371,7 @@ impl GrantLookup {
.map(u32::try_from) .map(u32::try_from)
.transpose() .transpose()
.map_err(|e| { .map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_authorization_grants") DatabaseInconsistencyError::on("oauth2_authorization_grants")
.column("max_age") .column("max_age")
.row(id) .row(id)
.source(e) .source(e)
@ -381,7 +379,7 @@ impl GrantLookup {
.map(NonZeroU32::try_from) .map(NonZeroU32::try_from)
.transpose() .transpose()
.map_err(|e| { .map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_authorization_grants") DatabaseInconsistencyError::on("oauth2_authorization_grants")
.column("max_age") .column("max_age")
.row(id) .row(id)
.source(e) .source(e)

View File

@ -27,7 +27,7 @@ use ulid::Ulid;
use url::Url; use url::Url;
use uuid::Uuid; use uuid::Uuid;
use crate::{Clock, DatabaseError, DatabaseInconsistencyError2, LookupResultExt}; use crate::{Clock, DatabaseError, DatabaseInconsistencyError, LookupResultExt};
// XXX: response_types & contacts // XXX: response_types & contacts
#[derive(Debug)] #[derive(Debug)]
@ -54,7 +54,7 @@ pub struct OAuth2ClientLookup {
} }
impl TryInto<Client> for OAuth2ClientLookup { impl TryInto<Client> for OAuth2ClientLookup {
type Error = DatabaseInconsistencyError2; type Error = DatabaseInconsistencyError;
#[allow(clippy::too_many_lines)] // TODO: refactor some of the field parsing #[allow(clippy::too_many_lines)] // TODO: refactor some of the field parsing
fn try_into(self) -> Result<Client, Self::Error> { fn try_into(self) -> Result<Client, Self::Error> {
@ -63,7 +63,7 @@ impl TryInto<Client> for OAuth2ClientLookup {
let redirect_uris: Result<Vec<Url>, _> = let redirect_uris: Result<Vec<Url>, _> =
self.redirect_uris.iter().map(|s| s.parse()).collect(); self.redirect_uris.iter().map(|s| s.parse()).collect();
let redirect_uris = redirect_uris.map_err(|e| { let redirect_uris = redirect_uris.map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_clients") DatabaseInconsistencyError::on("oauth2_clients")
.column("redirect_uris") .column("redirect_uris")
.row(id) .row(id)
.source(e) .source(e)
@ -92,7 +92,7 @@ impl TryInto<Client> for OAuth2ClientLookup {
} }
let logo_uri = self.logo_uri.map(|s| s.parse()).transpose().map_err(|e| { let logo_uri = self.logo_uri.map(|s| s.parse()).transpose().map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_clients") DatabaseInconsistencyError::on("oauth2_clients")
.column("logo_uri") .column("logo_uri")
.row(id) .row(id)
.source(e) .source(e)
@ -103,7 +103,7 @@ impl TryInto<Client> for OAuth2ClientLookup {
.map(|s| s.parse()) .map(|s| s.parse())
.transpose() .transpose()
.map_err(|e| { .map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_clients") DatabaseInconsistencyError::on("oauth2_clients")
.column("client_uri") .column("client_uri")
.row(id) .row(id)
.source(e) .source(e)
@ -114,14 +114,14 @@ impl TryInto<Client> for OAuth2ClientLookup {
.map(|s| s.parse()) .map(|s| s.parse())
.transpose() .transpose()
.map_err(|e| { .map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_clients") DatabaseInconsistencyError::on("oauth2_clients")
.column("policy_uri") .column("policy_uri")
.row(id) .row(id)
.source(e) .source(e)
})?; })?;
let tos_uri = self.tos_uri.map(|s| s.parse()).transpose().map_err(|e| { let tos_uri = self.tos_uri.map(|s| s.parse()).transpose().map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_clients") DatabaseInconsistencyError::on("oauth2_clients")
.column("tos_uri") .column("tos_uri")
.row(id) .row(id)
.source(e) .source(e)
@ -132,7 +132,7 @@ impl TryInto<Client> for OAuth2ClientLookup {
.map(|s| s.parse()) .map(|s| s.parse())
.transpose() .transpose()
.map_err(|e| { .map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_clients") DatabaseInconsistencyError::on("oauth2_clients")
.column("id_token_signed_response_alg") .column("id_token_signed_response_alg")
.row(id) .row(id)
.source(e) .source(e)
@ -143,7 +143,7 @@ impl TryInto<Client> for OAuth2ClientLookup {
.map(|s| s.parse()) .map(|s| s.parse())
.transpose() .transpose()
.map_err(|e| { .map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_clients") DatabaseInconsistencyError::on("oauth2_clients")
.column("userinfo_signed_response_alg") .column("userinfo_signed_response_alg")
.row(id) .row(id)
.source(e) .source(e)
@ -154,7 +154,7 @@ impl TryInto<Client> for OAuth2ClientLookup {
.map(|s| s.parse()) .map(|s| s.parse())
.transpose() .transpose()
.map_err(|e| { .map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_clients") DatabaseInconsistencyError::on("oauth2_clients")
.column("token_endpoint_auth_method") .column("token_endpoint_auth_method")
.row(id) .row(id)
.source(e) .source(e)
@ -165,7 +165,7 @@ impl TryInto<Client> for OAuth2ClientLookup {
.map(|s| s.parse()) .map(|s| s.parse())
.transpose() .transpose()
.map_err(|e| { .map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_clients") DatabaseInconsistencyError::on("oauth2_clients")
.column("token_endpoint_auth_signing_alg") .column("token_endpoint_auth_signing_alg")
.row(id) .row(id)
.source(e) .source(e)
@ -176,7 +176,7 @@ impl TryInto<Client> for OAuth2ClientLookup {
.map(|s| s.parse()) .map(|s| s.parse())
.transpose() .transpose()
.map_err(|e| { .map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_clients") DatabaseInconsistencyError::on("oauth2_clients")
.column("initiate_login_uri") .column("initiate_login_uri")
.row(id) .row(id)
.source(e) .source(e)
@ -186,7 +186,7 @@ impl TryInto<Client> for OAuth2ClientLookup {
(None, None) => None, (None, None) => None,
(Some(jwks), None) => { (Some(jwks), None) => {
let jwks = serde_json::from_value(jwks).map_err(|e| { let jwks = serde_json::from_value(jwks).map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_clients") DatabaseInconsistencyError::on("oauth2_clients")
.column("jwks") .column("jwks")
.row(id) .row(id)
.source(e) .source(e)
@ -195,7 +195,7 @@ impl TryInto<Client> for OAuth2ClientLookup {
} }
(None, Some(jwks_uri)) => { (None, Some(jwks_uri)) => {
let jwks_uri = jwks_uri.parse().map_err(|e| { let jwks_uri = jwks_uri.parse().map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_clients") DatabaseInconsistencyError::on("oauth2_clients")
.column("jwks_uri") .column("jwks_uri")
.row(id) .row(id)
.source(e) .source(e)
@ -204,7 +204,7 @@ impl TryInto<Client> for OAuth2ClientLookup {
Some(JwksOrJwksUri::JwksUri(jwks_uri)) Some(JwksOrJwksUri::JwksUri(jwks_uri))
} }
_ => { _ => {
return Err(DatabaseInconsistencyError2::on("oauth2_clients") return Err(DatabaseInconsistencyError::on("oauth2_clients")
.column("jwks(_uri)") .column("jwks(_uri)")
.row(id)) .row(id))
} }

View File

@ -21,7 +21,7 @@ use sqlx::PgExecutor;
use ulid::Ulid; use ulid::Ulid;
use uuid::Uuid; use uuid::Uuid;
use crate::{Clock, DatabaseError, DatabaseInconsistencyError2}; use crate::{Clock, DatabaseError, DatabaseInconsistencyError};
#[tracing::instrument( #[tracing::instrument(
skip_all, skip_all,
@ -54,7 +54,7 @@ pub async fn fetch_client_consent(
.collect(); .collect();
let scope = scope.map_err(|e| { let scope = scope.map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_consents") DatabaseInconsistencyError::on("oauth2_consents")
.column("scope_token") .column("scope_token")
.source(e) .source(e)
})?; })?;

View File

@ -24,7 +24,7 @@ use self::client::lookup_clients;
use crate::{ use crate::{
pagination::{process_page, QueryBuilderExt}, pagination::{process_page, QueryBuilderExt},
user::lookup_active_session, user::lookup_active_session,
Clock, DatabaseError, DatabaseInconsistencyError2, Clock, DatabaseError, DatabaseInconsistencyError,
}; };
pub mod access_token; pub mod access_token;
@ -137,19 +137,19 @@ pub async fn get_paginated_user_oauth_sessions(
let v = lookup_active_session(&mut *conn, id) let v = lookup_active_session(&mut *conn, id)
.await? .await?
.ok_or_else(|| { .ok_or_else(|| {
DatabaseInconsistencyError2::on("oauth2_sessions").column("user_session_id") DatabaseInconsistencyError::on("oauth2_sessions").column("user_session_id")
})?; })?;
browser_sessions.insert(id, v); browser_sessions.insert(id, v);
} }
let page: Result<Vec<_>, DatabaseInconsistencyError2> = page let page: Result<Vec<_>, DatabaseInconsistencyError> = page
.into_iter() .into_iter()
.map(|item| { .map(|item| {
let id = Ulid::from(item.oauth2_session_id); let id = Ulid::from(item.oauth2_session_id);
let client = clients let client = clients
.get(&Ulid::from(item.oauth2_client_id)) .get(&Ulid::from(item.oauth2_client_id))
.ok_or_else(|| { .ok_or_else(|| {
DatabaseInconsistencyError2::on("oauth2_sessions") DatabaseInconsistencyError::on("oauth2_sessions")
.column("oauth2_client_id") .column("oauth2_client_id")
.row(id) .row(id)
})? })?
@ -158,14 +158,14 @@ pub async fn get_paginated_user_oauth_sessions(
let browser_session = browser_sessions let browser_session = browser_sessions
.get(&Ulid::from(item.user_session_id)) .get(&Ulid::from(item.user_session_id))
.ok_or_else(|| { .ok_or_else(|| {
DatabaseInconsistencyError2::on("oauth2_sessions") DatabaseInconsistencyError::on("oauth2_sessions")
.column("user_session_id") .column("user_session_id")
.row(id) .row(id)
})? })?
.clone(); .clone();
let scope = item.scope.parse().map_err(|e| { let scope = item.scope.parse().map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_sessions") DatabaseInconsistencyError::on("oauth2_sessions")
.column("scope") .column("scope")
.row(id) .row(id)
.source(e) .source(e)

View File

@ -22,7 +22,7 @@ use ulid::Ulid;
use uuid::Uuid; use uuid::Uuid;
use super::client::lookup_client; use super::client::lookup_client;
use crate::{Clock, DatabaseError, DatabaseInconsistencyError2}; use crate::{Clock, DatabaseError, DatabaseInconsistencyError};
#[tracing::instrument( #[tracing::instrument(
skip_all, skip_all,
@ -170,7 +170,7 @@ pub async fn lookup_active_refresh_token(
expires_at, expires_at,
}) })
} }
_ => return Err(DatabaseInconsistencyError2::on("oauth2_access_tokens").into()), _ => return Err(DatabaseInconsistencyError::on("oauth2_access_tokens").into()),
}; };
let refresh_token = RefreshToken { let refresh_token = RefreshToken {
@ -184,7 +184,7 @@ pub async fn lookup_active_refresh_token(
let client = lookup_client(&mut *conn, res.oauth2_client_id.into()) let client = lookup_client(&mut *conn, res.oauth2_client_id.into())
.await? .await?
.ok_or_else(|| { .ok_or_else(|| {
DatabaseInconsistencyError2::on("oauth2_sessions") DatabaseInconsistencyError::on("oauth2_sessions")
.column("client_id") .column("client_id")
.row(session_id) .row(session_id)
})?; })?;
@ -204,7 +204,7 @@ pub async fn lookup_active_refresh_token(
}), }),
(None, None, None, None) => None, (None, None, None, None) => None,
_ => { _ => {
return Err(DatabaseInconsistencyError2::on("users") return Err(DatabaseInconsistencyError::on("users")
.column("primary_user_email_id") .column("primary_user_email_id")
.row(user_id) .row(user_id)
.into()) .into())
@ -227,7 +227,7 @@ pub async fn lookup_active_refresh_token(
id: id.into(), id: id.into(),
created_at, created_at,
}), }),
_ => return Err(DatabaseInconsistencyError2::on("user_session_authentications").into()), _ => return Err(DatabaseInconsistencyError::on("user_session_authentications").into()),
}; };
let browser_session = BrowserSession { let browser_session = BrowserSession {
@ -238,7 +238,7 @@ pub async fn lookup_active_refresh_token(
}; };
let scope = res.oauth2_session_scope.parse().map_err(|e| { let scope = res.oauth2_session_scope.parse().map_err(|e| {
DatabaseInconsistencyError2::on("oauth2_sessions") DatabaseInconsistencyError::on("oauth2_sessions")
.column("scope") .column("scope")
.row(session_id) .row(session_id)
.source(e) .source(e)

View File

@ -24,7 +24,7 @@ use uuid::Uuid;
use crate::{ use crate::{
pagination::{process_page, QueryBuilderExt}, pagination::{process_page, QueryBuilderExt},
Clock, DatabaseError, DatabaseInconsistencyError2, LookupResultExt, Clock, DatabaseError, DatabaseInconsistencyError, LookupResultExt,
}; };
#[derive(sqlx::FromRow)] #[derive(sqlx::FromRow)]
@ -40,17 +40,17 @@ struct ProviderLookup {
} }
impl TryFrom<ProviderLookup> for UpstreamOAuthProvider { impl TryFrom<ProviderLookup> for UpstreamOAuthProvider {
type Error = DatabaseInconsistencyError2; type Error = DatabaseInconsistencyError;
fn try_from(value: ProviderLookup) -> Result<Self, Self::Error> { fn try_from(value: ProviderLookup) -> Result<Self, Self::Error> {
let id = value.upstream_oauth_provider_id.into(); let id = value.upstream_oauth_provider_id.into();
let scope = value.scope.parse().map_err(|e| { let scope = value.scope.parse().map_err(|e| {
DatabaseInconsistencyError2::on("upstream_oauth_providers") DatabaseInconsistencyError::on("upstream_oauth_providers")
.column("scope") .column("scope")
.row(id) .row(id)
.source(e) .source(e)
})?; })?;
let token_endpoint_auth_method = value.token_endpoint_auth_method.parse().map_err(|e| { let token_endpoint_auth_method = value.token_endpoint_auth_method.parse().map_err(|e| {
DatabaseInconsistencyError2::on("upstream_oauth_providers") DatabaseInconsistencyError::on("upstream_oauth_providers")
.column("token_endpoint_auth_method") .column("token_endpoint_auth_method")
.row(id) .row(id)
.source(e) .source(e)
@ -60,7 +60,7 @@ impl TryFrom<ProviderLookup> for UpstreamOAuthProvider {
.map(|x| x.parse()) .map(|x| x.parse())
.transpose() .transpose()
.map_err(|e| { .map_err(|e| {
DatabaseInconsistencyError2::on("upstream_oauth_providers") DatabaseInconsistencyError::on("upstream_oauth_providers")
.column("token_endpoint_signing_alg") .column("token_endpoint_signing_alg")
.row(id) .row(id)
.source(e) .source(e)

View File

@ -19,9 +19,7 @@ use sqlx::PgExecutor;
use ulid::Ulid; use ulid::Ulid;
use uuid::Uuid; use uuid::Uuid;
use crate::{ use crate::{Clock, DatabaseError, DatabaseInconsistencyError, LookupResultExt};
Clock, DatabaseError, DatabaseInconsistencyError2, GenericLookupError, LookupResultExt,
};
struct SessionAndProviderLookup { struct SessionAndProviderLookup {
upstream_oauth_authorization_session_id: Uuid, upstream_oauth_authorization_session_id: Uuid,
@ -92,7 +90,7 @@ pub async fn lookup_session(
id, id,
issuer: res.provider_issuer, issuer: res.provider_issuer,
scope: res.provider_scope.parse().map_err(|e| { scope: res.provider_scope.parse().map_err(|e| {
DatabaseInconsistencyError2::on("upstream_oauth_providers") DatabaseInconsistencyError::on("upstream_oauth_providers")
.column("scope") .column("scope")
.row(id) .row(id)
.source(e) .source(e)
@ -101,7 +99,7 @@ pub async fn lookup_session(
encrypted_client_secret: res.provider_encrypted_client_secret, encrypted_client_secret: res.provider_encrypted_client_secret,
token_endpoint_auth_method: res.provider_token_endpoint_auth_method.parse().map_err( token_endpoint_auth_method: res.provider_token_endpoint_auth_method.parse().map_err(
|e| { |e| {
DatabaseInconsistencyError2::on("upstream_oauth_providers") DatabaseInconsistencyError::on("upstream_oauth_providers")
.column("token_endpoint_auth_method") .column("token_endpoint_auth_method")
.row(id) .row(id)
.source(e) .source(e)
@ -112,7 +110,7 @@ pub async fn lookup_session(
.map(|x| x.parse()) .map(|x| x.parse())
.transpose() .transpose()
.map_err(|e| { .map_err(|e| {
DatabaseInconsistencyError2::on("upstream_oauth_providers") DatabaseInconsistencyError::on("upstream_oauth_providers")
.column("token_endpoint_signing_alg") .column("token_endpoint_signing_alg")
.row(id) .row(id)
.source(e) .source(e)
@ -297,7 +295,7 @@ pub async fn lookup_session_on_link(
executor: impl PgExecutor<'_>, executor: impl PgExecutor<'_>,
upstream_oauth_link: &UpstreamOAuthLink, upstream_oauth_link: &UpstreamOAuthLink,
id: Ulid, id: Ulid,
) -> Result<UpstreamOAuthAuthorizationSession, GenericLookupError> { ) -> Result<Option<UpstreamOAuthAuthorizationSession>, sqlx::Error> {
let res = sqlx::query_as!( let res = sqlx::query_as!(
SessionLookup, SessionLookup,
r#" r#"
@ -321,11 +319,11 @@ pub async fn lookup_session_on_link(
) )
.fetch_one(executor) .fetch_one(executor)
.await .await
.map_err(GenericLookupError::what( .to_option()?;
"Upstream OAuth 2.0 session on link",
))?;
Ok(UpstreamOAuthAuthorizationSession { let Some(res) = res else { return Ok(None) };
Ok(Some(UpstreamOAuthAuthorizationSession {
id: res.upstream_oauth_authorization_session_id.into(), id: res.upstream_oauth_authorization_session_id.into(),
provider_id: res.upstream_oauth_provider_id.into(), provider_id: res.upstream_oauth_provider_id.into(),
link_id: res.upstream_oauth_link_id.map(Ulid::from), link_id: res.upstream_oauth_link_id.map(Ulid::from),
@ -336,5 +334,5 @@ pub async fn lookup_session_on_link(
created_at: res.created_at, created_at: res.created_at,
completed_at: res.completed_at, completed_at: res.completed_at,
consumed_at: res.consumed_at, consumed_at: res.consumed_at,
}) }))
} }

View File

@ -32,7 +32,7 @@ use uuid::Uuid;
use crate::{ use crate::{
pagination::{process_page, QueryBuilderExt}, pagination::{process_page, QueryBuilderExt},
Clock, DatabaseError, DatabaseInconsistencyError2, LookupResultExt, Clock, DatabaseError, DatabaseInconsistencyError, LookupResultExt,
}; };
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -118,7 +118,7 @@ struct SessionLookup {
} }
impl TryInto<BrowserSession> for SessionLookup { impl TryInto<BrowserSession> for SessionLookup {
type Error = DatabaseInconsistencyError2; type Error = DatabaseInconsistencyError;
fn try_into(self) -> Result<BrowserSession, Self::Error> { fn try_into(self) -> Result<BrowserSession, Self::Error> {
let id = Ulid::from(self.user_id); let id = Ulid::from(self.user_id);
@ -136,7 +136,7 @@ impl TryInto<BrowserSession> for SessionLookup {
}), }),
(None, None, None, None) => None, (None, None, None, None) => None,
_ => { _ => {
return Err(DatabaseInconsistencyError2::on("users") return Err(DatabaseInconsistencyError::on("users")
.column("primary_user_email_id") .column("primary_user_email_id")
.row(id)) .row(id))
} }
@ -156,7 +156,7 @@ impl TryInto<BrowserSession> for SessionLookup {
}), }),
(None, None) => None, (None, None) => None,
_ => { _ => {
return Err(DatabaseInconsistencyError2::on( return Err(DatabaseInconsistencyError::on(
"user_session_authentications", "user_session_authentications",
)) ))
} }
@ -669,7 +669,7 @@ pub async fn lookup_user_by_username(
}), }),
(None, None, None, None) => None, (None, None, None, None) => None,
_ => { _ => {
return Err(DatabaseInconsistencyError2::on("users") return Err(DatabaseInconsistencyError::on("users")
.column("primary_user_email_id") .column("primary_user_email_id")
.row(id) .row(id)
.into()) .into())
@ -728,7 +728,7 @@ pub async fn lookup_user(executor: impl PgExecutor<'_>, id: Ulid) -> Result<User
}), }),
(None, None, None, None) => None, (None, None, None, None) => None,
_ => { _ => {
return Err(DatabaseInconsistencyError2::on("users") return Err(DatabaseInconsistencyError::on("users")
.column("primary_user_email_id") .column("primary_user_email_id")
.row(id) .row(id)
.into()) .into())