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

Axum migration: /oauth2/userinfo & UserAuthorization util

This commit is contained in:
Quentin Gliech
2022-03-30 16:21:45 +02:00
parent 64900ef1d9
commit 9dad21475e
8 changed files with 424 additions and 96 deletions

View File

@ -15,7 +15,7 @@
use anyhow::Context;
use chrono::{DateTime, Duration, Utc};
use mas_data_model::{AccessToken, Authentication, BrowserSession, Session, User, UserEmail};
use sqlx::{PgConnection, PgExecutor};
use sqlx::{Acquire, PgExecutor, Postgres};
use thiserror::Error;
use super::client::{lookup_client_by_client_id, ClientFetchError};
@ -93,14 +93,26 @@ impl AccessTokenLookupError {
}
}
#[allow(clippy::too_many_lines)]
pub async fn lookup_active_access_token(
conn: &mut PgConnection,
token: &str,
) -> Result<(AccessToken<PostgresqlBackend>, Session<PostgresqlBackend>), AccessTokenLookupError> {
let res = sqlx::query_as!(
OAuth2AccessTokenLookup,
r#"
// TODO: remove that manual async
#[allow(clippy::too_many_lines, clippy::manual_async_fn)]
pub fn lookup_active_access_token<'a, 'c, A>(
conn: A,
token: &'a str,
) -> impl std::future::Future<
Output = Result<
(AccessToken<PostgresqlBackend>, Session<PostgresqlBackend>),
AccessTokenLookupError,
>,
> + Send
+ 'a
where
A: Acquire<'c, Database = Postgres> + Send + 'a,
{
async move {
let mut conn = conn.acquire().await?;
let res = sqlx::query_as!(
OAuth2AccessTokenLookup,
r#"
SELECT
at.id AS "access_token_id",
at.token AS "access_token",
@ -140,73 +152,74 @@ pub async fn lookup_active_access_token(
ORDER BY usa.created_at DESC
LIMIT 1
"#,
token,
)
.fetch_one(&mut *conn)
.await?;
token,
)
.fetch_one(&mut *conn)
.await?;
let access_token = AccessToken {
data: res.access_token_id,
jti: format!("{}", res.access_token_id),
token: res.access_token,
created_at: res.access_token_created_at,
expires_after: Duration::seconds(res.access_token_expires_after.into()),
};
let access_token = AccessToken {
data: res.access_token_id,
jti: format!("{}", res.access_token_id),
token: res.access_token,
created_at: res.access_token_created_at,
expires_after: Duration::seconds(res.access_token_expires_after.into()),
};
let client = lookup_client_by_client_id(&mut *conn, &res.client_id).await?;
let client = lookup_client_by_client_id(&mut *conn, &res.client_id).await?;
let primary_email = match (
res.user_email_id,
res.user_email,
res.user_email_created_at,
res.user_email_confirmed_at,
) {
(Some(id), Some(email), Some(created_at), confirmed_at) => Some(UserEmail {
data: id,
email,
created_at,
confirmed_at,
}),
(None, None, None, None) => None,
_ => return Err(DatabaseInconsistencyError.into()),
};
let primary_email = match (
res.user_email_id,
res.user_email,
res.user_email_created_at,
res.user_email_confirmed_at,
) {
(Some(id), Some(email), Some(created_at), confirmed_at) => Some(UserEmail {
data: id,
email,
created_at,
confirmed_at,
}),
(None, None, None, None) => None,
_ => return Err(DatabaseInconsistencyError.into()),
};
let user = User {
data: res.user_id,
username: res.user_username,
sub: format!("fake-sub-{}", res.user_id),
primary_email,
};
let user = User {
data: res.user_id,
username: res.user_username,
sub: format!("fake-sub-{}", res.user_id),
primary_email,
};
let last_authentication = match (
res.user_session_last_authentication_id,
res.user_session_last_authentication_created_at,
) {
(None, None) => None,
(Some(id), Some(created_at)) => Some(Authentication {
data: id,
created_at,
}),
_ => return Err(DatabaseInconsistencyError.into()),
};
let last_authentication = match (
res.user_session_last_authentication_id,
res.user_session_last_authentication_created_at,
) {
(None, None) => None,
(Some(id), Some(created_at)) => Some(Authentication {
data: id,
created_at,
}),
_ => return Err(DatabaseInconsistencyError.into()),
};
let browser_session = BrowserSession {
data: res.user_session_id,
created_at: res.user_session_created_at,
user,
last_authentication,
};
let browser_session = BrowserSession {
data: res.user_session_id,
created_at: res.user_session_created_at,
user,
last_authentication,
};
let scope = res.scope.parse().map_err(|_e| DatabaseInconsistencyError)?;
let scope = res.scope.parse().map_err(|_e| DatabaseInconsistencyError)?;
let session = Session {
data: res.session_id,
client,
browser_session,
scope,
};
let session = Session {
data: res.session_id,
client,
browser_session,
scope,
};
Ok((access_token, session))
Ok((access_token, session))
}
}
pub async fn revoke_access_token(