From 2128772d88dcabe89451029390de6ebc4b91432b Mon Sep 17 00:00:00 2001 From: Sarah Bird Date: Fri, 11 Mar 2022 19:39:11 -0600 Subject: [PATCH] Replace chrono with time --- Cargo.toml | 12 ++++++------ src/authenticator_delegate.rs | 15 ++++++++------- src/service_account.rs | 3 ++- src/types.rs | 14 +++++++------- tests/tests.rs | 4 ++-- 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b7663f4..e5ffae5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,24 +31,24 @@ default = ["hyper-rustls", "service_account"] service_account = ["rustls"] [dependencies] +anyhow = "1.0.38" +async-trait = "^0.1" base64 = "0.13.0" -chrono = { version = "0.4", features = ["serde"] } +futures = "0.3" http = "0.2" hyper = { version = "0.14", features = ["client", "server", "tcp", "http2"] } hyper-rustls = { version = "0.22.1", optional = true } hyper-tls = { version = "0.5.0", optional = true } +itertools = "0.10.0" log = "0.4" +percent-encoding = "2" rustls = { version = "0.19", optional = true } seahash = "4" serde = {version = "1.0", features = ["derive"]} serde_json = "1.0" +time = { version = "0.3.7", features = ["local-offset", "serde"] } tokio = { version = "1.0", features = ["fs", "macros", "io-std", "io-util", "time", "sync", "rt"] } url = "2" -percent-encoding = "2" -futures = "0.3" -async-trait = "^0.1" -anyhow = "1.0.38" -itertools = "0.10.0" [dev-dependencies] httptest = "0.14" diff --git a/src/authenticator_delegate.rs b/src/authenticator_delegate.rs index 6308bd5..58436ba 100644 --- a/src/authenticator_delegate.rs +++ b/src/authenticator_delegate.rs @@ -4,8 +4,8 @@ use crate::error::{AuthErrorOr, Error}; use std::pin::Pin; use std::time::Duration; -use chrono::{DateTime, Local, Utc}; use std::future::Future; +use time::{OffsetDateTime, UtcOffset}; /// Contains state of pending authentication requests #[derive(Clone, Debug, PartialEq)] @@ -18,7 +18,7 @@ pub struct DeviceAuthResponse { pub verification_uri: String, /// The `user_code` expires at the given time /// It's the time the user has left to authenticate your application - pub expires_at: DateTime, + pub expires_at: OffsetDateTime, /// The interval in which we may poll for a status change /// The server responds with errors of we poll too fast. pub interval: Duration, @@ -61,7 +61,7 @@ impl<'de> serde::Deserialize<'de> for DeviceAuthResponse { let verification_uri = verification_uri.or(verification_url).ok_or_else(|| { serde::de::Error::custom("neither verification_uri nor verification_url specified") })?; - let expires_at = Utc::now() + chrono::Duration::seconds(expires_in); + let expires_at = OffsetDateTime::now_utc() + time::Duration::seconds(expires_in); let interval = Duration::from_secs(interval.unwrap_or(5)); Ok(DeviceAuthResponse { device_code, @@ -94,10 +94,11 @@ async fn present_user_code(device_auth_resp: &DeviceAuthResponse) { device_auth_resp.user_code, device_auth_resp.verification_uri ); println!("Do not close this application until you either denied or granted access."); - println!( - "You have time until {}.", - device_auth_resp.expires_at.with_timezone(&Local) - ); + let printable_time = match UtcOffset::current_local_offset() { + Ok(offset) => device_auth_resp.expires_at.to_offset(offset), + Err(_) => device_auth_resp.expires_at, // Fallback to printing in UTC + }; + println!("You have time until {}.", printable_time); } /// InstalledFlowDelegate methods are called when an installed flow needs to ask diff --git a/src/service_account.rs b/src/service_account.rs index 3d78e76..2ebe315 100644 --- a/src/service_account.rs +++ b/src/service_account.rs @@ -26,6 +26,7 @@ use rustls::{ PrivateKey, }; use serde::{Deserialize, Serialize}; +use time::OffsetDateTime; use url::form_urlencoded; const GRANT_TYPE: &str = "urn:ietf:params:oauth:grant-type:jwt-bearer"; @@ -105,7 +106,7 @@ impl<'a> Claims<'a> { where T: AsRef, { - let iat = chrono::Utc::now().timestamp(); + let iat = OffsetDateTime::now_utc().unix_timestamp(); let expiry = iat + 3600 - 5; // Max validity is 1h. let scope = crate::helper::join(scopes, " "); diff --git a/src/types.rs b/src/types.rs index c4fe272..a62d8f4 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,6 +1,6 @@ use crate::error::{AuthErrorOr, Error}; -use chrono::{DateTime, Utc}; +use time::OffsetDateTime; use serde::{Deserialize, Serialize}; /// Represents an access token returned by oauth2 servers. All access tokens are @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)] pub struct AccessToken { value: String, - expires_at: Option>, + expires_at: Option, } impl AccessToken { @@ -18,7 +18,7 @@ impl AccessToken { } /// The time the access token will expire, if any. - pub fn expiration_time(&self) -> Option> { + pub fn expiration_time(&self) -> Option { self.expires_at } @@ -30,7 +30,7 @@ impl AccessToken { // Consider the token expired if it's within 1 minute of it's expiration // time. self.expires_at - .map(|expiration_time| expiration_time - chrono::Duration::minutes(1) <= Utc::now()) + .map(|expiration_time| expiration_time - time::Duration::minutes(1) <= OffsetDateTime::now_utc()) .unwrap_or(false) } } @@ -62,7 +62,7 @@ pub struct TokenInfo { /// used to refresh an expired access_token. pub refresh_token: Option, /// The time when the token expires. - pub expires_at: Option>, + pub expires_at: Option, /// 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" @@ -105,7 +105,7 @@ impl TokenInfo { } let expires_at = expires_in - .map(|seconds_from_now| Utc::now() + chrono::Duration::seconds(seconds_from_now)); + .map(|seconds_from_now| OffsetDateTime::now_utc() + time::Duration::seconds(seconds_from_now)); Ok(TokenInfo { access_token, @@ -118,7 +118,7 @@ impl TokenInfo { /// Returns true if we are expired. pub fn is_expired(&self) -> bool { self.expires_at - .map(|expiration_time| expiration_time - chrono::Duration::minutes(1) <= Utc::now()) + .map(|expiration_time| expiration_time - time::Duration::minutes(1) <= OffsetDateTime::now_utc()) .unwrap_or(false) } } diff --git a/tests/tests.rs b/tests/tests.rs index 846e51e..13b97a3 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -334,7 +334,7 @@ async fn create_service_account_auth(server: &Server) -> DefaultAuthenticator { #[tokio::test] async fn test_service_account_success() { - use chrono::Utc; + use time::OffsetDateTime; let _ = env_logger::try_init(); let server = Server::run(); let auth = create_service_account_auth(&server).await; @@ -352,7 +352,7 @@ async fn test_service_account_success() { .await .expect("token failed"); assert!(tok.as_str().contains("ya29.c.ElouBywiys0Ly")); - assert!(Utc::now() + chrono::Duration::seconds(3600) >= tok.expiration_time().unwrap()); + assert!(OffsetDateTime::now_utc() + time::Duration::seconds(3600) >= tok.expiration_time().unwrap()); } #[tokio::test]