Merge pull request #196 from williamho/default-expiry-for-id-token

Set default expires_at if only ID token is returned
This commit is contained in:
Lewin Bormann
2023-02-27 10:17:07 +01:00
committed by GitHub

View File

@@ -1,7 +1,7 @@
use crate::error::{AuthErrorOr, Error};
use time::OffsetDateTime;
use serde::{Deserialize, Serialize};
use time::OffsetDateTime;
/// Represents a token returned by oauth2 servers. All tokens are Bearer tokens. Other types of
/// tokens are not supported.
@@ -12,7 +12,6 @@ pub struct AccessToken {
}
impl AccessToken {
/// A string representation of the access token.
pub fn token(&self) -> Option<&str> {
self.access_token.as_deref()
@@ -30,7 +29,9 @@ impl AccessToken {
pub fn is_expired(&self) -> bool {
// Consider the token expired if it's within 1 minute of it's expiration time.
self.expires_at
.map(|expiration_time| expiration_time - time::Duration::minutes(1) <= OffsetDateTime::now_utc())
.map(|expiration_time| {
expiration_time - time::Duration::minutes(1) <= OffsetDateTime::now_utc()
})
.unwrap_or(false)
}
}
@@ -106,8 +107,19 @@ impl TokenInfo {
_ => (),
}
let expires_at = expires_in
.map(|seconds_from_now| OffsetDateTime::now_utc() + time::Duration::seconds(seconds_from_now));
let expires_at = match expires_in {
Some(seconds_from_now) => {
Some(OffsetDateTime::now_utc() + time::Duration::seconds(seconds_from_now))
}
None if id_token.is_some() && access_token.is_none() => {
// If the response contains only an ID token, an expiration date may not be
// returned. According to the docs, the tokens are always valid for 1 hour.
//
// https://cloud.google.com/iam/docs/create-short-lived-credentials-direct#sa-credentials-oidc
Some(OffsetDateTime::now_utc() + time::Duration::HOUR)
}
None => None,
};
Ok(TokenInfo {
id_token,
@@ -120,7 +132,9 @@ impl TokenInfo {
/// Returns true if we are expired.
pub fn is_expired(&self) -> bool {
self.expires_at
.map(|expiration_time| expiration_time - time::Duration::minutes(1) <= OffsetDateTime::now_utc())
.map(|expiration_time| {
expiration_time - time::Duration::minutes(1) <= OffsetDateTime::now_utc()
})
.unwrap_or(false)
}
}
@@ -183,4 +197,27 @@ pub mod tests {
),
}
}
#[test]
fn default_expiry_for_id_token_only() {
// If only an ID token is present, set a default expiration date
let json = r#"{"id_token": "id"}"#;
let token = TokenInfo::from_json(json.as_bytes()).unwrap();
assert_eq!(token.id_token, Some("id".to_owned()));
let expiry = token.expires_at.unwrap();
assert!(expiry <= time::OffsetDateTime::now_utc() + time::Duration::HOUR);
}
#[test]
fn no_default_expiry_for_access_token() {
// Don't set a default expiration date if an access token is returned
let json = r#"{"access_token": "access", "id_token": "id"}"#;
let token = TokenInfo::from_json(json.as_bytes()).unwrap();
assert_eq!(token.access_token, Some("access".to_owned()));
assert_eq!(token.id_token, Some("id".to_owned()));
assert_eq!(token.expires_at, None);
}
}