From a10a26a68d7870f421c93958925b8d326a2a6c19 Mon Sep 17 00:00:00 2001 From: Doug Date: Tue, 19 Jul 2022 11:36:34 +0100 Subject: [PATCH] Tidy up authentication service. Add HomeserverLoginDetails --- bindings/matrix-sdk-ffi/src/api.udl | 21 +++-- .../src/authentication_service.rs | 79 +++++++++++-------- 2 files changed, 57 insertions(+), 43 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/api.udl b/bindings/matrix-sdk-ffi/src/api.udl index 80a24aa20..5ccb81863 100644 --- a/bindings/matrix-sdk-ffi/src/api.udl +++ b/bindings/matrix-sdk-ffi/src/api.udl @@ -156,24 +156,21 @@ interface MediaSource { [Error] enum AuthenticationError { - "ClientMissing", - "Generic", + "ClientMissing", + "Generic", +}; + +interface HomeserverLoginDetails { + string url(); + string? authentication_issuer(); + boolean supports_password_login(); }; interface AuthenticationService { constructor(string base_path); [Throws=AuthenticationError] - string homeserver(); - - [Throws=AuthenticationError] - string? authentication_issuer(); - - [Throws=AuthenticationError] - boolean supports_password_login(); - - [Throws=AuthenticationError] - void use_server(string server_name); + HomeserverLoginDetails configure_homeserver(string server_name); [Throws=AuthenticationError] Client login(string username, string password); diff --git a/bindings/matrix-sdk-ffi/src/authentication_service.rs b/bindings/matrix-sdk-ffi/src/authentication_service.rs index 7ed148d82..da52f9fc1 100644 --- a/bindings/matrix-sdk-ffi/src/authentication_service.rs +++ b/bindings/matrix-sdk-ffi/src/authentication_service.rs @@ -23,42 +23,42 @@ impl From for AuthenticationError { } } +pub struct HomeserverLoginDetails { + url: String, + authentication_issuer: Option, + supports_password_login: bool, +} + +impl HomeserverLoginDetails { + /// The URL of the currently configured homeserver. + pub fn url(&self) -> String { + self.url.clone() + } + + /// The OIDC Provider that is trusted by the homeserver. `None` when + /// not configured. + pub fn authentication_issuer(&self) -> Option { + self.authentication_issuer.clone() + } + + /// Whether the current homeserver supports the password login flow. + pub fn supports_password_login(&self) -> bool { + self.supports_password_login + } +} + impl AuthenticationService { /// Creates a new service to authenticate a user with. pub fn new(base_path: String) -> Self { AuthenticationService { base_path, client: RwLock::new(None) } } - /// The currently configured homeserver. - pub fn homeserver(&self) -> Result { - self.client - .read() - .as_ref() - .ok_or(AuthenticationError::ClientMissing) - .map(|client| client.homeserver()) - } - - /// The OIDC Provider that is trusted by the homeserver. `None` when - /// not configured. - pub fn authentication_issuer(&self) -> Result, AuthenticationError> { - self.client - .read() - .as_ref() - .ok_or(AuthenticationError::ClientMissing) - .map(|client| client.authentication_issuer()) - } - - /// Whether the current homeserver supports the password login flow. - pub fn supports_password_login(&self) -> Result { - self.client - .read() - .as_ref() - .ok_or(AuthenticationError::ClientMissing) - .and_then(|client| client.supports_password_login().map_err(AuthenticationError::from)) - } - - /// Updates the server to authenticate with the specified homeserver. - pub fn use_server(&self, server_name: String) -> Result<(), AuthenticationError> { + /// Updates the service to authenticate with the homeserver for the + /// specified address. + pub fn configure_homeserver( + &self, + server_name: String, + ) -> Result, AuthenticationError> { // Construct a username as the builder currently requires one. let username = format!("@auth:{}", server_name); let client = Arc::new(ClientBuilder::new()) @@ -67,8 +67,10 @@ impl AuthenticationService { .build() .map_err(AuthenticationError::from)?; + let details = self.details_from_client(&client)?; + *self.client.write() = Some(client); - Ok(()) + Ok(Arc::new(details)) } /// Performs a password login using the current homeserver. @@ -97,4 +99,19 @@ impl AuthenticationService { None => Err(AuthenticationError::ClientMissing), } } + + fn details_from_client( + &self, + client: &Arc, + ) -> Result { + let homeserver = client.homeserver(); + let authentication_issuer = client.authentication_issuer(); + let supports_password_login = + client.supports_password_login().map_err(AuthenticationError::from)?; + Ok(HomeserverLoginDetails { + url: homeserver, + authentication_issuer, + supports_password_login, + }) + } }