mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-18 10:43:15 +00:00
fix: restore default CORS fallback and STS object ACL ownership (#2053)
Co-authored-by: houseme <housemecn@gmail.com>
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
use crate::app::context::{AppContext, default_notify_interface, get_global_app_context};
|
||||
use crate::config::workload_profiles::RustFSBufferConfig;
|
||||
use crate::error::ApiError;
|
||||
use crate::storage::access::{ReqInfo, authorize_request, has_bypass_governance_header, req_info_mut};
|
||||
use crate::storage::access::{authorize_request, has_bypass_governance_header, req_info_mut};
|
||||
use crate::storage::concurrency::{
|
||||
CachedGetObject, ConcurrencyManager, GetObjectGuard, get_concurrency_aware_buffer_size, get_concurrency_manager,
|
||||
};
|
||||
@@ -29,7 +29,7 @@ use crate::storage::options::{
|
||||
filter_object_metadata, get_content_sha256_with_query, get_opts, put_opts,
|
||||
};
|
||||
use crate::storage::s3_api::multipart::parse_list_parts_params;
|
||||
use crate::storage::s3_api::{restore, select};
|
||||
use crate::storage::s3_api::{acl, restore, select};
|
||||
use crate::storage::*;
|
||||
use bytes::Bytes;
|
||||
use datafusion::arrow::{
|
||||
@@ -287,11 +287,6 @@ impl DefaultObjectUsecase {
|
||||
body,
|
||||
bucket,
|
||||
key,
|
||||
acl,
|
||||
grant_full_control,
|
||||
grant_read,
|
||||
grant_read_acp,
|
||||
grant_write_acp,
|
||||
content_length,
|
||||
content_type,
|
||||
tagging,
|
||||
@@ -318,14 +313,6 @@ impl DefaultObjectUsecase {
|
||||
// Validate object key
|
||||
validate_object_key(&key, "PUT")?;
|
||||
|
||||
if let Some(acl) = &acl
|
||||
&& let Ok((config, _)) = metadata_sys::get_public_access_block_config(&bucket).await
|
||||
&& config.block_public_acls.unwrap_or(false)
|
||||
&& is_public_canned_acl(acl.as_str())
|
||||
{
|
||||
return Err(s3_error!(AccessDenied, "Access Denied"));
|
||||
}
|
||||
|
||||
if let Some(size) = content_length {
|
||||
self.check_bucket_quota(&bucket, QuotaOperation::PutObject, size as u64)
|
||||
.await?;
|
||||
@@ -407,33 +394,6 @@ impl DefaultObjectUsecase {
|
||||
)?;
|
||||
|
||||
let mut metadata = metadata.unwrap_or_default();
|
||||
let owner = req
|
||||
.extensions
|
||||
.get::<ReqInfo>()
|
||||
.and_then(|info| info.cred.as_ref())
|
||||
.map(|cred| owner_from_access_key(&cred.access_key))
|
||||
.unwrap_or_else(default_owner);
|
||||
let bucket_owner = default_owner();
|
||||
let mut stored_acl = stored_acl_from_grant_headers(
|
||||
&owner,
|
||||
grant_read.map(|v| v.to_string()),
|
||||
None,
|
||||
grant_read_acp.map(|v| v.to_string()),
|
||||
grant_write_acp.map(|v| v.to_string()),
|
||||
grant_full_control.map(|v| v.to_string()),
|
||||
)?;
|
||||
|
||||
if stored_acl.is_none()
|
||||
&& let Some(canned) = acl.as_ref()
|
||||
{
|
||||
stored_acl = Some(stored_acl_from_canned_object(canned.as_str(), &bucket_owner, &owner));
|
||||
}
|
||||
|
||||
let stored_acl =
|
||||
stored_acl.unwrap_or_else(|| stored_acl_from_canned_object(ObjectCannedACL::PRIVATE, &bucket_owner, &owner));
|
||||
let acl_data = serialize_acl(&stored_acl)?;
|
||||
metadata.insert(INTERNAL_ACL_METADATA_KEY.to_string(), String::from_utf8_lossy(&acl_data).to_string());
|
||||
|
||||
if let Some(content_type) = content_type {
|
||||
metadata.insert("content-type".to_string(), content_type.to_string());
|
||||
}
|
||||
@@ -622,13 +582,7 @@ impl DefaultObjectUsecase {
|
||||
let PutObjectAclInput {
|
||||
bucket,
|
||||
key,
|
||||
acl,
|
||||
access_control_policy,
|
||||
grant_full_control,
|
||||
grant_read,
|
||||
grant_read_acp,
|
||||
grant_write,
|
||||
grant_write_acp,
|
||||
version_id,
|
||||
..
|
||||
} = req.input;
|
||||
@@ -640,64 +594,15 @@ impl DefaultObjectUsecase {
|
||||
let opts: ObjectOptions = get_opts(&bucket, &key, version_id.clone(), None, &req.headers)
|
||||
.await
|
||||
.map_err(ApiError::from)?;
|
||||
let info = store.get_object_info(&bucket, &key, &opts).await.map_err(ApiError::from)?;
|
||||
store.get_object_info(&bucket, &key, &opts).await.map_err(ApiError::from)?;
|
||||
|
||||
let bucket_owner = default_owner();
|
||||
let existing_owner = info
|
||||
.user_defined
|
||||
.get(INTERNAL_ACL_METADATA_KEY)
|
||||
.and_then(|acl| serde_json::from_str::<StoredAcl>(acl).ok())
|
||||
.map(|acl| acl.owner)
|
||||
.unwrap_or_else(|| bucket_owner.clone());
|
||||
|
||||
let mut stored_acl = access_control_policy
|
||||
.as_ref()
|
||||
.map(|policy| stored_acl_from_policy(policy, &existing_owner))
|
||||
.transpose()?;
|
||||
|
||||
if stored_acl.is_none() {
|
||||
stored_acl = stored_acl_from_grant_headers(
|
||||
&existing_owner,
|
||||
grant_read.map(|v| v.to_string()),
|
||||
grant_write.map(|v| v.to_string()),
|
||||
grant_read_acp.map(|v| v.to_string()),
|
||||
grant_write_acp.map(|v| v.to_string()),
|
||||
grant_full_control.map(|v| v.to_string()),
|
||||
)?;
|
||||
if access_control_policy.is_some() {
|
||||
return Err(s3_error!(
|
||||
NotImplemented,
|
||||
"ACL XML grants are not supported; use canned ACL headers or omit ACL"
|
||||
));
|
||||
}
|
||||
|
||||
if stored_acl.is_none()
|
||||
&& let Some(canned) = acl
|
||||
{
|
||||
stored_acl = Some(stored_acl_from_canned_object(canned.as_str(), &bucket_owner, &existing_owner));
|
||||
}
|
||||
|
||||
let stored_acl =
|
||||
stored_acl.unwrap_or_else(|| stored_acl_from_canned_object(ObjectCannedACL::PRIVATE, &bucket_owner, &existing_owner));
|
||||
|
||||
if let Ok((config, _)) = metadata_sys::get_public_access_block_config(&bucket).await
|
||||
&& config.block_public_acls.unwrap_or(false)
|
||||
&& stored_acl.grants.iter().any(is_public_grant)
|
||||
{
|
||||
return Err(s3_error!(AccessDenied, "Access Denied"));
|
||||
}
|
||||
|
||||
let acl_data = serialize_acl(&stored_acl)?;
|
||||
let mut eval_metadata = HashMap::new();
|
||||
eval_metadata.insert(INTERNAL_ACL_METADATA_KEY.to_string(), String::from_utf8_lossy(&acl_data).to_string());
|
||||
|
||||
let popts = ObjectOptions {
|
||||
mod_time: info.mod_time,
|
||||
version_id: opts.version_id,
|
||||
eval_metadata: Some(eval_metadata),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
store.put_object_metadata(&bucket, &key, &popts).await.map_err(|e| {
|
||||
error!("put_object_metadata failed, {}", e.to_string());
|
||||
s3_error!(InternalError, "{}", e.to_string())
|
||||
})?;
|
||||
|
||||
Ok(S3Response::new(PutObjectAclOutput::default()))
|
||||
}
|
||||
|
||||
@@ -1606,31 +1511,9 @@ impl DefaultObjectUsecase {
|
||||
let opts: ObjectOptions = get_opts(&bucket, &key, version_id.clone(), None, &req.headers)
|
||||
.await
|
||||
.map_err(ApiError::from)?;
|
||||
let info = store.get_object_info(&bucket, &key, &opts).await.map_err(ApiError::from)?;
|
||||
store.get_object_info(&bucket, &key, &opts).await.map_err(ApiError::from)?;
|
||||
|
||||
let bucket_owner = default_owner();
|
||||
let object_owner = info
|
||||
.user_defined
|
||||
.get(INTERNAL_ACL_METADATA_KEY)
|
||||
.and_then(|acl| serde_json::from_str::<StoredAcl>(acl).ok())
|
||||
.map(|acl| acl.owner)
|
||||
.unwrap_or_else(default_owner);
|
||||
|
||||
let stored_acl = info
|
||||
.user_defined
|
||||
.get(INTERNAL_ACL_METADATA_KEY)
|
||||
.map(|acl| parse_acl_json_or_canned_object(acl, &bucket_owner, &object_owner))
|
||||
.unwrap_or_else(|| stored_acl_from_canned_object(ObjectCannedACL::PRIVATE, &bucket_owner, &object_owner));
|
||||
|
||||
let mut sorted_grants = stored_acl.grants.clone();
|
||||
sorted_grants.sort_by_key(|grant| grant.grantee.grantee_type != "Group");
|
||||
let grants = sorted_grants.iter().map(stored_grant_to_dto).collect();
|
||||
|
||||
Ok(S3Response::new(GetObjectAclOutput {
|
||||
grants: Some(grants),
|
||||
owner: Some(stored_owner_to_dto(&stored_acl.owner)),
|
||||
..Default::default()
|
||||
}))
|
||||
Ok(S3Response::new(acl::build_get_object_acl_output()))
|
||||
}
|
||||
|
||||
pub async fn execute_get_object_attributes(
|
||||
|
||||
Reference in New Issue
Block a user