diff --git a/crates/matrix-sdk/src/client.rs b/crates/matrix-sdk/src/client.rs index 8d1e964eb..8db64ea86 100644 --- a/crates/matrix-sdk/src/client.rs +++ b/crates/matrix-sdk/src/client.rs @@ -55,6 +55,7 @@ use ruma::{ sync::sync_events, uiaa::{AuthData, UserIdentifier}, }, + session::sso_login_with_provider::v3 as sso_login_with_provider, unversioned::{discover_homeserver, get_supported_versions}, }, error::FromHttpResponseError, @@ -743,12 +744,23 @@ impl Client { /// * `redirect_url` - The URL that will receive a `loginToken` after a /// successful SSO login. /// + /// * `idp_id` - The optional ID of the identity provider to login with. + /// /// [`login_with_token`]: #method.login_with_token - pub async fn get_sso_login_url(&self, redirect_url: &str) -> Result { + pub async fn get_sso_login_url( + &self, + redirect_url: &str, + idp_id: Option<&str>, + ) -> Result { let homeserver = self.homeserver().await; - let request = sso_login::Request::new(redirect_url) - .try_into_http_request::>(homeserver.as_str(), SendAccessToken::None); + let request = if let Some(id) = idp_id { + sso_login_with_provider::Request::new(id, redirect_url) + .try_into_http_request::>(homeserver.as_str(), SendAccessToken::None) + } else { + sso_login::Request::new(redirect_url) + .try_into_http_request::>(homeserver.as_str(), SendAccessToken::None) + }; match request { Ok(req) => Ok(req.uri().to_string()), @@ -876,6 +888,8 @@ impl Client { /// associated with the device_id. Only necessary the first time you login /// with this device_id. It can be changed later. /// + /// * `idp_id` - The optional ID of the identity provider to login with. + /// /// # Example /// ```no_run /// # use matrix_sdk::Client; @@ -894,7 +908,8 @@ impl Client { /// None, /// None, /// None, - /// Some("My app") + /// Some("My app"), + /// None, /// ) /// .await /// .unwrap(); @@ -915,6 +930,7 @@ impl Client { server_response: Option<&str>, device_id: Option<&str>, initial_device_display_name: Option<&str>, + idp_id: Option<&str>, ) -> Result where C: Future>, @@ -1007,7 +1023,7 @@ impl Client { tokio::spawn(server); - let sso_url = self.get_sso_login_url(redirect_url.as_str()).await?; + let sso_url = self.get_sso_login_url(redirect_url.as_str(), idp_id).await?; match use_sso_login_url(sso_url).await { Ok(t) => t, @@ -1067,7 +1083,7 @@ impl Client { /// # let login_token = "token"; /// # block_on(async { /// let client = Client::new(homeserver).await.unwrap(); - /// let sso_url = client.get_sso_login_url(redirect_url); + /// let sso_url = client.get_sso_login_url(redirect_url, None); /// /// // Let the user authenticate at the SSO URL /// // Receive the loginToken param at redirect_url @@ -2499,7 +2515,10 @@ pub(crate) mod test { let homeserver = Url::from_str(&mockito::server_url()).unwrap(); let client = Client::new(homeserver).await.unwrap(); - + let idp = crate::client::get_login_types::IdentityProvider::new( + "some-id".to_string(), + "idp-name".to_string(), + ); client .login_with_sso( |sso_url| async move { @@ -2519,6 +2538,7 @@ pub(crate) mod test { None, None, None, + Some(&idp.id), ) .await .unwrap(); @@ -2547,7 +2567,7 @@ pub(crate) mod test { .any(|flow| matches!(flow, LoginType::Sso(_))); assert!(can_sso); - let sso_url = client.get_sso_login_url("http://127.0.0.1:3030").await; + let sso_url = client.get_sso_login_url("http://127.0.0.1:3030", None).await; assert!(sso_url.is_ok()); let _m = mock("POST", "/_matrix/client/r0/login")