From 6bf811a7f4fc8152706b709faff92b47fffc8cd1 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Tue, 2 Dec 2025 18:09:47 +0100 Subject: [PATCH] Add the Matrix user display name in the compat SSO login context --- .../handlers/src/compat/login_sso_complete.rs | 41 +++++++++++++++++-- crates/templates/src/context.rs | 29 +++++++++---- 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/crates/handlers/src/compat/login_sso_complete.rs b/crates/handlers/src/compat/login_sso_complete.rs index a4fbb24fb..0062a65da 100644 --- a/crates/handlers/src/compat/login_sso_complete.rs +++ b/crates/handlers/src/compat/login_sso_complete.rs @@ -4,7 +4,7 @@ // SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial // Please see LICENSE files in the repository root for full details. -use std::collections::HashMap; +use std::{collections::HashMap, sync::Arc}; use anyhow::Context; use axum::{ @@ -18,7 +18,8 @@ use mas_axum_utils::{ cookies::CookieJar, csrf::{CsrfExt, ProtectedForm}, }; -use mas_data_model::{BoxClock, BoxRng, Clock}; +use mas_data_model::{BoxClock, BoxRng, Clock, MatrixUser}; +use mas_matrix::HomeserverConnection; use mas_router::{CompatLoginSsoAction, UrlBuilder}; use mas_storage::{BoxRepository, RepositoryAccess, compat::CompatSsoLoginRepository}; use mas_templates::{CompatSsoContext, ErrorContext, TemplateContext, Templates}; @@ -56,6 +57,7 @@ pub async fn get( mut repo: BoxRepository, State(templates): State, State(url_builder): State, + State(homeserver): State>, cookie_jar: CookieJar, Path(id): Path, Query(params): Query, @@ -96,6 +98,9 @@ pub async fn get( .context("Could not find compat SSO login") .map_err(InternalError::from_anyhow)?; + // We can close the repository early, we don't need it at this point + repo.save().await?; + // Bail out if that login session is more than 30min old if clock.now() > login.created_at + Duration::microseconds(30 * 60 * 1000 * 1000) { let ctx = ErrorContext::new() @@ -107,7 +112,37 @@ pub async fn get( return Ok((cookie_jar, Html(content)).into_response()); } - let ctx = CompatSsoContext::new(login) + // Fetch informations about the user. This is purely cosmetic, so we let it + // fail and put a 1s timeout to it in case we fail to query it + // XXX: we're likely to need this in other places + let localpart = &session.user.username; + let display_name = match tokio::time::timeout( + std::time::Duration::from_secs(1), + homeserver.query_user(localpart), + ) + .await + { + Ok(Ok(user)) => user.displayname, + Ok(Err(err)) => { + tracing::warn!( + error = &*err as &dyn std::error::Error, + localpart, + "Failed to query user" + ); + None + } + Err(_) => { + tracing::warn!(localpart, "Timed out while querying user"); + None + } + }; + + let matrix_user = MatrixUser { + mxid: homeserver.mxid(localpart), + display_name, + }; + + let ctx = CompatSsoContext::new(login, matrix_user) .with_session(session) .with_csrf(csrf_token.form_value()) .with_language(locale); diff --git a/crates/templates/src/context.rs b/crates/templates/src/context.rs index 73a38972f..c881198f8 100644 --- a/crates/templates/src/context.rs +++ b/crates/templates/src/context.rs @@ -872,6 +872,7 @@ impl PolicyViolationContext { pub struct CompatSsoContext { login: CompatSsoLogin, action: PostAuthAction, + matrix_user: MatrixUser, } impl TemplateContext for CompatSsoContext { @@ -884,23 +885,33 @@ impl TemplateContext for CompatSsoContext { Self: Sized, { let id = Ulid::from_datetime_with_source(now.into(), rng); - sample_list(vec![CompatSsoContext::new(CompatSsoLogin { - id, - redirect_uri: Url::parse("https://app.element.io/").unwrap(), - login_token: "abcdefghijklmnopqrstuvwxyz012345".into(), - created_at: now, - state: CompatSsoLoginState::Pending, - })]) + sample_list(vec![CompatSsoContext::new( + CompatSsoLogin { + id, + redirect_uri: Url::parse("https://app.element.io/").unwrap(), + login_token: "abcdefghijklmnopqrstuvwxyz012345".into(), + created_at: now, + state: CompatSsoLoginState::Pending, + }, + MatrixUser { + mxid: "@alice:example.com".to_owned(), + display_name: Some("Alice".to_owned()), + }, + )]) } } impl CompatSsoContext { /// Constructs a context for the legacy SSO login page #[must_use] - pub fn new(login: CompatSsoLogin) -> Self + pub fn new(login: CompatSsoLogin, matrix_user: MatrixUser) -> Self where { let action = PostAuthAction::continue_compat_sso_login(login.id); - Self { login, action } + Self { + login, + action, + matrix_user, + } } }