You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@opendal.apache.org by xu...@apache.org on 2024/01/17 04:57:08 UTC

(incubator-opendal) branch fix-anonymous created (now 1788d5938a)

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

xuanwo pushed a change to branch fix-anonymous
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git


      at 1788d5938a feat(services/s3): Return error if credential is empty after loaded

This branch includes the following new commits:

     new 1788d5938a feat(services/s3): Return error if credential is empty after loaded

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(incubator-opendal) 01/01: feat(services/s3): Return error if credential is empty after loaded

Posted by xu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xuanwo pushed a commit to branch fix-anonymous
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git

commit 1788d5938ad6e32e73b7c3d8f5fe22441c8a85f0
Author: Xuanwo <gi...@xuanwo.io>
AuthorDate: Wed Jan 17 12:56:15 2024 +0800

    feat(services/s3): Return error if credential is empty after loaded
    
    Signed-off-by: Xuanwo <gi...@xuanwo.io>
---
 core/src/services/s3/backend.rs |  2 ++
 core/src/services/s3/core.rs    | 34 +++++++++++++++++++++++++---------
 2 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/core/src/services/s3/backend.rs b/core/src/services/s3/backend.rs
index 35d1eb2b4c..bb7b3949c3 100644
--- a/core/src/services/s3/backend.rs
+++ b/core/src/services/s3/backend.rs
@@ -19,6 +19,7 @@ use std::collections::HashMap;
 use std::fmt::Debug;
 use std::fmt::Formatter;
 use std::fmt::Write;
+use std::sync::atomic::AtomicBool;
 use std::sync::Arc;
 
 use async_trait::async_trait;
@@ -966,6 +967,7 @@ impl Builder for S3Builder {
                 disable_stat_with_override: self.config.disable_stat_with_override,
                 signer,
                 loader,
+                credential_loaded: AtomicBool::new(false),
                 client,
                 batch_max_operations,
             }),
diff --git a/core/src/services/s3/core.rs b/core/src/services/s3/core.rs
index 35342d1479..7a271bec8e 100644
--- a/core/src/services/s3/core.rs
+++ b/core/src/services/s3/core.rs
@@ -19,6 +19,8 @@ use std::fmt;
 use std::fmt::Debug;
 use std::fmt::Formatter;
 use std::fmt::Write;
+use std::sync::atomic;
+use std::sync::atomic::AtomicBool;
 use std::time::Duration;
 
 use bytes::Bytes;
@@ -83,6 +85,7 @@ pub struct S3Core {
 
     pub signer: AwsV4Signer,
     pub loader: Box<dyn AwsCredentialLoad>,
+    pub credential_loaded: AtomicBool,
     pub client: HttpClient,
     pub batch_max_operations: usize,
 }
@@ -107,18 +110,31 @@ impl S3Core {
             .map_err(new_request_credential_error)?;
 
         if let Some(cred) = cred {
-            Ok(Some(cred))
-        } else if self.allow_anonymous {
-            // If allow_anonymous has been set, we will not sign the request.
-            Ok(None)
-        } else {
-            // Mark this error as temporary since it could be caused by AWS STS.
-            Err(Error::new(
+            // Update credential_loaded to true if we have load credential successfully.
+            self.credential_loaded
+                .store(true, atomic::Ordering::Relaxed);
+            return Ok(Some(cred));
+        }
+
+        // If we have load credential before but failed to load this time, we should
+        // return error instead.
+        if self.credential_loaded.load(atomic::Ordering::Relaxed) {
+            return Err(Error::new(
                 ErrorKind::PermissionDenied,
-                "no valid credential found, please check configuration or try again",
+                "credential was previously loaded successfully but has failed this time",
             )
-            .set_temporary())
+            .set_temporary());
         }
+
+        // Credential is empty and users allow anonymous access, we will not sign the request.
+        if self.allow_anonymous {
+            return Ok(None);
+        }
+
+        Err(Error::new(
+            ErrorKind::PermissionDenied,
+            "no valid credential found and anonymous access is not allowed",
+        ))
     }
 
     pub async fn sign<T>(&self, req: &mut Request<T>) -> Result<()> {