matrix_sdk/authentication/
mod.rs1use std::{fmt, sync::Arc};
18
19use matrix_sdk_base::{locks::Mutex, SessionMeta};
20use serde::{Deserialize, Serialize};
21use tokio::sync::{broadcast, Mutex as AsyncMutex, OnceCell};
22
23pub mod matrix;
24pub mod oauth;
25
26use self::{
27 matrix::MatrixAuth,
28 oauth::{OAuth, OAuthAuthData, OAuthCtx},
29};
30use crate::{Client, RefreshTokenError, SessionChange};
31
32#[derive(Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
34#[allow(missing_debug_implementations)]
35pub struct SessionTokens {
36 pub access_token: String,
38
39 #[serde(default, skip_serializing_if = "Option::is_none")]
41 pub refresh_token: Option<String>,
42}
43
44#[cfg(not(tarpaulin_include))]
45impl fmt::Debug for SessionTokens {
46 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47 f.debug_struct("SessionTokens").finish_non_exhaustive()
48 }
49}
50
51#[cfg(not(target_family = "wasm"))]
52pub(crate) type SessionCallbackError = Box<dyn std::error::Error + Send + Sync>;
53#[cfg(target_family = "wasm")]
54pub(crate) type SessionCallbackError = Box<dyn std::error::Error>;
55
56#[cfg(not(target_family = "wasm"))]
57pub(crate) type SaveSessionCallback =
58 dyn Fn(Client) -> Result<(), SessionCallbackError> + Send + Sync;
59#[cfg(target_family = "wasm")]
60pub(crate) type SaveSessionCallback = dyn Fn(Client) -> Result<(), SessionCallbackError>;
61
62#[cfg(not(target_family = "wasm"))]
63pub(crate) type ReloadSessionCallback =
64 dyn Fn(Client) -> Result<SessionTokens, SessionCallbackError> + Send + Sync;
65#[cfg(target_family = "wasm")]
66pub(crate) type ReloadSessionCallback =
67 dyn Fn(Client) -> Result<SessionTokens, SessionCallbackError>;
68
69pub(crate) struct AuthCtx {
72 pub(crate) oauth: OAuthCtx,
73
74 pub(crate) handle_refresh_tokens: bool,
77
78 pub(crate) refresh_token_lock: Arc<AsyncMutex<Result<(), RefreshTokenError>>>,
80
81 pub(crate) session_change_sender: broadcast::Sender<SessionChange>,
85
86 pub(crate) auth_data: OnceCell<AuthData>,
88
89 pub(crate) tokens: OnceCell<Mutex<SessionTokens>>,
91
92 pub(crate) reload_session_callback: OnceCell<Box<ReloadSessionCallback>>,
97
98 pub(crate) save_session_callback: OnceCell<Box<SaveSessionCallback>>,
106}
107
108impl AuthCtx {
109 pub(crate) fn session_tokens(&self) -> Option<SessionTokens> {
111 Some(self.tokens.get()?.lock().clone())
112 }
113
114 pub(crate) fn access_token(&self) -> Option<String> {
116 Some(self.tokens.get()?.lock().access_token.clone())
117 }
118
119 pub(crate) fn set_session_tokens(&self, session_tokens: SessionTokens) {
121 if let Some(tokens) = self.tokens.get() {
122 *tokens.lock() = session_tokens;
123 } else {
124 let _ = self.tokens.set(Mutex::new(session_tokens));
125 }
126 }
127}
128
129#[derive(Debug, Clone)]
131#[non_exhaustive]
132pub enum AuthApi {
133 Matrix(MatrixAuth),
135
136 OAuth(OAuth),
138}
139
140#[derive(Debug, Clone)]
142#[non_exhaustive]
143pub enum AuthSession {
144 Matrix(matrix::MatrixSession),
146
147 OAuth(Box<oauth::OAuthSession>),
149}
150
151impl AuthSession {
152 pub fn meta(&self) -> &SessionMeta {
154 match self {
155 AuthSession::Matrix(session) => &session.meta,
156 AuthSession::OAuth(session) => &session.user.meta,
157 }
158 }
159
160 pub fn into_meta(self) -> SessionMeta {
162 match self {
163 AuthSession::Matrix(session) => session.meta,
164 AuthSession::OAuth(session) => session.user.meta,
165 }
166 }
167
168 pub fn access_token(&self) -> &str {
170 match self {
171 AuthSession::Matrix(session) => &session.tokens.access_token,
172 AuthSession::OAuth(session) => &session.user.tokens.access_token,
173 }
174 }
175
176 pub fn get_refresh_token(&self) -> Option<&str> {
178 match self {
179 AuthSession::Matrix(session) => session.tokens.refresh_token.as_deref(),
180 AuthSession::OAuth(session) => session.user.tokens.refresh_token.as_deref(),
181 }
182 }
183}
184
185impl From<matrix::MatrixSession> for AuthSession {
186 fn from(session: matrix::MatrixSession) -> Self {
187 Self::Matrix(session)
188 }
189}
190
191impl From<oauth::OAuthSession> for AuthSession {
192 fn from(session: oauth::OAuthSession) -> Self {
193 Self::OAuth(session.into())
194 }
195}
196
197#[derive(Debug)]
199pub(crate) enum AuthData {
200 Matrix,
202 OAuth(OAuthAuthData),
204}