You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-11-20 12:02:22 +03:00
frontend: Show all compatibilities sessions, not just SSO logins
Also cleans up a bunch of things in the frontend
This commit is contained in:
@@ -14,14 +14,20 @@
|
||||
|
||||
use async_trait::async_trait;
|
||||
use chrono::{DateTime, Utc};
|
||||
use mas_data_model::{CompatSession, CompatSessionState, Device, User};
|
||||
use mas_storage::{compat::CompatSessionRepository, Clock};
|
||||
use mas_data_model::{
|
||||
CompatSession, CompatSessionState, CompatSsoLogin, CompatSsoLoginState, Device, User,
|
||||
};
|
||||
use mas_storage::{compat::CompatSessionRepository, Clock, Page, Pagination};
|
||||
use rand::RngCore;
|
||||
use sqlx::PgConnection;
|
||||
use sqlx::{PgConnection, QueryBuilder};
|
||||
use ulid::Ulid;
|
||||
use url::Url;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{tracing::ExecuteExt, DatabaseError, DatabaseInconsistencyError, LookupResultExt};
|
||||
use crate::{
|
||||
pagination::QueryBuilderExt, tracing::ExecuteExt, DatabaseError, DatabaseInconsistencyError,
|
||||
LookupResultExt,
|
||||
};
|
||||
|
||||
/// An implementation of [`CompatSessionRepository`] for a PostgreSQL connection
|
||||
pub struct PgCompatSessionRepository<'c> {
|
||||
@@ -75,6 +81,101 @@ impl TryFrom<CompatSessionLookup> for CompatSession {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(sqlx::FromRow)]
|
||||
struct CompatSessionAndSsoLoginLookup {
|
||||
compat_session_id: Uuid,
|
||||
device_id: String,
|
||||
user_id: Uuid,
|
||||
created_at: DateTime<Utc>,
|
||||
finished_at: Option<DateTime<Utc>>,
|
||||
is_synapse_admin: bool,
|
||||
compat_sso_login_id: Option<Uuid>,
|
||||
compat_sso_login_token: Option<String>,
|
||||
compat_sso_login_redirect_uri: Option<String>,
|
||||
compat_sso_login_created_at: Option<DateTime<Utc>>,
|
||||
compat_sso_login_fulfilled_at: Option<DateTime<Utc>>,
|
||||
compat_sso_login_exchanged_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
impl TryFrom<CompatSessionAndSsoLoginLookup> for (CompatSession, Option<CompatSsoLogin>) {
|
||||
type Error = DatabaseInconsistencyError;
|
||||
|
||||
fn try_from(value: CompatSessionAndSsoLoginLookup) -> Result<Self, Self::Error> {
|
||||
let id = value.compat_session_id.into();
|
||||
let device = Device::try_from(value.device_id).map_err(|e| {
|
||||
DatabaseInconsistencyError::on("compat_sessions")
|
||||
.column("device_id")
|
||||
.row(id)
|
||||
.source(e)
|
||||
})?;
|
||||
|
||||
let state = match value.finished_at {
|
||||
None => CompatSessionState::Valid,
|
||||
Some(finished_at) => CompatSessionState::Finished { finished_at },
|
||||
};
|
||||
|
||||
let session = CompatSession {
|
||||
id,
|
||||
state,
|
||||
user_id: value.user_id.into(),
|
||||
device,
|
||||
created_at: value.created_at,
|
||||
is_synapse_admin: value.is_synapse_admin,
|
||||
};
|
||||
|
||||
match (
|
||||
value.compat_sso_login_id,
|
||||
value.compat_sso_login_token,
|
||||
value.compat_sso_login_redirect_uri,
|
||||
value.compat_sso_login_created_at,
|
||||
value.compat_sso_login_fulfilled_at,
|
||||
value.compat_sso_login_exchanged_at,
|
||||
) {
|
||||
(None, None, None, None, None, None) => Ok((session, None)),
|
||||
(
|
||||
Some(id),
|
||||
Some(login_token),
|
||||
Some(redirect_uri),
|
||||
Some(created_at),
|
||||
fulfilled_at,
|
||||
exchanged_at,
|
||||
) => {
|
||||
let id = id.into();
|
||||
let redirect_uri = Url::parse(&redirect_uri).map_err(|e| {
|
||||
DatabaseInconsistencyError::on("compat_sso_logins")
|
||||
.column("redirect_uri")
|
||||
.row(id)
|
||||
.source(e)
|
||||
})?;
|
||||
|
||||
let state = match (fulfilled_at, exchanged_at) {
|
||||
(Some(fulfilled_at), None) => CompatSsoLoginState::Fulfilled {
|
||||
fulfilled_at,
|
||||
session_id: session.id,
|
||||
},
|
||||
(Some(fulfilled_at), Some(exchanged_at)) => CompatSsoLoginState::Exchanged {
|
||||
fulfilled_at,
|
||||
exchanged_at,
|
||||
session_id: session.id,
|
||||
},
|
||||
_ => return Err(DatabaseInconsistencyError::on("compat_sso_logins").row(id)),
|
||||
};
|
||||
|
||||
let login = CompatSsoLogin {
|
||||
id,
|
||||
redirect_uri,
|
||||
login_token,
|
||||
created_at,
|
||||
state,
|
||||
};
|
||||
|
||||
Ok((session, Some(login)))
|
||||
}
|
||||
_ => Err(DatabaseInconsistencyError::on("compat_sso_logins").row(id)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<'c> CompatSessionRepository for PgCompatSessionRepository<'c> {
|
||||
type Error = DatabaseError;
|
||||
@@ -201,4 +302,53 @@ impl<'c> CompatSessionRepository for PgCompatSessionRepository<'c> {
|
||||
|
||||
Ok(compat_session)
|
||||
}
|
||||
|
||||
#[tracing::instrument(
|
||||
name = "db.compat_session.list_paginated",
|
||||
skip_all,
|
||||
fields(
|
||||
db.statement,
|
||||
%user.id,
|
||||
),
|
||||
err,
|
||||
)]
|
||||
async fn list_paginated(
|
||||
&mut self,
|
||||
user: &User,
|
||||
pagination: Pagination,
|
||||
) -> Result<Page<(CompatSession, Option<CompatSsoLogin>)>, Self::Error> {
|
||||
let mut query = QueryBuilder::new(
|
||||
r#"
|
||||
SELECT cs.compat_session_id
|
||||
, cs.device_id
|
||||
, cs.user_id
|
||||
, cs.created_at
|
||||
, cs.finished_at
|
||||
, cs.is_synapse_admin
|
||||
, cl.compat_sso_login_id
|
||||
, cl.login_token as compat_sso_login_token
|
||||
, cl.redirect_uri as compat_sso_login_redirect_uri
|
||||
, cl.created_at as compat_sso_login_created_at
|
||||
, cl.fulfilled_at as compat_sso_login_fulfilled_at
|
||||
, cl.exchanged_at as compat_sso_login_exchanged_at
|
||||
|
||||
FROM compat_sessions cs
|
||||
LEFT JOIN compat_sso_logins cl USING (compat_session_id)
|
||||
"#,
|
||||
);
|
||||
|
||||
query
|
||||
.push(" WHERE cs.user_id = ")
|
||||
.push_bind(Uuid::from(user.id))
|
||||
.generate_pagination("cs.compat_session_id", pagination);
|
||||
|
||||
let edges: Vec<CompatSessionAndSsoLoginLookup> = query
|
||||
.build_query_as()
|
||||
.traced()
|
||||
.fetch_all(&mut *self.conn)
|
||||
.await?;
|
||||
|
||||
let page = pagination.process(edges).try_map(TryFrom::try_from)?;
|
||||
Ok(page)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user