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

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


The following commit(s) were added to refs/heads/main by this push:
     new b2c59eb67f feat(services/s3): Return error if credential is empty 
after loaded (#4000)
b2c59eb67f is described below

commit b2c59eb67fc2902250bafd2ae37b9dacf6a46222
Author: Xuanwo <[email protected]>
AuthorDate: Wed Jan 17 13:07:52 2024 +0800

    feat(services/s3): Return error if credential is empty after loaded (#4000)
    
    Signed-off-by: Xuanwo <[email protected]>
---
 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<()> {

Reply via email to