fix: block force delete on object lock buckets (#4298)

This commit is contained in:
Zhengchao An
2026-07-06 14:05:39 +08:00
committed by GitHub
parent 3e4c15da5d
commit a9115f729e
3 changed files with 29 additions and 6 deletions
+19 -1
View File
@@ -423,7 +423,7 @@ impl BucketMetadata {
}
pub fn object_locking(&self) -> bool {
self.lock_enabled || (self.versioning_config.as_ref().is_some_and(|v| v.enabled()))
self.lock_enabled || self.object_lock_config.as_ref().is_some_and(|v| v.enabled())
}
pub fn table_bucket_enabled(&self) -> bool {
@@ -1113,6 +1113,24 @@ mod test {
assert_eq!(bm.name, new.name);
}
#[test]
fn object_locking_requires_lock_metadata_not_plain_versioning() {
use s3s::dto::ObjectLockEnabled;
let mut bm = BucketMetadata::new("test-bucket");
bm.versioning_config = Some(VersioningConfiguration {
status: Some(s3s::dto::BucketVersioningStatus::from_static("Enabled")),
..Default::default()
});
assert!(!bm.object_locking());
bm.object_lock_config = Some(ObjectLockConfiguration {
object_lock_enabled: Some(ObjectLockEnabled::from_static(ObjectLockEnabled::ENABLED)),
..Default::default()
});
assert!(bm.object_locking());
}
#[test]
fn parse_all_configs_parses_stored_configs_without_store_dependency() {
let mut bm = BucketMetadata::new("test-bucket");
+10 -3
View File
@@ -17,6 +17,8 @@
// Performance metrics recording (with zero-copy-metrics integration)
use rustfs_io_metrics::buffered_write;
use crate::storage_api::table::get_bucket_metadata;
use super::storage_api::object_usecase::ECStore;
use super::storage_api::object_usecase::access::{
PostObjectRequestMarker, authorize_request, has_bypass_governance_header, req_info_mut,
@@ -35,7 +37,7 @@ use super::storage_api::object_usecase::bucket::{
metadata_sys,
object_lock::{
objectlock::{get_object_legalhold_meta, get_object_retention_meta},
objectlock_sys::{BucketObjectLockSys, check_object_lock_for_deletion, is_retention_active},
objectlock_sys::{check_object_lock_for_deletion, is_retention_active},
},
predict_lifecycle_expiration,
quota::QuotaOperation,
@@ -5053,8 +5055,7 @@ impl DefaultObjectUsecase {
});
let force_delete = opts.delete_prefix;
let lock_cfg = BucketObjectLockSys::get(&bucket).await;
if lock_cfg.is_some() && opts.delete_prefix {
if opts.delete_prefix && bucket_object_locking_enabled(&bucket).await {
return Err(S3Error::with_message(
S3ErrorCode::Custom("force-delete is forbidden on Object Locking enabled buckets".into()),
"force-delete is forbidden on Object Locking enabled buckets",
@@ -6265,6 +6266,12 @@ fn object_attributes_requested(object_attributes: &[ObjectAttributes], name: &'s
})
}
async fn bucket_object_locking_enabled(bucket: &str) -> bool {
get_bucket_metadata(bucket)
.await
.is_ok_and(|metadata| metadata.object_locking())
}
#[cfg(test)]
mod tests {
use super::*;
-2
View File
@@ -567,8 +567,6 @@ pub(crate) mod bucket {
}
pub(crate) mod objectlock_sys {
pub(crate) type BucketObjectLockSys =
crate::storage::storage_api::ecstore_bucket::object_lock::objectlock_sys::BucketObjectLockSys;
pub(crate) type ObjectLockBlockReason =
crate::storage::storage_api::ecstore_bucket::object_lock::objectlock_sys::ObjectLockBlockReason;