Skip to content

Commit

Permalink
feat(services/s3): Return error if credential is empty after loaded (#…
Browse files Browse the repository at this point in the history
…4000)

Signed-off-by: Xuanwo <[email protected]>
  • Loading branch information
Xuanwo authored Jan 17, 2024
1 parent c6bb112 commit b2c59eb
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 9 deletions.
2 changes: 2 additions & 0 deletions core/src/services/s3/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
}),
Expand Down
34 changes: 25 additions & 9 deletions core/src/services/s3/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
}
Expand All @@ -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<()> {
Expand Down

0 comments on commit b2c59eb

Please sign in to comment.