From 15c9e470c80844da8539c41689eaf9735f2d1a59 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Mon, 26 Apr 2021 22:42:07 +0200 Subject: [PATCH] client: Remove session data other than the access token --- ruma-client/src/client_api.rs | 91 +++++++++++------------------------ ruma-client/src/lib.rs | 43 ++++++++--------- 2 files changed, 48 insertions(+), 86 deletions(-) diff --git a/ruma-client/src/client_api.rs b/ruma-client/src/client_api.rs index 533d8f5d..b7de86c9 100644 --- a/ruma-client/src/client_api.rs +++ b/ruma-client/src/client_api.rs @@ -3,34 +3,32 @@ use std::time::Duration; use assign::assign; use async_stream::try_stream; use futures_core::stream::Stream; -use ruma_client_api::r0::sync::sync_events::{ - Filter as SyncFilter, Request as SyncRequest, Response as SyncResponse, +use ruma_client_api::r0::{ + account::register::{self, RegistrationKind}, + session::login::{self, LoginInfo, UserIdentifier}, + sync::sync_events, }; use ruma_common::presence::PresenceState; use ruma_identifiers::DeviceId; -use super::{Client, Error, Identification, Session}; +use super::{Client, Error}; +/// Client-API specific functionality of `Client`. impl Client { /// Log in with a username and password. /// - /// In contrast to `api::r0::session::login::call()`, this method stores the - /// session data returned by the endpoint in this client, instead of - /// returning it. + /// In contrast to [`request`], this method stores the access token returned by the endpoint in + /// this client, in addition to returning it. pub async fn log_in( &self, user: &str, password: &str, device_id: Option<&DeviceId>, initial_device_display_name: Option<&str>, - ) -> Result> { - use ruma_client_api::r0::session::login::{ - LoginInfo, Request as LoginRequest, UserIdentifier, - }; - + ) -> Result> { let response = self .request(assign!( - LoginRequest::new( + login::Request::new( LoginInfo::Password { identifier: UserIdentifier::MatrixId(user), password } ), { device_id, @@ -39,92 +37,61 @@ impl Client { )) .await?; - let session = Session { - access_token: response.access_token, - identification: Some(Identification { - device_id: response.device_id, - user_id: response.user_id, - }), - }; - *self.0.session.lock().unwrap() = Some(session.clone()); + *self.0.access_token.lock().unwrap() = Some(response.access_token.clone()); - Ok(session) + Ok(response) } - /// Register as a guest. In contrast to `api::r0::account::register::call()`, - /// this method stores the session data returned by the endpoint in this - /// client, instead of returning it. + /// Register as a guest. + /// + /// In contrast to [`request`], this method stores the access token returned by the endpoint in + /// this client, in addition to returning it. pub async fn register_guest( &self, - ) -> Result> { - use ruma_client_api::r0::account::register::{self, RegistrationKind}; - + ) -> Result> { let response = self .request(assign!(register::Request::new(), { kind: RegistrationKind::Guest })) .await?; - let session = Session { - // since we supply inhibit_login: false above, the access token needs to be there - // TODO: maybe unwrap is not the best solution though - access_token: response.access_token.unwrap(), - identification: Some(Identification { - // same as access_token - device_id: response.device_id.unwrap(), - user_id: response.user_id, - }), - }; - *self.0.session.lock().unwrap() = Some(session.clone()); + *self.0.access_token.lock().unwrap() = response.access_token.clone(); - Ok(session) + Ok(response) } /// Register as a new user on this server. /// - /// In contrast to `api::r0::account::register::call()`, this method stores - /// the session data returned by the endpoint in this client, instead of - /// returning it. + /// In contrast to [`request`], this method stores the access token returned by the endpoint in + /// this client, in addition to returning it. /// - /// The username is the local part of the returned user_id. If it is - /// omitted from this request, the server will generate one. + /// The username is the local part of the returned user_id. If it is omitted from this request, + /// the server will generate one. pub async fn register_user( &self, username: Option<&str>, password: &str, - ) -> Result> { - use ruma_client_api::r0::account::register; - + ) -> Result> { let response = self .request(assign!(register::Request::new(), { username, password: Some(password) })) .await?; - let session = Session { - // since we supply inhibit_login: false above, the access token needs to be there - // TODO: maybe unwrap is not the best solution though - access_token: response.access_token.unwrap(), - identification: Some(Identification { - // same as access_token - device_id: response.device_id.unwrap(), - user_id: response.user_id, - }), - }; - *self.0.session.lock().unwrap() = Some(session.clone()); + *self.0.access_token.lock().unwrap() = response.access_token.clone(); - Ok(session) + Ok(response) } /// Convenience method that represents repeated calls to the sync_events endpoint as a stream. pub fn sync<'a>( &self, - filter: Option<&'a SyncFilter<'a>>, + filter: Option<&'a sync_events::Filter<'a>>, mut since: String, set_presence: &'a PresenceState, timeout: Option, - ) -> impl Stream>> + 'a { + ) -> impl Stream>> + 'a { let client = self.clone(); try_stream! { loop { let response = client - .request(assign!(SyncRequest::new(), { + .request(assign!(sync_events::Request::new(), { filter, since: Some(&since), set_presence, diff --git a/ruma-client/src/lib.rs b/ruma-client/src/lib.rs index d62e35e1..b0deaa4e 100644 --- a/ruma-client/src/lib.rs +++ b/ruma-client/src/lib.rs @@ -1,6 +1,6 @@ #![doc(html_favicon_url = "https://www.ruma.io/favicon.ico")] #![doc(html_logo_url = "https://www.ruma.io/images/logo.png")] -//! A [Matrix](https://matrix.org/) client library. +//! A minimal [Matrix](https://matrix.org/) client library. //! //! # Usage //! @@ -24,17 +24,16 @@ //! }; //! ``` //! -//! You can also pass an existing session to the `Client` constructor to restore a previous session -//! rather than calling `log_in`. This can also be used to create a session for an application -//! service that does not need to log in, but uses the access_token directly: +//! You can also pass an existing access token to the `Client` constructor to restore a previous +//! session rather than calling `log_in`. This can also be used to create a session for an +//! application service that does not need to log in, but uses the access_token directly: //! //! ```no_run -//! use ruma_client::{Client, Session}; +//! use ruma_client::Client; //! //! let work = async { //! let homeserver_url = "https://example.com".parse().unwrap(); -//! let session = Session{access_token: "as_access_token".to_string(), identification: None}; -//! let client = Client::new(homeserver_url, Some(session)); +//! let client = Client::new(homeserver_url, Some("as_access_token".into())); //! //! // make calls to the API //! }; @@ -116,12 +115,8 @@ use ruma_serde::urlencoded; #[cfg(feature = "client-api")] mod client_api; mod error; -mod session; -pub use self::{ - error::Error, - session::{Identification, Session}, -}; +pub use self::error::Error; #[cfg(not(feature = "_tls"))] type Connector = HttpConnector; @@ -162,16 +157,16 @@ struct ClientData { hyper: HyperClient, /// User session data. - session: Mutex>, + access_token: Mutex>, } impl Client { /// Creates a new client. - pub fn new(homeserver_url: Uri, session: Option) -> Self { + pub fn new(homeserver_url: Uri, access_token: Option) -> Self { Self(Arc::new(ClientData { homeserver_url, hyper: HyperClient::builder().build(create_connector()), - session: Mutex::new(session), + access_token: Mutex::new(access_token), })) } @@ -181,20 +176,20 @@ impl Client { pub fn custom( client_builder: &hyper::client::Builder, homeserver_url: Uri, - session: Option, + access_token: Option, ) -> Self { Self(Arc::new(ClientData { homeserver_url, hyper: client_builder.build(create_connector()), - session: Mutex::new(session), + access_token: Mutex::new(access_token), })) } - /// Get a copy of the current `Session`, if any. + /// Get a copy of the current `access_token`, if any. /// /// Useful for serializing and persisting the session to be restored later. - pub fn session(&self) -> Option { - self.0.session.lock().expect("session mutex was poisoned").clone() + pub fn access_token(&self) -> Option { + self.0.access_token.lock().expect("session mutex was poisoned").clone() } /// Makes a request to a Matrix API endpoint. @@ -213,11 +208,11 @@ impl Client { ) -> Result> { let client = self.0.clone(); let mut http_request = { - let session; + let lock; let access_token = if Request::METADATA.authentication == AuthScheme::AccessToken { - session = client.session.lock().unwrap(); - if let Some(s) = &*session { - SendAccessToken::IfRequired(s.access_token.as_str()) + lock = client.access_token.lock().unwrap(); + if let Some(access_token) = &*lock { + SendAccessToken::IfRequired(access_token.as_str()) } else { return Err(Error::AuthenticationRequired); }