diff --git a/crates/handlers/src/upstream_oauth2/backchannel_logout.rs b/crates/handlers/src/upstream_oauth2/backchannel_logout.rs index 63454741c..254a4d010 100644 --- a/crates/handlers/src/upstream_oauth2/backchannel_logout.rs +++ b/crates/handlers/src/upstream_oauth2/backchannel_logout.rs @@ -1,3 +1,4 @@ +// Copyright 2025, 2026 Element Creations Ltd. // Copyright 2025 New Vector Ltd. // // SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial @@ -249,14 +250,14 @@ pub(crate) async fn post( } UpstreamOAuthProviderOnBackchannelLogout::LogoutBrowserOnly => { let filter = BrowserSessionFilter::new() - .authenticated_by_upstream_sessions_only(auth_session_filter) + .linked_to_upstream_sessions_only(auth_session_filter) .active_only(); let affected = repo.browser_session().finish_bulk(&clock, filter).await?; tracing::info!("Finished {affected} browser sessions"); } UpstreamOAuthProviderOnBackchannelLogout::LogoutAll => { - let browser_session_filter = BrowserSessionFilter::new() - .authenticated_by_upstream_sessions_only(auth_session_filter); + let browser_session_filter = + BrowserSessionFilter::new().linked_to_upstream_sessions_only(auth_session_filter); // We need to loop through all the browser sessions to find all the // users affected so that we can trigger a device sync job for them diff --git a/crates/storage-pg/src/iden.rs b/crates/storage-pg/src/iden.rs index 4e5a39139..f1af1a5d2 100644 --- a/crates/storage-pg/src/iden.rs +++ b/crates/storage-pg/src/iden.rs @@ -1,3 +1,4 @@ +// Copyright 2025, 2026 Element Creations Ltd. // Copyright 2024, 2025 New Vector Ltd. // Copyright 2023, 2024 The Matrix.org Foundation C.I.C. // @@ -18,18 +19,6 @@ pub enum UserSessions { LastActiveIp, } -#[derive(sea_query::Iden)] -#[expect(dead_code)] -pub enum UserSessionAuthentications { - Table, - UserSessionAuthenticationId, - UserSessionId, - CreatedAt, - UserPasswordId, - #[iden = "upstream_oauth_authorization_session_id"] - UpstreamOAuthAuthorizationSessionId, -} - #[derive(sea_query::Iden)] pub enum Users { Table, @@ -204,6 +193,7 @@ pub enum UpstreamOAuthAuthorizationSessions { CompletedAt, ConsumedAt, UnlinkedAt, + UserSessionId, } #[derive(sea_query::Iden)] diff --git a/crates/storage-pg/src/user/session.rs b/crates/storage-pg/src/user/session.rs index 8644d7666..9c546695e 100644 --- a/crates/storage-pg/src/user/session.rs +++ b/crates/storage-pg/src/user/session.rs @@ -1,3 +1,4 @@ +// Copyright 2025, 2026 Element Creations Ltd. // Copyright 2024, 2025 New Vector Ltd. // Copyright 2022-2024 The Matrix.org Foundation C.I.C. // @@ -27,7 +28,7 @@ use uuid::Uuid; use crate::{ DatabaseError, DatabaseInconsistencyError, filter::StatementExt, - iden::{UpstreamOAuthAuthorizationSessions, UserSessionAuthentications, UserSessions, Users}, + iden::{UpstreamOAuthAuthorizationSessions, UserSessions, Users}, pagination::QueryBuilderExt, tracing::ExecuteExt, }; @@ -154,26 +155,14 @@ impl crate::filter::Filter for BrowserSessionFilter<'_> { .add_option(self.last_active_before().map(|last_active_before| { Expr::col((UserSessions::Table, UserSessions::LastActiveAt)).lt(last_active_before) })) - .add_option(self.authenticated_by_upstream_sessions().map(|filter| { - // For filtering by upstream sessions, we need to hop over the - // `user_session_authentications` table - let join_expr = Expr::col(( - UserSessionAuthentications::Table, - UserSessionAuthentications::UpstreamOAuthAuthorizationSessionId, - )) - .eq(Expr::col(( - UpstreamOAuthAuthorizationSessions::Table, - UpstreamOAuthAuthorizationSessions::UpstreamOAuthAuthorizationSessionId, - ))); - + .add_option(self.linked_to_upstream_sessions().map(|filter| { Expr::col((UserSessions::Table, UserSessions::UserSessionId)).in_subquery( Query::select() .expr(Expr::col(( - UserSessionAuthentications::Table, - UserSessionAuthentications::UserSessionId, + UpstreamOAuthAuthorizationSessions::Table, + UpstreamOAuthAuthorizationSessions::UserSessionId, ))) - .from(UserSessionAuthentications::Table) - .inner_join(UpstreamOAuthAuthorizationSessions::Table, join_expr) + .from(UpstreamOAuthAuthorizationSessions::Table) .apply_filter(filter) .take(), ) diff --git a/crates/storage-pg/src/user/tests.rs b/crates/storage-pg/src/user/tests.rs index aa8c9dd07..be106c56f 100644 --- a/crates/storage-pg/src/user/tests.rs +++ b/crates/storage-pg/src/user/tests.rs @@ -1,3 +1,4 @@ +// Copyright 2025, 2026 Element Creations Ltd. // Copyright 2024, 2025 New Vector Ltd. // Copyright 2023, 2024 The Matrix.org Foundation C.I.C. // @@ -799,8 +800,8 @@ async fn test_user_session(pool: PgPool) { // This will match all authorization sessions, which matches exactly that one // authorization session let upstream_oauth_session_filter = UpstreamOAuthSessionFilter::new(); - let filter = BrowserSessionFilter::new() - .authenticated_by_upstream_sessions_only(upstream_oauth_session_filter); + let filter = + BrowserSessionFilter::new().linked_to_upstream_sessions_only(upstream_oauth_session_filter); // Now try to look it up let page = repo diff --git a/crates/storage/src/user/session.rs b/crates/storage/src/user/session.rs index 155556454..78e2f6ebd 100644 --- a/crates/storage/src/user/session.rs +++ b/crates/storage/src/user/session.rs @@ -1,3 +1,4 @@ +// Copyright 2025, 2026 Element Creations Ltd. // Copyright 2024, 2025 New Vector Ltd. // Copyright 2022-2024 The Matrix.org Foundation C.I.C. // @@ -41,7 +42,7 @@ pub struct BrowserSessionFilter<'a> { state: Option, last_active_before: Option>, last_active_after: Option>, - authenticated_by_upstream_sessions: Option>, + linked_to_upstream_sessions: Option>, } impl<'a> BrowserSessionFilter<'a> { @@ -114,21 +115,20 @@ impl<'a> BrowserSessionFilter<'a> { self.state } - /// Only return browser sessions authenticated by the given upstream OAuth - /// sessions + /// Only return browser sessions linked to the given upstream OAuth sessions #[must_use] - pub fn authenticated_by_upstream_sessions_only( + pub fn linked_to_upstream_sessions_only( mut self, filter: UpstreamOAuthSessionFilter<'a>, ) -> Self { - self.authenticated_by_upstream_sessions = Some(filter); + self.linked_to_upstream_sessions = Some(filter); self } /// Get the upstream OAuth session filter #[must_use] - pub fn authenticated_by_upstream_sessions(&self) -> Option> { - self.authenticated_by_upstream_sessions + pub fn linked_to_upstream_sessions(&self) -> Option> { + self.linked_to_upstream_sessions } }