mirror of
https://github.com/rustfs/rustfs.git
synced 2026-03-17 14:24:08 +00:00
refactor(storage): extract ACL response builders into s3_api (#1880)
This commit is contained in:
@@ -23,11 +23,11 @@ use crate::storage::head_prefix::{head_prefix_not_found_message, probe_prefix_ha
|
||||
use crate::storage::helper::OperationHelper;
|
||||
use crate::storage::options::{filter_object_metadata, get_content_sha256};
|
||||
use crate::storage::readers::InMemoryAsyncReader;
|
||||
use crate::storage::s3_api::acl::{build_get_bucket_acl_output, build_get_object_acl_output};
|
||||
use crate::storage::s3_api::bucket::{
|
||||
build_list_buckets_output, build_list_object_versions_output, build_list_objects_output, build_list_objects_v2_output,
|
||||
parse_list_object_versions_params, parse_list_objects_v2_params,
|
||||
};
|
||||
use crate::storage::s3_api::common::rustfs_owner;
|
||||
use crate::storage::s3_api::multipart::{
|
||||
build_list_multipart_uploads_output, build_list_parts_output, parse_list_multipart_uploads_params, parse_list_parts_params,
|
||||
};
|
||||
@@ -148,13 +148,7 @@ use s3s::header::{X_AMZ_RESTORE, X_AMZ_RESTORE_OUTPUT_PATH};
|
||||
use s3s::{S3, S3Error, S3ErrorCode, S3Request, S3Response, S3Result, dto::*, s3_error};
|
||||
use std::convert::Infallible;
|
||||
use std::ops::Add;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fmt::Debug,
|
||||
path::Path,
|
||||
str::FromStr,
|
||||
sync::{Arc, LazyLock},
|
||||
};
|
||||
use std::{collections::HashMap, fmt::Debug, path::Path, str::FromStr, sync::Arc};
|
||||
use time::{OffsetDateTime, format_description::well_known::Rfc3339};
|
||||
use tokio::sync::mpsc;
|
||||
use tokio_stream::wrappers::ReceiverStream;
|
||||
@@ -174,9 +168,6 @@ macro_rules! try_ {
|
||||
};
|
||||
}
|
||||
|
||||
// Shared owner metadata source for S3 response compatibility.
|
||||
pub(crate) static RUSTFS_OWNER: LazyLock<Owner> = LazyLock::new(rustfs_owner);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FS {
|
||||
// pub store: ECStore,
|
||||
@@ -1957,21 +1948,7 @@ impl S3 for FS {
|
||||
.await
|
||||
.map_err(ApiError::from)?;
|
||||
|
||||
let grants = vec![Grant {
|
||||
grantee: Some(Grantee {
|
||||
type_: Type::from_static(Type::CANONICAL_USER),
|
||||
display_name: None,
|
||||
email_address: None,
|
||||
id: None,
|
||||
uri: None,
|
||||
}),
|
||||
permission: Some(Permission::from_static(Permission::FULL_CONTROL)),
|
||||
}];
|
||||
|
||||
Ok(s3_response(GetBucketAclOutput {
|
||||
grants: Some(grants),
|
||||
owner: Some(RUSTFS_OWNER.to_owned()),
|
||||
}))
|
||||
Ok(s3_response(build_get_bucket_acl_output()))
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
@@ -2900,22 +2877,7 @@ impl S3 for FS {
|
||||
return Err(S3Error::with_message(S3ErrorCode::InternalError, format!("{e}")));
|
||||
}
|
||||
|
||||
let grants = vec![Grant {
|
||||
grantee: Some(Grantee {
|
||||
type_: Type::from_static(Type::CANONICAL_USER),
|
||||
display_name: None,
|
||||
email_address: None,
|
||||
id: None,
|
||||
uri: None,
|
||||
}),
|
||||
permission: Some(Permission::from_static(Permission::FULL_CONTROL)),
|
||||
}];
|
||||
|
||||
Ok(s3_response(GetObjectAclOutput {
|
||||
grants: Some(grants),
|
||||
owner: Some(RUSTFS_OWNER.to_owned()),
|
||||
..Default::default()
|
||||
}))
|
||||
Ok(s3_response(build_get_object_acl_output()))
|
||||
}
|
||||
|
||||
async fn get_object_attributes(
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
mod tests {
|
||||
use crate::config::workload_profiles::WorkloadProfile;
|
||||
use crate::storage::ecfs::FS;
|
||||
use crate::storage::ecfs::RUSTFS_OWNER;
|
||||
use crate::storage::s3_api::common::rustfs_owner;
|
||||
use crate::storage::{
|
||||
apply_cors_headers, check_preconditions, get_adaptive_buffer_size_with_profile, get_buffer_size_opt_in, is_etag_equal,
|
||||
matches_origin_pattern, parse_etag, parse_object_lock_legal_hold, parse_object_lock_retention,
|
||||
@@ -67,11 +67,12 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rustfs_owner_constant() {
|
||||
// Test that RUSTFS_OWNER constant is properly defined
|
||||
assert!(!RUSTFS_OWNER.display_name.as_ref().unwrap().is_empty());
|
||||
assert!(!RUSTFS_OWNER.id.as_ref().unwrap().is_empty());
|
||||
assert_eq!(RUSTFS_OWNER.display_name.as_ref().unwrap(), "rustfs");
|
||||
fn test_rustfs_owner_helper() {
|
||||
// Test that rustfs owner metadata remains stable for S3 compatibility.
|
||||
let owner = rustfs_owner();
|
||||
assert!(!owner.display_name.as_ref().unwrap().is_empty());
|
||||
assert!(!owner.id.as_ref().unwrap().is_empty());
|
||||
assert_eq!(owner.display_name.as_ref().unwrap(), "rustfs");
|
||||
}
|
||||
|
||||
// Note: Most S3 API methods require complex setup with global state, storage backend,
|
||||
|
||||
87
rustfs/src/storage/s3_api/acl.rs
Normal file
87
rustfs/src/storage/s3_api/acl.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
// Copyright 2024 RustFS Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::storage::s3_api::common::rustfs_owner;
|
||||
use s3s::dto::{GetBucketAclOutput, GetObjectAclOutput, Grant, Grantee, Permission, Type};
|
||||
|
||||
fn full_control_grants() -> Vec<Grant> {
|
||||
vec![Grant {
|
||||
grantee: Some(Grantee {
|
||||
type_: Type::from_static(Type::CANONICAL_USER),
|
||||
display_name: None,
|
||||
email_address: None,
|
||||
id: None,
|
||||
uri: None,
|
||||
}),
|
||||
permission: Some(Permission::from_static(Permission::FULL_CONTROL)),
|
||||
}]
|
||||
}
|
||||
|
||||
pub(crate) fn build_get_bucket_acl_output() -> GetBucketAclOutput {
|
||||
GetBucketAclOutput {
|
||||
grants: Some(full_control_grants()),
|
||||
owner: Some(rustfs_owner()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn build_get_object_acl_output() -> GetObjectAclOutput {
|
||||
GetObjectAclOutput {
|
||||
grants: Some(full_control_grants()),
|
||||
owner: Some(rustfs_owner()),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{build_get_bucket_acl_output, build_get_object_acl_output};
|
||||
use crate::storage::s3_api::common::rustfs_owner;
|
||||
use s3s::dto::{Permission, Type};
|
||||
|
||||
#[test]
|
||||
fn test_build_get_bucket_acl_output_contains_full_control_grant_and_owner() {
|
||||
let output = build_get_bucket_acl_output();
|
||||
let grants = output.grants.as_ref().expect("grants should be present");
|
||||
let owner = output.owner.as_ref().expect("owner should be present");
|
||||
|
||||
assert_eq!(grants.len(), 1);
|
||||
assert_eq!(grants[0].permission.as_ref().map(Permission::as_str), Some(Permission::FULL_CONTROL));
|
||||
assert_eq!(
|
||||
grants[0].grantee.as_ref().map(|grantee| grantee.type_.as_str()),
|
||||
Some(Type::CANONICAL_USER)
|
||||
);
|
||||
|
||||
let expected_owner = rustfs_owner();
|
||||
assert_eq!(owner.display_name, expected_owner.display_name);
|
||||
assert_eq!(owner.id, expected_owner.id);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_get_object_acl_output_contains_full_control_grant_and_owner() {
|
||||
let output = build_get_object_acl_output();
|
||||
let grants = output.grants.as_ref().expect("grants should be present");
|
||||
let owner = output.owner.as_ref().expect("owner should be present");
|
||||
|
||||
assert_eq!(grants.len(), 1);
|
||||
assert_eq!(grants[0].permission.as_ref().map(Permission::as_str), Some(Permission::FULL_CONTROL));
|
||||
assert_eq!(
|
||||
grants[0].grantee.as_ref().map(|grantee| grantee.type_.as_str()),
|
||||
Some(Type::CANONICAL_USER)
|
||||
);
|
||||
|
||||
let expected_owner = rustfs_owner();
|
||||
assert_eq!(owner.display_name, expected_owner.display_name);
|
||||
assert_eq!(owner.id, expected_owner.id);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
//! This file intentionally starts as skeleton-only. Behavior remains in place
|
||||
//! until each helper is moved with dedicated small refactor steps.
|
||||
|
||||
pub(crate) mod acl {}
|
||||
pub(crate) mod acl;
|
||||
pub(crate) mod bucket;
|
||||
pub(crate) mod common;
|
||||
pub(crate) mod encryption {}
|
||||
|
||||
Reference in New Issue
Block a user