@@ -7,7 +7,7 @@ use std::{
77 sync:: { Arc , RwLock } ,
88} ;
99
10- use futures_util:: future:: join;
10+ use futures_util:: { future:: join, FutureExt } ;
1111use matrix_sdk:: {
1212 oidc:: {
1313 types:: {
@@ -16,9 +16,9 @@ use matrix_sdk::{
1616 iana:: oauth:: OAuthClientAuthenticationMethod ,
1717 oidc:: ApplicationType ,
1818 registration:: { ClientMetadata , Localized , VerifiedClientMetadata } ,
19- requests:: GrantType ,
19+ requests:: { GrantType , Prompt } ,
2020 } ,
21- AuthorizationCode , AuthorizationResponse , Oidc , OidcError , RegisteredClientData ,
21+ AuthorizationResponse , Oidc , OidcError , RegisteredClientData ,
2222 } ,
2323 AuthSession ,
2424} ;
@@ -122,7 +122,7 @@ pub struct OidcConfiguration {
122122/// The data needed to restore an OpenID Connect session.
123123#[ derive( Debug , Serialize , Deserialize ) ]
124124struct OidcRegistrations {
125- /// The URL of the OIDC Provider .
125+ /// The path of the file where the registrations are stored .
126126 file_path : PathBuf ,
127127 /// Pre-configured registrations for use with issuers that don't support
128128 /// dynamic client registration.
@@ -163,10 +163,10 @@ impl OidcRegistrations {
163163
164164 /// Returns the client ID registered for a particular issuer or None if a
165165 /// registration hasn't been made.
166- fn client_id ( & self , issuer : String ) -> Option < String > {
166+ fn client_id ( & self , issuer : & str ) -> Option < String > {
167167 let mut registrations = self . dynamic_registrations ( ) ;
168168 registrations. extend ( self . static_registrations . clone ( ) ) ;
169- registrations. get ( & issuer) . cloned ( )
169+ registrations. get ( issuer) . cloned ( )
170170 }
171171
172172 /// Stores a new client ID registration for a particular issuer. If a client
@@ -185,8 +185,7 @@ impl OidcRegistrations {
185185/// The data required to authenticate against an OIDC server.
186186#[ derive( uniffi:: Object ) ]
187187pub struct OidcAuthenticationData {
188- /// The underlying URL for authentication. Additional parameters may be
189- /// needed. Call `login_url()` to get the URL to be loaded in a web view.
188+ /// The underlying URL for authentication.
190189 url : Url ,
191190 /// A unique identifier for the request, used to ensure the response
192191 /// originated from the authentication issuer.
@@ -197,9 +196,7 @@ pub struct OidcAuthenticationData {
197196impl OidcAuthenticationData {
198197 /// The login URL to use for authentication.
199198 pub fn login_url ( & self ) -> String {
200- let mut prompt_url = self . url . clone ( ) ;
201- prompt_url. query_pairs_mut ( ) . append_pair ( "prompt" , "consent" ) ;
202- prompt_url. to_string ( )
199+ self . url . to_string ( )
203200 }
204201}
205202
@@ -346,7 +343,7 @@ impl AuthenticationService {
346343 return Err ( AuthenticationError :: ClientMissing ) ;
347344 } ;
348345
349- let Some ( authentication_server) = client. authentication_server ( ) else {
346+ let Some ( authentication_server) = client. discovered_authentication_server ( ) else {
350347 return Err ( AuthenticationError :: OidcNotSupported ) ;
351348 } ;
352349
@@ -362,7 +359,20 @@ impl AuthenticationService {
362359 RUNTIME . block_on ( async {
363360 self . configure_oidc ( & oidc, authentication_server, oidc_configuration) . await ?;
364361
365- let data = oidc. login ( redirect_url, None ) ?. build ( ) . await ?;
362+ let mut data_builder = oidc. login ( redirect_url, None ) ?;
363+
364+ if let Ok ( provider_metadata) = oidc. provider_metadata ( ) . await {
365+ if provider_metadata
366+ . prompt_values_supported
367+ . as_ref ( )
368+ . map ( |p| p. contains ( & Prompt :: Consent ) )
369+ . unwrap_or ( false )
370+ {
371+ data_builder = data_builder. prompt ( vec ! [ Prompt :: Consent ] ) ;
372+ }
373+ }
374+
375+ let data = data_builder. build ( ) . await ?;
366376
367377 Ok ( Arc :: new ( OidcAuthenticationData { url : data. url , state : data. state } ) )
368378 } )
@@ -404,11 +414,7 @@ impl AuthenticationService {
404414 } ;
405415
406416 RUNTIME . block_on ( async move {
407- oidc. finish_authorization ( AuthorizationCode {
408- code : code. code ,
409- state : code. state . to_string ( ) ,
410- } )
411- . await ?;
417+ oidc. finish_authorization ( code) . await ?;
412418
413419 oidc. finish_login ( )
414420 . await
@@ -443,7 +449,7 @@ impl AuthenticationService {
443449 let login_details = join ( client. async_homeserver ( ) , client. supports_password_login ( ) ) . await ;
444450
445451 let url = login_details. 0 ;
446- let supports_oidc_login = client. authentication_server ( ) . is_some ( ) ;
452+ let supports_oidc_login = client. discovered_authentication_server ( ) . is_some ( ) ;
447453 let supports_password_login = login_details. 1 . ok ( ) . unwrap_or ( false ) ;
448454
449455 Ok ( HomeserverLoginDetails { url, supports_oidc_login, supports_password_login } )
@@ -536,16 +542,19 @@ impl AuthenticationService {
536542 . ok ( ) else {
537543 return false ;
538544 } ;
539- let Some ( client_id) = registrations. client_id ( issuer. to_owned ( ) ) else {
545+ let Some ( client_id) = registrations. client_id ( issuer) else {
540546 return false ;
541547 } ;
542548
543549 let client_data = RegisteredClientData {
544- credentials : ClientCredentials :: None { client_id : client_id . clone ( ) } ,
550+ credentials : ClientCredentials :: None { client_id } ,
545551 metadata : oidc_metadata,
546552 } ;
547553
548- let authentication_server = AuthenticationServerInfo :: new ( issuer. to_owned ( ) , None ) ;
554+ let authentication_server = AuthenticationServerInfo :: new (
555+ issuer. to_owned ( ) ,
556+ oidc. account_management_url ( ) . unwrap_or ( None ) . map ( |url| url. to_string ( ) ) ,
557+ ) ;
549558 oidc. restore_registered_client ( authentication_server, client_data) . await ;
550559
551560 true
0 commit comments