This is an automated email from the ASF dual-hosted git repository.

tustvold pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/master by this push:
     new f82b704c5 object-store: fix handling of AWS profile credentials 
without expiry (#3766)
f82b704c5 is described below

commit f82b704c5c38090a6ecd052b5c25bdfee7010130
Author: Willem D'Haeseleer <[email protected]>
AuthorDate: Mon Feb 27 09:21:25 2023 -0800

    object-store: fix handling of AWS profile credentials without expiry (#3766)
    
    * fix aws profile
    
    * fix unused import
    
    * support None as expiry
    
    * fix clippy
    
    * fix fmt
    
    * revert fmt whitespace fix
---
 object_store/src/aws/credential.rs   | 18 ++++++------------
 object_store/src/azure/credential.rs | 16 +++++++++-------
 object_store/src/client/token.rs     | 22 ++++++++++++++--------
 object_store/src/gcp/credential.rs   |  6 +++---
 4 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/object_store/src/aws/credential.rs 
b/object_store/src/aws/credential.rs
index cba55845e..e2332d0fa 100644
--- a/object_store/src/aws/credential.rs
+++ b/object_store/src/aws/credential.rs
@@ -438,7 +438,7 @@ async fn instance_creds(
     let ttl = (creds.expiration - now).to_std().unwrap_or_default();
     Ok(TemporaryToken {
         token: Arc::new(creds.into()),
-        expiry: Instant::now() + ttl,
+        expiry: Some(Instant::now() + ttl),
     })
 }
 
@@ -509,7 +509,7 @@ async fn web_identity(
 
     Ok(TemporaryToken {
         token: Arc::new(creds.into()),
-        expiry: Instant::now() + ttl,
+        expiry: Some(Instant::now() + ttl),
     })
 }
 
@@ -553,17 +553,11 @@ mod profile {
                             store: "S3",
                             source: Box::new(source),
                         })?;
-
                 let t_now = SystemTime::now();
-                let expiry = match c.expiry().and_then(|e| 
e.duration_since(t_now).ok()) {
-                    Some(ttl) => Instant::now() + ttl,
-                    None => {
-                        return Err(crate::Error::Generic {
-                            store: "S3",
-                            source: "Invalid expiry".into(),
-                        })
-                    }
-                };
+                let expiry = c
+                    .expiry()
+                    .and_then(|e| e.duration_since(t_now).ok())
+                    .map(|ttl| Instant::now() + ttl);
 
                 Ok(TemporaryToken {
                     token: Arc::new(AwsCredential {
diff --git a/object_store/src/azure/credential.rs 
b/object_store/src/azure/credential.rs
index 9460c2def..9e072229f 100644
--- a/object_store/src/azure/credential.rs
+++ b/object_store/src/azure/credential.rs
@@ -360,7 +360,7 @@ impl TokenCredential for ClientSecretOAuthProvider {
 
         let token = TemporaryToken {
             token: response.access_token,
-            expiry: Instant::now() + Duration::from_secs(response.expires_in),
+            expiry: Some(Instant::now() + 
Duration::from_secs(response.expires_in)),
         };
 
         Ok(token)
@@ -467,7 +467,7 @@ impl TokenCredential for ImdsManagedIdentityOAuthProvider {
 
         let token = TemporaryToken {
             token: response.access_token,
-            expiry: Instant::now() + Duration::from_secs(response.expires_in),
+            expiry: Some(Instant::now() + 
Duration::from_secs(response.expires_in)),
         };
 
         Ok(token)
@@ -541,7 +541,7 @@ impl TokenCredential for WorkloadIdentityOAuthProvider {
 
         let token = TemporaryToken {
             token: response.access_token,
-            expiry: Instant::now() + Duration::from_secs(response.expires_in),
+            expiry: Some(Instant::now() + 
Duration::from_secs(response.expires_in)),
         };
 
         Ok(token)
@@ -640,10 +640,12 @@ impl TokenCredential for AzureCliCredential {
                     - chrono::Local::now().naive_local();
                 Ok(TemporaryToken {
                     token: token_response.access_token,
-                    expiry: Instant::now()
-                        + duration.to_std().map_err(|_| Error::AzureCli {
-                            message: "az returned invalid 
lifetime".to_string(),
-                        })?,
+                    expiry: Some(
+                        Instant::now()
+                            + duration.to_std().map_err(|_| Error::AzureCli {
+                                message: "az returned invalid 
lifetime".to_string(),
+                            })?,
+                    ),
                 })
             }
             Ok(az_output) => {
diff --git a/object_store/src/client/token.rs b/object_store/src/client/token.rs
index 2ff28616e..7e48d351d 100644
--- a/object_store/src/client/token.rs
+++ b/object_store/src/client/token.rs
@@ -25,7 +25,8 @@ pub struct TemporaryToken<T> {
     /// The temporary credential
     pub token: T,
     /// The instant at which this credential is no longer valid
-    pub expiry: Instant,
+    /// None means the credential does not expire
+    pub expiry: Option<Instant>,
 }
 
 /// Provides [`TokenCache::get_or_insert_with`] which can be used to cache a
@@ -53,13 +54,18 @@ impl<T: Clone + Send> TokenCache<T> {
         let mut locked = self.cache.lock().await;
 
         if let Some(cached) = locked.as_ref() {
-            let delta = cached
-                .expiry
-                .checked_duration_since(now)
-                .unwrap_or_default();
-
-            if delta.as_secs() > 300 {
-                return Ok(cached.token.clone());
+            match cached.expiry {
+                Some(ttl)
+                    if ttl
+                        .checked_duration_since(now)
+                        .unwrap_or_default()
+                        .as_secs()
+                        > 300 =>
+                {
+                    return Ok(cached.token.clone());
+                }
+                None => return Ok(cached.token.clone()),
+                _ => (),
             }
         }
 
diff --git a/object_store/src/gcp/credential.rs 
b/object_store/src/gcp/credential.rs
index c12b37cdd..853e4ce83 100644
--- a/object_store/src/gcp/credential.rs
+++ b/object_store/src/gcp/credential.rs
@@ -220,7 +220,7 @@ impl TokenProvider for OAuthProvider {
 
         let token = TemporaryToken {
             token: response.access_token,
-            expiry: Instant::now() + Duration::from_secs(response.expires_in),
+            expiry: Some(Instant::now() + 
Duration::from_secs(response.expires_in)),
         };
 
         Ok(token)
@@ -393,7 +393,7 @@ impl TokenProvider for InstanceCredentialProvider {
                 .await?;
         let token = TemporaryToken {
             token: response.access_token,
-            expiry: Instant::now() + Duration::from_secs(response.expires_in),
+            expiry: Some(Instant::now() + 
Duration::from_secs(response.expires_in)),
         };
         Ok(token)
     }
@@ -467,7 +467,7 @@ impl TokenProvider for ApplicationDefaultCredentials {
             .context(TokenResponseBodySnafu)?;
         let token = TemporaryToken {
             token: response.access_token,
-            expiry: Instant::now() + Duration::from_secs(response.expires_in),
+            expiry: Some(Instant::now() + 
Duration::from_secs(response.expires_in)),
         };
         Ok(token)
     }

Reply via email to