mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-22 07:06:51 +00:00
s3api: address object lock delete review comments
- Remove versioningConfigured guard: object lock protections must apply to all buckets - Combine identical switch cases for clarity - Change default case to fail-closed (true) for safety - Add test case for suspended versioning with specific versionId - Update test expectations to reflect fail-closed default Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -28,14 +28,12 @@ func objectLockVersionToCheckForDelete(versioningState, requestedVersionID strin
|
||||
}
|
||||
|
||||
switch versioningState {
|
||||
case s3_constants.VersioningEnabled:
|
||||
case s3_constants.VersioningEnabled, "":
|
||||
return "", true
|
||||
case s3_constants.VersioningSuspended:
|
||||
return "null", true
|
||||
case "":
|
||||
return "", true
|
||||
default:
|
||||
return "", false
|
||||
return "", true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,22 +251,20 @@ func (s3a *S3ApiServer) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *h
|
||||
continue
|
||||
}
|
||||
|
||||
// Check object lock permissions before deletion
|
||||
if versioningConfigured {
|
||||
lockCheckVersionID, shouldCheckObjectLock := objectLockVersionToCheckForDelete(versioningState, object.VersionId)
|
||||
if shouldCheckObjectLock {
|
||||
// Validate governance bypass for this specific object
|
||||
governanceBypassAllowed := s3a.evaluateGovernanceBypassRequest(r, bucket, object.Key)
|
||||
if err := s3a.enforceObjectLockProtections(r, bucket, object.Key, lockCheckVersionID, governanceBypassAllowed); err != nil {
|
||||
glog.V(2).Infof("DeleteMultipleObjectsHandler: object lock check failed for %s/%s (version: %s): %v", bucket, object.Key, lockCheckVersionID, err)
|
||||
deleteErrors = append(deleteErrors, DeleteError{
|
||||
Code: s3err.GetAPIError(s3err.ErrAccessDenied).Code,
|
||||
Message: s3err.GetAPIError(s3err.ErrAccessDenied).Description,
|
||||
Key: object.Key,
|
||||
VersionId: object.VersionId,
|
||||
})
|
||||
continue
|
||||
}
|
||||
// Check object lock permissions before deletion (applies to all buckets: versioned or non-versioned)
|
||||
lockCheckVersionID, shouldCheckObjectLock := objectLockVersionToCheckForDelete(versioningState, object.VersionId)
|
||||
if shouldCheckObjectLock {
|
||||
// Validate governance bypass for this specific object
|
||||
governanceBypassAllowed := s3a.evaluateGovernanceBypassRequest(r, bucket, object.Key)
|
||||
if err := s3a.enforceObjectLockProtections(r, bucket, object.Key, lockCheckVersionID, governanceBypassAllowed); err != nil {
|
||||
glog.V(2).Infof("DeleteMultipleObjectsHandler: object lock check failed for %s/%s (version: %s): %v", bucket, object.Key, lockCheckVersionID, err)
|
||||
deleteErrors = append(deleteErrors, DeleteError{
|
||||
Code: s3err.GetAPIError(s3err.ErrAccessDenied).Code,
|
||||
Message: s3err.GetAPIError(s3err.ErrAccessDenied).Description,
|
||||
Key: object.Key,
|
||||
VersionId: object.VersionId,
|
||||
})
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,11 +44,18 @@ func TestObjectLockVersionToCheckForDelete(t *testing.T) {
|
||||
expectedShouldCheck: true,
|
||||
},
|
||||
{
|
||||
name: "unknown versioning state without version id is skipped",
|
||||
name: "unknown versioning state without version id is checked (fail-closed for safety)",
|
||||
versioningState: "UnexpectedState",
|
||||
requestedVersionID: "",
|
||||
expectedVersionID: "",
|
||||
expectedShouldCheck: false,
|
||||
expectedShouldCheck: true,
|
||||
},
|
||||
{
|
||||
name: "suspended versioning with specific version id checks that version",
|
||||
versioningState: s3_constants.VersioningSuspended,
|
||||
requestedVersionID: "abc123",
|
||||
expectedVersionID: "abc123",
|
||||
expectedShouldCheck: true,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user