1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-07-29 22:01:14 +03:00

Allow fetching more nodes by their IDs

This commit is contained in:
Quentin Gliech
2022-11-16 17:21:40 +01:00
parent 10815d8101
commit 78778648ca
18 changed files with 232 additions and 67 deletions

View File

@ -31,7 +31,7 @@ use uuid::Uuid;
use crate::{
pagination::{process_page, QueryBuilderExt},
user::lookup_user_by_username,
Clock, DatabaseInconsistencyError, PostgresqlBackend,
Clock, DatabaseInconsistencyError, LookupError, PostgresqlBackend,
};
struct CompatAccessTokenLookup {
@ -59,9 +59,8 @@ pub enum CompatAccessTokenLookupError {
Inconsistency(#[from] DatabaseInconsistencyError),
}
impl CompatAccessTokenLookupError {
#[must_use]
pub fn not_found(&self) -> bool {
impl LookupError for CompatAccessTokenLookupError {
fn not_found(&self) -> bool {
matches!(
self,
Self::Database(sqlx::Error::RowNotFound) | Self::Expired { .. }
@ -194,9 +193,8 @@ pub enum CompatRefreshTokenLookupError {
Inconsistency(#[from] DatabaseInconsistencyError),
}
impl CompatRefreshTokenLookupError {
#[must_use]
pub fn not_found(&self) -> bool {
impl LookupError for CompatRefreshTokenLookupError {
fn not_found(&self) -> bool {
matches!(self, Self::Database(sqlx::Error::RowNotFound))
}
}
@ -752,9 +750,8 @@ pub enum CompatSsoLoginLookupError {
Inconsistency(#[from] DatabaseInconsistencyError),
}
impl CompatSsoLoginLookupError {
#[must_use]
pub fn not_found(&self) -> bool {
impl LookupError for CompatSsoLoginLookupError {
fn not_found(&self) -> bool {
matches!(self, Self::Database(sqlx::Error::RowNotFound))
}
}

View File

@ -35,6 +35,54 @@ use sqlx::migrate::Migrator;
use thiserror::Error;
use ulid::Ulid;
#[derive(Debug, Error)]
#[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)
}
}
pub trait LookupError {
fn not_found(&self) -> bool;
}
pub trait LookupResultExt {
type Error;
type Output;
/// Transform a [`Result`] with a [`LookupError`] to transform "not
/// found" errors into [`None`]
fn to_option(self) -> Result<Option<Self::Output>, Self::Error>;
}
impl<T, E> LookupResultExt for Result<T, E>
where
E: LookupError,
{
type Output = T;
type Error = E;
fn to_option(self) -> Result<Option<Self::Output>, Self::Error> {
match self {
Ok(v) => Ok(Some(v)),
Err(e) if e.not_found() => Ok(None),
Err(e) => Err(e),
}
}
}
#[derive(Default, Debug, Clone, Copy)]
pub struct Clock {
_private: (),

View File

@ -22,7 +22,7 @@ use ulid::Ulid;
use uuid::Uuid;
use super::client::{lookup_client, ClientFetchError};
use crate::{Clock, DatabaseInconsistencyError, PostgresqlBackend};
use crate::{Clock, DatabaseInconsistencyError, LookupError, PostgresqlBackend};
#[tracing::instrument(
skip_all,
@ -103,9 +103,8 @@ pub enum AccessTokenLookupError {
Inconsistency(#[from] DatabaseInconsistencyError),
}
impl AccessTokenLookupError {
#[must_use]
pub fn not_found(&self) -> bool {
impl LookupError for AccessTokenLookupError {
fn not_found(&self) -> bool {
matches!(self, Self::Database(sqlx::Error::RowNotFound))
}
}

View File

@ -28,7 +28,7 @@ use ulid::Ulid;
use url::Url;
use uuid::Uuid;
use crate::{Clock, PostgresqlBackend};
use crate::{Clock, LookupError, PostgresqlBackend};
// XXX: response_types & contacts
#[derive(Debug)]
@ -81,9 +81,8 @@ pub enum ClientFetchError {
Database(#[from] sqlx::Error),
}
impl ClientFetchError {
#[must_use]
pub fn not_found(&self) -> bool {
impl LookupError for ClientFetchError {
fn not_found(&self) -> bool {
matches!(
self,
Self::Database(sqlx::Error::RowNotFound) | Self::InvalidClientId(_)

View File

@ -24,7 +24,7 @@ use ulid::Ulid;
use uuid::Uuid;
use super::client::{lookup_client, ClientFetchError};
use crate::{Clock, DatabaseInconsistencyError, PostgresqlBackend};
use crate::{Clock, DatabaseInconsistencyError, LookupError, PostgresqlBackend};
#[tracing::instrument(
skip_all,
@ -106,9 +106,8 @@ pub enum RefreshTokenLookupError {
Conversion(#[from] DatabaseInconsistencyError),
}
impl RefreshTokenLookupError {
#[must_use]
pub fn not_found(&self) -> bool {
impl LookupError for RefreshTokenLookupError {
fn not_found(&self) -> bool {
matches!(self, Self::Fetch(sqlx::Error::RowNotFound))
}
}

View File

@ -33,7 +33,7 @@ use uuid::Uuid;
use super::{DatabaseInconsistencyError, PostgresqlBackend};
use crate::{
pagination::{process_page, QueryBuilderExt},
Clock,
Clock, GenericLookupError, LookupError,
};
#[derive(Debug, Clone)]
@ -117,9 +117,8 @@ pub enum ActiveSessionLookupError {
Conversion(#[from] DatabaseInconsistencyError),
}
impl ActiveSessionLookupError {
#[must_use]
pub fn not_found(&self) -> bool {
impl LookupError for ActiveSessionLookupError {
fn not_found(&self) -> bool {
matches!(self, Self::Fetch(sqlx::Error::RowNotFound))
}
}
@ -566,9 +565,8 @@ pub enum UserLookupError {
Inconsistency(#[from] DatabaseInconsistencyError),
}
impl UserLookupError {
#[must_use]
pub fn not_found(&self) -> bool {
impl LookupError for UserLookupError {
fn not_found(&self) -> bool {
matches!(self, Self::Database(sqlx::Error::RowNotFound))
}
}
@ -955,13 +953,13 @@ pub async fn lookup_user_email(
user.id = %user.data,
user_email.id = %id,
),
err(Display),
err,
)]
pub async fn lookup_user_email_by_id(
executor: impl PgExecutor<'_>,
user: &User<PostgresqlBackend>,
id: Ulid,
) -> Result<UserEmail<PostgresqlBackend>, anyhow::Error> {
) -> Result<UserEmail<PostgresqlBackend>, GenericLookupError> {
let res = sqlx::query_as!(
UserEmailLookup,
r#"
@ -981,7 +979,7 @@ pub async fn lookup_user_email_by_id(
.fetch_one(executor)
.instrument(info_span!("Lookup user email"))
.await
.context("could not lookup user email")?;
.map_err(GenericLookupError::what("user email"))?;
Ok(res.into())
}