Merge pull request #1759 from mozilla/session-code-token
Add ability to attach a session token from the OAuth code flow
This commit is contained in:
Коммит
ca6a6a90b7
|
@ -4,6 +4,13 @@
|
|||
|
||||
[Full Changelog](https://github.com/mozilla/application-services/compare/v0.38.2...master)
|
||||
|
||||
## FxA Client
|
||||
|
||||
### What's new
|
||||
|
||||
* New `getSessionToken` method on the FxA Client that returns the stored session_token from state.
|
||||
Also we now store the session_token into the state from the 'https://identity.mozilla.com/tokens/session' scope.
|
||||
|
||||
## Places
|
||||
|
||||
### What's fixed
|
||||
|
|
|
@ -240,6 +240,17 @@ class FirefoxAccount(handle: FxaHandle, persistCallback: PersistCallback?) : Aut
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to return a session token
|
||||
*
|
||||
* @throws FxaException Will send you an exception if there is no session token set
|
||||
*/
|
||||
fun getSessionToken(): String {
|
||||
return rustCallWithLock { e ->
|
||||
LibFxAFFI.INSTANCE.fxa_get_session_token(this.handle.get(), e)
|
||||
}.getAndConsumeRustString()
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be called when a request made with
|
||||
* an OAuth token failed with an authentication error.
|
||||
|
|
|
@ -50,6 +50,7 @@ internal interface LibFxAFFI : Library {
|
|||
|
||||
fun fxa_complete_oauth_flow(fxa: FxaHandle, code: String, state: String, e: RustError.ByReference)
|
||||
fun fxa_get_access_token(fxa: FxaHandle, scope: String, e: RustError.ByReference): RustBuffer.ByValue
|
||||
fun fxa_get_session_token(fxa: FxaHandle, e: RustError.ByReference): Pointer?
|
||||
fun fxa_clear_access_token_cache(fxa: FxaHandle, e: RustError.ByReference)
|
||||
|
||||
fun fxa_set_push_subscription(
|
||||
|
|
|
@ -272,6 +272,20 @@ pub extern "C" fn fxa_get_access_token(
|
|||
})
|
||||
}
|
||||
|
||||
/// Try to get a session token.
|
||||
///
|
||||
/// If the system can't find a suitable token it will return an error
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// A destructor [fxa_bytebuffer_free] is provided for releasing the memory for this
|
||||
/// pointer type.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn fxa_get_session_token(handle: u64, error: &mut ExternError) -> *mut c_char {
|
||||
log::debug!("fxa_get_session_token");
|
||||
ACCOUNTS.call_with_result_mut(error, handle, |fxa| fxa.get_session_token())
|
||||
}
|
||||
|
||||
/// This method should be called when a request made with
|
||||
/// an OAuth token failed with an authentication error.
|
||||
/// It clears the internal cache of OAuth access tokens,
|
||||
|
|
|
@ -29,6 +29,9 @@ pub enum ErrorKind {
|
|||
#[fail(display = "No stored refresh token")]
|
||||
NoRefreshToken,
|
||||
|
||||
#[fail(display = "No stored session token")]
|
||||
NoSessionToken,
|
||||
|
||||
#[fail(display = "Could not find a refresh token in the server response")]
|
||||
RefreshTokenNotPresent,
|
||||
|
||||
|
|
|
@ -610,6 +610,7 @@ pub struct DeviceResponseCommon {
|
|||
pub struct OAuthTokenResponse {
|
||||
pub keys_jwe: Option<String>,
|
||||
pub refresh_token: Option<String>,
|
||||
pub session_token: Option<String>,
|
||||
pub expires_in: u64,
|
||||
pub scope: String,
|
||||
pub access_token: String,
|
||||
|
|
|
@ -76,6 +76,14 @@ impl FirefoxAccount {
|
|||
Ok(token_info)
|
||||
}
|
||||
|
||||
/// Retrieve the current session token from state
|
||||
pub fn get_session_token(&mut self) -> Result<String> {
|
||||
match self.state.session_token {
|
||||
Some(ref session_token) => Ok(session_token.to_string()),
|
||||
None => Err(ErrorKind::NoSessionToken.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Initiate a pairing flow and return a URL that should be navigated to.
|
||||
///
|
||||
/// * `pairing_url` - A pairing URL obtained by scanning a QR code produced by
|
||||
|
@ -199,6 +207,13 @@ impl FirefoxAccount {
|
|||
self.state.scoped_keys.insert(scope, scoped_key);
|
||||
}
|
||||
}
|
||||
|
||||
// If the client requested a 'tokens/session' OAuth scope then as part of the code
|
||||
// exchange this will get a session_token in the response.
|
||||
if resp.session_token.is_some() {
|
||||
self.state.session_token = resp.session_token;
|
||||
}
|
||||
|
||||
// We are only interested in the refresh token at this time because we
|
||||
// don't want to return an over-scoped access token.
|
||||
// Let's be good citizens and destroy this access token.
|
||||
|
|
|
@ -200,6 +200,7 @@ mod tests {
|
|||
expires_in: 6_000_000,
|
||||
scope: "profile".to_owned(),
|
||||
access_token: "good_profile_token".to_owned(),
|
||||
session_token: None,
|
||||
}));
|
||||
// Then hooray it works!
|
||||
client
|
||||
|
|
Загрузка…
Ссылка в новой задаче