Skip to main content

mas_axum_utils/
log_context.rs

1// Copyright 2026 Element Creations Ltd.
2//
3// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
4// Please see LICENSE files in the repository root for full details.
5
6//! Ergonomic glue between domain types and the [`LogContext`] requester slot.
7//!
8//! Auth-resolution sites can call `value.maybe_record_as_requester()` on a
9//! [`User`], [`BrowserSession`], [`Session`], [`CompatSession`] or [`Client`]
10//! instead of reaching for [`LogContext::maybe_set_requester`] + [`Requester`]
11//! directly. Each call site should record the entity that *authenticated the
12//! request* exactly once; [`LogContext`] is first-writer-wins, so an accidental
13//! second call is harmless.
14
15use mas_context::{LogContext, Requester};
16use mas_data_model::{BrowserSession, Client, CompatSession, Session, User};
17
18pub trait RecordAsRequester {
19    /// Record `self` as the [`Requester`] on the current [`LogContext`], if
20    /// any.
21    ///
22    /// First writer wins — calling on a request that already has a requester
23    /// recorded is a no-op.
24    fn maybe_record_as_requester(&self);
25}
26
27impl RecordAsRequester for User {
28    fn maybe_record_as_requester(&self) {
29        LogContext::maybe_set_requester(Requester::user(self.id, self.username.clone()));
30    }
31}
32
33impl RecordAsRequester for BrowserSession {
34    fn maybe_record_as_requester(&self) {
35        self.user.maybe_record_as_requester();
36    }
37}
38
39impl RecordAsRequester for Session {
40    /// Records the `OAuth2` session's user (without a username) when it has
41    /// one, otherwise the client acting on its own behalf
42    /// (client-credentials).
43    fn maybe_record_as_requester(&self) {
44        if let Some(user_id) = self.user_id {
45            LogContext::maybe_set_requester(Requester::user_id_only(user_id));
46        } else {
47            LogContext::maybe_set_requester(Requester::oauth2_client(self.client_id));
48        }
49    }
50}
51
52impl RecordAsRequester for CompatSession {
53    fn maybe_record_as_requester(&self) {
54        LogContext::maybe_set_requester(Requester::user_id_only(self.user_id));
55    }
56}
57
58impl RecordAsRequester for Client {
59    fn maybe_record_as_requester(&self) {
60        LogContext::maybe_set_requester(Requester::oauth2_client(self.id));
61    }
62}