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<()> {