Skip to content

Commit db5a688

Browse files
committed
Merge branch 'master' into async-mode
2 parents ce5db46 + cd3e2e3 commit db5a688

File tree

2 files changed

+43
-4
lines changed

2 files changed

+43
-4
lines changed

RELEASE_NOTES.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ xxxx-yy-zz
77
any header.
88
* Users who use the default client shouldn't notice any changes.
99

10+
# v0.18.1
11+
2024-05-06
12+
* fixed bug when using oauth2 refresh tokens using client secret instead of PKCE:
13+
* See https://github.com/dropbox/dropbox-sdk-rust/issues/151 for details
14+
* New function Authorize::from_client_secret_refresh_token() should be used for any refresh tokens previously obtained using this flow
15+
* Thanks to Peerat Vichivanives for reporting and testing the fix
16+
1017
# v0.18.0
1118
2024-01-12
1219
* MSRV raised to 1.65.0

src/oauth2.rs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ enum AuthorizationState {
296296
},
297297
Refresh {
298298
refresh_token: String,
299+
client_secret: Option<String>,
299300
},
300301
AccessToken {
301302
client_secret: Option<String>,
@@ -373,14 +374,34 @@ impl Authorization {
373374
})
374375
}
375376

376-
/// Recreate the authorization from a refresh token.
377+
/// Recreate the authorization from a refresh token obtained using the [`Oauth2Type::PKCE`]
378+
/// flow.
377379
pub fn from_refresh_token(
378380
client_id: String,
379381
refresh_token: String,
380382
) -> Self {
381383
Self {
382384
client_id,
383-
state: AuthorizationState::Refresh { refresh_token },
385+
state: AuthorizationState::Refresh {
386+
refresh_token,
387+
client_secret: None,
388+
},
389+
}
390+
}
391+
392+
/// Recreate the authorization from a refresh token obtained using the
393+
/// [`Oauth2Type::AuthorizationCode`] flow. This requires the client secret as well.
394+
pub fn from_client_secret_refresh_token(
395+
client_id: String,
396+
client_secret: String,
397+
refresh_token: String,
398+
) -> Self {
399+
Self {
400+
client_id,
401+
state: AuthorizationState::Refresh {
402+
refresh_token,
403+
client_secret: Some(client_secret),
404+
},
384405
}
385406
}
386407

@@ -452,8 +473,11 @@ impl Authorization {
452473
auth_code = Some(code);
453474
redirect_uri = uri;
454475
}
455-
AuthorizationState::Refresh { refresh_token: refresh } => {
476+
AuthorizationState::Refresh { refresh_token: refresh, client_secret: secret } => {
456477
refresh_token = Some(refresh);
478+
if let Some(secret) = secret {
479+
client_secret = Some(secret);
480+
}
457481
}
458482
}
459483

@@ -470,6 +494,14 @@ impl Authorization {
470494

471495
params.append_pair("client_id", &self.client_id);
472496

497+
if let Some(client_secret) = client_secret.as_deref() {
498+
params.append_pair("client_secret", client_secret);
499+
}
500+
501+
if let Some(pkce) = &pkce_code {
502+
params.append_pair("code_verifier", pkce);
503+
}
504+
473505
if refresh_token.is_none() {
474506
if let Some(pkce) = pkce_code {
475507
params.append_pair("code_verifier", &pkce);
@@ -531,7 +563,7 @@ impl Authorization {
531563

532564
match refresh_token {
533565
Some(refresh) => {
534-
self.state = AuthorizationState::Refresh { refresh_token: refresh };
566+
self.state = AuthorizationState::Refresh { refresh_token: refresh, client_secret };
535567
}
536568
None if !matches!(self.state, AuthorizationState::Refresh {..}) => {
537569
self.state = AuthorizationState::AccessToken {

0 commit comments

Comments
 (0)