Merge pull request #166 from bjornwein/master

Add ID token support
This commit is contained in:
Lewin Bormann
2021-12-26 19:55:47 +01:00
committed by GitHub
3 changed files with 29 additions and 6 deletions

View File

@@ -60,7 +60,9 @@ where
where
T: AsRef<str>,
{
self.find_token(scopes, /* force_refresh = */ false).await
self.find_token_info(scopes, /* force_refresh = */ false)
.await
.map(|info| info.into())
}
/// Return a token for the provided scopes, but don't reuse cached tokens. Instead,
@@ -72,15 +74,27 @@ where
where
T: AsRef<str>,
{
self.find_token(scopes, /* force_refresh = */ true).await
self.find_token_info(scopes, /* force_refresh = */ true)
.await
.map(|info| info.into())
}
/// Return the current ID token for the provided scopes, if any
pub async fn id_token<'a, T>(&'a self, scopes: &'a [T]) -> Result<Option<String>, Error>
where
T: AsRef<str>,
{
self.find_token_info(scopes, /* force_refresh = */ false)
.await
.map(|info| info.id_token)
}
/// Return a cached token or fetch a new one from the server.
async fn find_token<'a, T>(
async fn find_token_info<'a, T>(
&'a self,
scopes: &'a [T],
force_refresh: bool,
) -> Result<AccessToken, Error>
) -> Result<TokenInfo, Error>
where
T: AsRef<str>,
{
@@ -116,7 +130,7 @@ where
.storage
.set(hashed_scopes, token_info.clone())
.await?;
Ok(token_info.into())
Ok(token_info)
}
_ => {
// no token in the cache or the token returned can't be refreshed.
@@ -129,7 +143,7 @@ where
.storage
.set(hashed_scopes, token_info.clone())
.await?;
Ok(token_info.into())
Ok(token_info)
}
}
}

View File

@@ -452,6 +452,7 @@ mod tests {
access_token: access_token.to_owned(),
refresh_token: None,
expires_at: None,
id_token: None,
};
let scope_set = ScopeSet::from(&["myscope"]);
let tempdir = tempfile::tempdir().unwrap();

View File

@@ -63,6 +63,11 @@ pub struct TokenInfo {
pub refresh_token: Option<String>,
/// The time when the token expires.
pub expires_at: Option<DateTime<Utc>>,
/// Optionally included by the OAuth2 server and may contain information to verify the identity
/// used to obtain the access token.
/// Specifically Google API:s include this if the additional scopes "email" and/or "profile"
/// are used. In that case the content is an JWT token.
pub id_token: Option<String>,
}
impl TokenInfo {
@@ -73,6 +78,7 @@ impl TokenInfo {
refresh_token: Option<String>,
token_type: String,
expires_in: Option<i64>,
id_token: Option<String>,
}
// Serialize first to a `serde_json::Value` then to `AuthErrorOr<RawToken>` to work around this bug in
@@ -83,6 +89,7 @@ impl TokenInfo {
refresh_token,
token_type,
expires_in,
id_token,
} = <AuthErrorOr<RawToken>>::deserialize(raw_token)?.into_result()?;
if token_type.to_lowercase().as_str() != "bearer" {
@@ -104,6 +111,7 @@ impl TokenInfo {
access_token,
refresh_token,
expires_at,
id_token,
})
}