fix: fixes missing bucket object lock config error

Fixes #1751

When an object lock–related operation is performed on an object in a bucket where Object Lock is not enabled, an `InvalidRequest` error is returned; however, the error message differs for some actions. This PR introduces a new error, `ErrMissingObjectLockConfigurationNoSpaces`, for `PutObject`, `CopyObject`, and `CreateMultipartUpload` to maintain compatibility with S3 in terms of the error message. It also adds the missing integration tests for these actions.
This commit is contained in:
niksis02
2026-01-14 13:41:50 +04:00
parent 5979e056e1
commit 2a7e76a44f
11 changed files with 126 additions and 18 deletions
+16 -4
View File
@@ -364,6 +364,9 @@ func (az *Azure) PutObject(ctx context.Context, po s3response.PutObjectInput) (s
if po.ObjectLockLegalHoldStatus == types.ObjectLockLegalHoldStatusOn {
err := az.PutObjectLegalHold(ctx, *po.Bucket, *po.Key, "", true)
if err != nil {
if errors.Is(err, s3err.GetAPIError(s3err.ErrMissingObjectLockConfiguration)) {
err = s3err.GetAPIError(s3err.ErrMissingObjectLockConfigurationNoSpaces)
}
return s3response.PutObjectOutput{}, err
}
}
@@ -380,6 +383,9 @@ func (az *Azure) PutObject(ctx context.Context, po s3response.PutObjectInput) (s
}
err = az.PutObjectRetention(ctx, *po.Bucket, *po.Key, "", retParsed)
if err != nil {
if errors.Is(err, s3err.GetAPIError(s3err.ErrMissingObjectLockConfiguration)) {
err = s3err.GetAPIError(s3err.ErrMissingObjectLockConfigurationNoSpaces)
}
return s3response.PutObjectOutput{}, err
}
}
@@ -980,6 +986,9 @@ func (az *Azure) CopyObject(ctx context.Context, input s3response.CopyObjectInpu
if input.ObjectLockLegalHoldStatus != "" {
err = az.PutObjectLegalHold(ctx, *input.Bucket, *input.Key, "", input.ObjectLockLegalHoldStatus == types.ObjectLockLegalHoldStatusOn)
if err != nil {
if errors.Is(err, s3err.GetAPIError(s3err.ErrMissingObjectLockConfiguration)) {
err = s3err.GetAPIError(s3err.ErrMissingObjectLockConfigurationNoSpaces)
}
return s3response.CopyObjectOutput{}, azureErrToS3Err(err)
}
}
@@ -998,6 +1007,9 @@ func (az *Azure) CopyObject(ctx context.Context, input s3response.CopyObjectInpu
}
err = az.PutObjectRetention(ctx, *input.Bucket, *input.Key, "", retParsed)
if err != nil {
if errors.Is(err, s3err.GetAPIError(s3err.ErrMissingObjectLockConfiguration)) {
err = s3err.GetAPIError(s3err.ErrMissingObjectLockConfigurationNoSpaces)
}
return s3response.CopyObjectOutput{}, azureErrToS3Err(err)
}
}
@@ -1140,7 +1152,7 @@ func (az *Azure) CreateMultipartUpload(ctx context.Context, input s3response.Cre
}
if len(bucketLock) == 0 {
return s3response.InitiateMultipartUploadResult{}, s3err.GetAPIError(s3err.ErrInvalidBucketObjectLockConfiguration)
return s3response.InitiateMultipartUploadResult{}, s3err.GetAPIError(s3err.ErrMissingObjectLockConfigurationNoSpaces)
}
var bucketLockConfig auth.BucketLockConfig
@@ -1149,7 +1161,7 @@ func (az *Azure) CreateMultipartUpload(ctx context.Context, input s3response.Cre
}
if !bucketLockConfig.Enabled {
return s3response.InitiateMultipartUploadResult{}, s3err.GetAPIError(s3err.ErrInvalidBucketObjectLockConfiguration)
return s3response.InitiateMultipartUploadResult{}, s3err.GetAPIError(s3err.ErrMissingObjectLockConfigurationNoSpaces)
}
}
@@ -1839,7 +1851,7 @@ func (az *Azure) isBucketObjectLockEnabled(ctx context.Context, bucket string) e
}
if len(cfg) == 0 {
return s3err.GetAPIError(s3err.ErrInvalidBucketObjectLockConfiguration)
return s3err.GetAPIError(s3err.ErrMissingObjectLockConfiguration)
}
var bucketLockConfig auth.BucketLockConfig
@@ -1848,7 +1860,7 @@ func (az *Azure) isBucketObjectLockEnabled(ctx context.Context, bucket string) e
}
if !bucketLockConfig.Enabled {
return s3err.GetAPIError(s3err.ErrInvalidBucketObjectLockConfiguration)
return s3err.GetAPIError(s3err.ErrMissingObjectLockConfiguration)
}
return nil
+14 -2
View File
@@ -1359,6 +1359,9 @@ func (p *Posix) CreateMultipartUpload(ctx context.Context, mpu s3response.Create
if mpu.ObjectLockLegalHoldStatus == types.ObjectLockLegalHoldStatusOn {
err := p.PutObjectLegalHold(ctx, bucket, filepath.Join(objdir, uploadID), "", true)
if err != nil {
if errors.Is(err, s3err.GetAPIError(s3err.ErrMissingObjectLockConfiguration)) {
err = s3err.GetAPIError(s3err.ErrMissingObjectLockConfigurationNoSpaces)
}
// cleanup object if returning error
os.RemoveAll(filepath.Join(tmppath, uploadID))
os.Remove(tmppath)
@@ -1381,6 +1384,9 @@ func (p *Posix) CreateMultipartUpload(ctx context.Context, mpu s3response.Create
}
err = p.PutObjectRetention(ctx, bucket, filepath.Join(objdir, uploadID), "", retParsed)
if err != nil {
if errors.Is(err, s3err.GetAPIError(s3err.ErrMissingObjectLockConfiguration)) {
err = s3err.GetAPIError(s3err.ErrMissingObjectLockConfigurationNoSpaces)
}
// cleanup object if returning error
os.RemoveAll(filepath.Join(tmppath, uploadID))
os.Remove(tmppath)
@@ -3238,6 +3244,9 @@ func (p *Posix) PutObjectWithPostFunc(ctx context.Context, po s3response.PutObje
if po.ObjectLockLegalHoldStatus == types.ObjectLockLegalHoldStatusOn {
err := p.PutObjectLegalHold(ctx, *po.Bucket, *po.Key, "", true)
if err != nil {
if errors.Is(err, s3err.GetAPIError(s3err.ErrMissingObjectLockConfiguration)) {
err = s3err.GetAPIError(s3err.ErrMissingObjectLockConfigurationNoSpaces)
}
return s3response.PutObjectOutput{}, err
}
}
@@ -3254,6 +3263,9 @@ func (p *Posix) PutObjectWithPostFunc(ctx context.Context, po s3response.PutObje
}
err = p.PutObjectRetention(ctx, *po.Bucket, *po.Key, "", retParsed)
if err != nil {
if errors.Is(err, s3err.GetAPIError(s3err.ErrMissingObjectLockConfiguration)) {
err = s3err.GetAPIError(s3err.ErrMissingObjectLockConfigurationNoSpaces)
}
return s3response.PutObjectOutput{}, err
}
}
@@ -5108,7 +5120,7 @@ func (p *Posix) isBucketObjectLockEnabled(bucket string) error {
return s3err.GetAPIError(s3err.ErrNoSuchBucket)
}
if errors.Is(err, meta.ErrNoSuchKey) {
return s3err.GetAPIError(s3err.ErrInvalidBucketObjectLockConfiguration)
return s3err.GetAPIError(s3err.ErrMissingObjectLockConfiguration)
}
if err != nil {
return fmt.Errorf("get object lock config: %w", err)
@@ -5120,7 +5132,7 @@ func (p *Posix) isBucketObjectLockEnabled(bucket string) error {
}
if !bucketLockConfig.Enabled {
return s3err.GetAPIError(s3err.ErrInvalidBucketObjectLockConfiguration)
return s3err.GetAPIError(s3err.ErrMissingObjectLockConfiguration)
}
return nil