@@ -2561,10 +2561,8 @@ impl AuthorizationManager {
25612561 . exchange_refresh_token ( & refresh_token_value)
25622562 // RFC 8707: the resource indicator is required on token requests, including refreshes
25632563 . add_extra_param ( "resource" , self . oauth_resource ( ) . await ) ;
2564- let mut refresh_scopes = stored_credentials. granted_scopes . clone ( ) ;
2565- self . add_offline_access_if_supported ( & mut refresh_scopes) ;
2566- let requested_scopes = refresh_scopes. clone ( ) ;
2567- for scope in refresh_scopes {
2564+ let requested_scopes = stored_credentials. granted_scopes . clone ( ) ;
2565+ for scope in requested_scopes. iter ( ) . cloned ( ) {
25682566 refresh_request = refresh_request. add_scope ( Scope :: new ( scope) ) ;
25692567 }
25702568 let mut token_result = match refresh_request
@@ -10082,7 +10080,7 @@ mod tests {
1008210080 }
1008310081
1008410082 #[ tokio:: test]
10085- async fn refresh_token_adds_offline_access_when_as_supports_it ( ) {
10083+ async fn refresh_token_does_not_add_ungranted_offline_access ( ) {
1008610084 let ( base_url, captured) = start_token_server ( ) . await ;
1008710085
1008810086 let mut manager = manager_with_metadata ( Some ( AuthorizationMetadata {
@@ -10108,6 +10106,45 @@ mod tests {
1010810106
1010910107 manager. refresh_token ( ) . await . unwrap ( ) ;
1011010108
10109+ let body = captured. lock ( ) . unwrap ( ) . take ( ) . unwrap ( ) ;
10110+ let params: std:: collections:: HashMap < _ , _ > = url:: form_urlencoded:: parse ( body. as_bytes ( ) )
10111+ . into_owned ( )
10112+ . collect ( ) ;
10113+ let scope = params
10114+ . get ( "scope" )
10115+ . expect ( "scope should be present in refresh request" ) ;
10116+ let mut scope_parts: Vec < & str > = scope. split_whitespace ( ) . collect ( ) ;
10117+ scope_parts. sort_unstable ( ) ;
10118+ assert_eq ! ( scope_parts, vec![ "read" ] ) ;
10119+ }
10120+
10121+ #[ tokio:: test]
10122+ async fn refresh_token_keeps_offline_access_when_it_was_granted ( ) {
10123+ let ( base_url, captured) = start_token_server ( ) . await ;
10124+
10125+ let mut manager = manager_with_metadata ( Some ( AuthorizationMetadata {
10126+ authorization_endpoint : format ! ( "{}/authorize" , base_url) ,
10127+ token_endpoint : format ! ( "{}/token" , base_url) ,
10128+ scopes_supported : Some ( vec ! [ "read" . to_string( ) , "offline_access" . to_string( ) ] ) ,
10129+ ..Default :: default ( )
10130+ } ) )
10131+ . await ;
10132+ manager. configure_client ( test_client_config ( ) ) . unwrap ( ) ;
10133+
10134+ let stored = StoredCredentials {
10135+ client_id : "my-client" . to_string ( ) ,
10136+ token_response : Some ( make_token_response_with_refresh (
10137+ "old-token" ,
10138+ "my-refresh-token" ,
10139+ ) ) ,
10140+ granted_scopes : vec ! [ "read" . to_string( ) , "offline_access" . to_string( ) ] ,
10141+ token_received_at : Some ( AuthorizationManager :: now_epoch_secs ( ) ) ,
10142+ issuer : None ,
10143+ } ;
10144+ manager. credential_store . save ( stored) . await . unwrap ( ) ;
10145+
10146+ manager. refresh_token ( ) . await . unwrap ( ) ;
10147+
1011110148 let body = captured. lock ( ) . unwrap ( ) . take ( ) . unwrap ( ) ;
1011210149 let params: std:: collections:: HashMap < _ , _ > = url:: form_urlencoded:: parse ( body. as_bytes ( ) )
1011310150 . into_owned ( )
0 commit comments