mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-05-19 08:11:29 +00:00
fixes
✅ Return 409 (Conflict) with InvalidBucketState for bucket-level object lock configuration operations on buckets without object lock enabled ✅ Allow increasing retention periods and overriding retention with same/later dates ✅ Only block decreasing retention periods without proper bypass permissions ✅ Handle all object lock validation errors consistently with proper error codes
This commit is contained in:
@@ -4,6 +4,8 @@ import (
|
||||
"encoding/xml"
|
||||
"net/http"
|
||||
|
||||
"errors"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||
"github.com/seaweedfs/seaweedfs/weed/s3api/s3_constants"
|
||||
"github.com/seaweedfs/seaweedfs/weed/s3api/s3err"
|
||||
@@ -17,7 +19,16 @@ func (s3a *S3ApiServer) PutObjectLockConfigurationHandler(w http.ResponseWriter,
|
||||
glog.V(3).Infof("PutObjectLockConfigurationHandler %s", bucket)
|
||||
|
||||
// Check if Object Lock is available for this bucket (requires versioning)
|
||||
if !s3a.handleObjectLockAvailabilityCheck(w, r, bucket, "PutObjectLockConfigurationHandler") {
|
||||
// For bucket-level operations, return InvalidBucketState (409) when object lock is not available
|
||||
if err := s3a.isObjectLockAvailable(bucket); err != nil {
|
||||
glog.Errorf("PutObjectLockConfigurationHandler: object lock not available for bucket %s: %v", bucket, err)
|
||||
if errors.Is(err, ErrBucketNotFound) {
|
||||
s3err.WriteErrorResponse(w, r, s3err.ErrNoSuchBucket)
|
||||
} else {
|
||||
// Return InvalidBucketState for bucket-level object lock operations on buckets without object lock enabled
|
||||
// This matches AWS S3 behavior and s3-tests expectations (409 Conflict)
|
||||
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidBucketState)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -348,18 +348,26 @@ func (s3a *S3ApiServer) setObjectRetention(bucket, object, versionId string, ret
|
||||
// Check if object is already under retention
|
||||
if entry.Extended != nil {
|
||||
if existingMode, exists := entry.Extended[s3_constants.ExtObjectLockModeKey]; exists {
|
||||
if string(existingMode) == s3_constants.RetentionModeCompliance && !bypassGovernance {
|
||||
// Return 403 Forbidden for compliance mode changes without bypass
|
||||
return ErrComplianceModeActive
|
||||
}
|
||||
|
||||
if existingDateBytes, dateExists := entry.Extended[s3_constants.ExtRetentionUntilDateKey]; dateExists {
|
||||
if timestamp, err := strconv.ParseInt(string(existingDateBytes), 10, 64); err == nil {
|
||||
existingDate := time.Unix(timestamp, 0)
|
||||
if existingDate.After(time.Now()) && string(existingMode) == s3_constants.RetentionModeGovernance && !bypassGovernance {
|
||||
// Return 403 Forbidden for governance mode changes without bypass
|
||||
return ErrGovernanceModeActive
|
||||
|
||||
// Check if the new retention date is earlier than the existing one
|
||||
if retention.RetainUntilDate != nil && retention.RetainUntilDate.Before(existingDate) {
|
||||
// Attempting to decrease retention period
|
||||
if string(existingMode) == s3_constants.RetentionModeCompliance {
|
||||
// Cannot decrease compliance mode retention without bypass
|
||||
return ErrComplianceModeActive
|
||||
}
|
||||
|
||||
if string(existingMode) == s3_constants.RetentionModeGovernance && !bypassGovernance {
|
||||
// Cannot decrease governance mode retention without bypass
|
||||
return ErrGovernanceModeActive
|
||||
}
|
||||
}
|
||||
|
||||
// If new retention date is later or same, allow the operation
|
||||
// This covers both increasing retention period and overriding with same/later date
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user