diff --git a/crates/matrix-sdk/src/client/builder.rs b/crates/matrix-sdk/src/client/builder.rs index 76a27cc50..1c84e4472 100644 --- a/crates/matrix-sdk/src/client/builder.rs +++ b/crates/matrix-sdk/src/client/builder.rs @@ -394,6 +394,7 @@ impl ClientBuilder { Some(RequestConfig::short_retry()), homeserver, None, + None, &[MatrixVersion::V1_0], ) .await diff --git a/crates/matrix-sdk/src/client/mod.rs b/crates/matrix-sdk/src/client/mod.rs index 1e370f726..49421a229 100644 --- a/crates/matrix-sdk/src/client/mod.rs +++ b/crates/matrix-sdk/src/client/mod.rs @@ -344,6 +344,31 @@ impl Client { self.base_client().session_tokens().get_cloned() } + /// Get the current access token for this session. + /// + /// Will be `None` if the client has not been logged in. + /// + /// After login, this token should only change if support for [refreshing + /// access tokens] has been enabled. + /// + /// [refreshing access tokens]: https://spec.matrix.org/v1.3/client-server-api/#refreshing-access-tokens + pub fn access_token(&self) -> Option { + self.session_tokens().map(|tokens| tokens.access_token) + } + + /// Get the current refresh token for this session. + /// + /// Will be `None` if the client has not been logged in, or if the access + /// token doesn't expire. + /// + /// After login, this token should only change if support for [refreshing + /// access tokens] has been enabled. + /// + /// [refreshing access tokens]: https://spec.matrix.org/v1.3/client-server-api/#refreshing-access-tokens + pub fn refresh_token(&self) -> Option { + self.session_tokens().and_then(|tokens| tokens.refresh_token) + } + /// [`Signal`] to get notified when the current access token and optional /// refresh token for this session change. /// @@ -1339,11 +1364,8 @@ impl Client { /// persist_session(client.session()); /// /// // Handle when an `M_UNKNOWN_TOKEN` error is encountered. - /// async fn on_unknown_token_err( - /// client: &Client, - /// session: &Session, - /// ) -> Result<(), Error> { - /// if session.refresh_token.is_some() + /// async fn on_unknown_token_err(client: &Client) -> Result<(), Error> { + /// if client.refresh_token().is_some() /// && client.refresh_access_token().await.is_ok() /// { /// persist_session(client.session()); @@ -1397,7 +1419,8 @@ impl Client { request, None, self.homeserver().await.to_string(), - self.session().as_ref(), + self.access_token().as_deref(), + self.user_id(), self.server_versions().await?, ) .await; @@ -1764,7 +1787,8 @@ impl Client { request, Some(request_config), self.homeserver().await.to_string(), - self.session().as_ref(), + self.access_token().as_deref(), + self.user_id(), self.server_versions().await?, ) .await?) @@ -1865,7 +1889,8 @@ impl Client { request, config, self.homeserver().await.to_string(), - self.session().as_ref(), + self.access_token().as_deref(), + self.user_id(), self.server_versions().await?, ) .await @@ -1880,6 +1905,7 @@ impl Client { None, self.homeserver().await.to_string(), None, + None, &[MatrixVersion::V1_0], ) .await? diff --git a/crates/matrix-sdk/src/error.rs b/crates/matrix-sdk/src/error.rs index a378053c2..754dbb19e 100644 --- a/crates/matrix-sdk/src/error.rs +++ b/crates/matrix-sdk/src/error.rs @@ -98,10 +98,6 @@ pub enum HttpError { #[error("The request cannot be cloned")] UnableToCloneRequest, - /// Tried to send a request without `user_id` in the `Session` - #[error("missing user_id in session")] - UserIdRequired, - /// An error occurred while refreshing the access token. #[error(transparent)] RefreshToken(#[from] RefreshTokenError), diff --git a/crates/matrix-sdk/src/http_client.rs b/crates/matrix-sdk/src/http_client.rs index b03ad5400..a4cd45a47 100644 --- a/crates/matrix-sdk/src/http_client.rs +++ b/crates/matrix-sdk/src/http_client.rs @@ -19,13 +19,16 @@ use bytes::{Bytes, BytesMut}; use http::Response as HttpResponse; use matrix_sdk_common::AsyncTraitDeps; use reqwest::Response; -use ruma::api::{ - error::FromHttpResponseError, AuthScheme, IncomingResponse, MatrixVersion, OutgoingRequest, - OutgoingRequestAppserviceExt, SendAccessToken, +use ruma::{ + api::{ + error::FromHttpResponseError, AuthScheme, IncomingResponse, MatrixVersion, OutgoingRequest, + OutgoingRequestAppserviceExt, SendAccessToken, + }, + UserId, }; use tracing::trace; -use crate::{config::RequestConfig, error::HttpError, Session}; +use crate::{config::RequestConfig, error::HttpError}; pub(crate) const DEFAULT_REQUEST_TIMEOUT: Duration = Duration::from_secs(10); @@ -108,7 +111,8 @@ impl HttpClient { request: Request, config: Option, homeserver: String, - session: Option<&Session>, + access_token: Option<&str>, + user_id: Option<&UserId>, server_versions: &[MatrixVersion], ) -> Result where @@ -126,23 +130,26 @@ impl HttpClient { } trace!("Serializing request"); - // We can't assert the identity without a session. - let request = if !config.assert_identity || session.is_none() { - let send_access_token = if auth_scheme == AuthScheme::None && !config.force_auth { - // Small optimization: Don't take the session lock if we know the auth token - // isn't going to be used anyways. - SendAccessToken::None - } else { - match session { - Some(sess) => { - if config.force_auth { - SendAccessToken::Always(&sess.access_token) - } else { - SendAccessToken::IfRequired(&sess.access_token) - } + // We can't assert the identity without a user_id. + let request = if let Some((access_token, user_id)) = + access_token.filter(|_| config.assert_identity).zip(user_id) + { + request.try_into_http_request_with_user_id::( + &homeserver, + SendAccessToken::Always(access_token), + user_id, + server_versions, + )? + } else { + let send_access_token = match access_token { + Some(access_token) => { + if config.force_auth { + SendAccessToken::Always(access_token) + } else { + SendAccessToken::IfRequired(access_token) } - None => SendAccessToken::None, } + None => SendAccessToken::None, }; request.try_into_http_request::( @@ -150,13 +157,6 @@ impl HttpClient { send_access_token, server_versions, )? - } else { - request.try_into_http_request_with_user_id::( - &homeserver, - SendAccessToken::Always(&session.ok_or(HttpError::UserIdRequired)?.access_token), - &session.ok_or(HttpError::UserIdRequired)?.user_id, - server_versions, - )? }; let request = request.map(|body| body.freeze());