matrix_sdk/authentication/
mod.rs1use std::sync::Arc;
18
19use as_variant::as_variant;
20use matrix_sdk_base::SessionMeta;
21use tokio::sync::{broadcast, Mutex, OnceCell};
22
23pub mod matrix;
24#[cfg(feature = "experimental-oidc")]
25pub mod oidc;
26
27use self::matrix::{MatrixAuth, MatrixAuthData};
28#[cfg(feature = "experimental-oidc")]
29use self::oidc::{Oidc, OidcAuthData, OidcCtx};
30use crate::{Client, RefreshTokenError, SessionChange};
31
32#[cfg(all(feature = "experimental-oidc", feature = "e2e-encryption", not(target_arch = "wasm32")))]
33pub mod qrcode;
34
35#[allow(missing_debug_implementations, clippy::large_enum_variant)]
37pub enum SessionTokens {
38 Matrix(matrix::MatrixSessionTokens),
40 #[cfg(feature = "experimental-oidc")]
41 Oidc(oidc::OidcSessionTokens),
43}
44
45pub(crate) type SessionCallbackError = Box<dyn std::error::Error + Send + Sync>;
46pub(crate) type SaveSessionCallback =
47 dyn Fn(Client) -> Result<(), SessionCallbackError> + Send + Sync;
48pub(crate) type ReloadSessionCallback =
49 dyn Fn(Client) -> Result<SessionTokens, SessionCallbackError> + Send + Sync;
50
51pub(crate) struct AuthCtx {
54 #[cfg(feature = "experimental-oidc")]
55 pub(crate) oidc: OidcCtx,
56
57 pub(crate) handle_refresh_tokens: bool,
60
61 pub(crate) refresh_token_lock: Arc<Mutex<Result<(), RefreshTokenError>>>,
63
64 pub(crate) session_change_sender: broadcast::Sender<SessionChange>,
68
69 pub(crate) auth_data: OnceCell<AuthData>,
71
72 pub(crate) reload_session_callback: OnceCell<Box<ReloadSessionCallback>>,
77
78 pub(crate) save_session_callback: OnceCell<Box<SaveSessionCallback>>,
86}
87
88#[derive(Debug, Clone)]
90#[non_exhaustive]
91pub enum AuthApi {
92 Matrix(MatrixAuth),
94
95 #[cfg(feature = "experimental-oidc")]
97 Oidc(Oidc),
98}
99
100#[derive(Debug, Clone)]
102#[non_exhaustive]
103pub enum AuthSession {
104 Matrix(matrix::MatrixSession),
106
107 #[cfg(feature = "experimental-oidc")]
109 Oidc(Box<oidc::OidcSession>),
110}
111
112impl AuthSession {
113 pub fn meta(&self) -> &SessionMeta {
115 match self {
116 AuthSession::Matrix(session) => &session.meta,
117 #[cfg(feature = "experimental-oidc")]
118 AuthSession::Oidc(session) => &session.user.meta,
119 }
120 }
121
122 pub fn into_meta(self) -> SessionMeta {
124 match self {
125 AuthSession::Matrix(session) => session.meta,
126 #[cfg(feature = "experimental-oidc")]
127 AuthSession::Oidc(session) => session.user.meta,
128 }
129 }
130
131 pub fn access_token(&self) -> &str {
133 match self {
134 AuthSession::Matrix(session) => &session.tokens.access_token,
135 #[cfg(feature = "experimental-oidc")]
136 AuthSession::Oidc(session) => &session.user.tokens.access_token,
137 }
138 }
139
140 pub fn get_refresh_token(&self) -> Option<&str> {
142 match self {
143 AuthSession::Matrix(session) => session.tokens.refresh_token.as_deref(),
144 #[cfg(feature = "experimental-oidc")]
145 AuthSession::Oidc(session) => session.user.tokens.refresh_token.as_deref(),
146 }
147 }
148}
149
150impl From<matrix::MatrixSession> for AuthSession {
151 fn from(session: matrix::MatrixSession) -> Self {
152 Self::Matrix(session)
153 }
154}
155
156#[cfg(feature = "experimental-oidc")]
157impl From<oidc::OidcSession> for AuthSession {
158 fn from(session: oidc::OidcSession) -> Self {
159 Self::Oidc(session.into())
160 }
161}
162
163#[derive(Debug)]
165pub(crate) enum AuthData {
166 Matrix(MatrixAuthData),
168 #[cfg(feature = "experimental-oidc")]
170 Oidc(OidcAuthData),
171}
172
173impl AuthData {
174 pub(crate) fn as_matrix(&self) -> Option<&MatrixAuthData> {
175 as_variant!(self, Self::Matrix)
176 }
177
178 pub(crate) fn access_token(&self) -> Option<String> {
179 let token = match self {
180 Self::Matrix(d) => d.tokens.get().access_token,
181 #[cfg(feature = "experimental-oidc")]
182 Self::Oidc(d) => d.tokens.get()?.get().access_token,
183 };
184
185 Some(token)
186 }
187}