Merge pull request #1148 from versity/sis/object-lock-mode-validation

fix: Fixes the returned error type for object legal hold status and o…
This commit is contained in:
Ben McClelland
2025-03-18 08:24:31 -07:00
committed by GitHub
4 changed files with 130 additions and 2 deletions

View File

@@ -349,13 +349,13 @@ func ParsObjectLockHdrs(ctx *fiber.Ctx) (*objLockCfg, error) {
if objLockMode != "" &&
objLockMode != types.ObjectLockModeCompliance &&
objLockMode != types.ObjectLockModeGovernance {
return nil, s3err.GetAPIError(s3err.ErrInvalidRequest)
return nil, s3err.GetAPIError(s3err.ErrInvalidObjectLockMode)
}
legalHold := types.ObjectLockLegalHoldStatus(legalHoldHdr)
if legalHold != "" && legalHold != types.ObjectLockLegalHoldStatusOff && legalHold != types.ObjectLockLegalHoldStatusOn {
return nil, s3err.GetAPIError(s3err.ErrInvalidRequest)
return nil, s3err.GetAPIError(s3err.ErrInvalidLegalHoldStatus)
}
return &objLockCfg{

View File

@@ -131,6 +131,8 @@ const (
ErrObjectLocked
ErrPastObjectLockRetainDate
ErrObjectLockInvalidRetentionPeriod
ErrInvalidLegalHoldStatus
ErrInvalidObjectLockMode
ErrNoSuchBucketPolicy
ErrBucketTaggingNotFound
ErrObjectLockInvalidHeaders
@@ -533,6 +535,16 @@ var errorCodeResponse = map[ErrorCode]APIError{
Description: "the retention days/years must be positive integer.",
HTTPStatusCode: http.StatusBadRequest,
},
ErrInvalidLegalHoldStatus: {
Code: "InvalidArgument",
Description: "Legal Hold must be either of 'ON' or 'OFF'",
HTTPStatusCode: http.StatusBadRequest,
},
ErrInvalidObjectLockMode: {
Code: "InvalidArgument",
Description: "Unknown wormMode directive.",
HTTPStatusCode: http.StatusBadRequest,
},
ErrNoSuchBucketPolicy: {
Code: "NoSuchBucketPolicy",
Description: "The bucket policy does not exist.",

View File

@@ -140,6 +140,8 @@ func TestPutObject(s *S3Conf) {
PutObject_invalid_long_tags(s)
PutObject_missing_object_lock_retention_config(s)
PutObject_with_object_lock(s)
PutObject_invalid_legal_hold(s)
PutObject_invalid_object_lock_mode(s)
//TODO: remove the condition after implementing checksums in azure
if !s.azureTests {
PutObject_checksum_algorithm_and_header_mismatch(s)
@@ -273,6 +275,8 @@ func TestCopyObject(s *S3Conf) {
CopyObject_non_existing_dir_object(s)
CopyObject_should_copy_meta_props(s)
CopyObject_should_replace_meta_props(s)
CopyObject_invalid_legal_hold(s)
CopyObject_invalid_object_lock_mode(s)
CopyObject_with_legal_hold(s)
CopyObject_with_retention_lock(s)
//TODO: remove the condition after implementing checksums in azure
@@ -314,6 +318,8 @@ func TestCreateMultipartUpload(s *S3Conf) {
CreateMultipartUpload_with_object_lock_not_enabled(s)
CreateMultipartUpload_with_object_lock_invalid_retention(s)
CreateMultipartUpload_past_retain_until_date(s)
CreateMultipartUpload_invalid_legal_hold(s)
CreateMultipartUpload_invalid_object_lock_mode(s)
//TODO: remove the condition after implementing checksums in azure
if !s.azureTests {
CreateMultipartUpload_invalid_checksum_algorithm(s)
@@ -793,6 +799,8 @@ func GetIntTests() IntTests {
"PutObject_missing_object_lock_retention_config": PutObject_missing_object_lock_retention_config,
"PutObject_name_too_long": PutObject_name_too_long,
"PutObject_with_object_lock": PutObject_with_object_lock,
"PutObject_invalid_legal_hold": PutObject_invalid_legal_hold,
"PutObject_invalid_object_lock_mode": PutObject_invalid_object_lock_mode,
"PutObject_checksum_algorithm_and_header_mismatch": PutObject_checksum_algorithm_and_header_mismatch,
"PutObject_multiple_checksum_headers": PutObject_multiple_checksum_headers,
"PutObject_invalid_checksum_header": PutObject_invalid_checksum_header,
@@ -922,6 +930,8 @@ func GetIntTests() IntTests {
"CopyObject_non_existing_dir_object": CopyObject_non_existing_dir_object,
"CopyObject_should_copy_meta_props": CopyObject_should_copy_meta_props,
"CopyObject_should_replace_meta_props": CopyObject_should_replace_meta_props,
"CopyObject_invalid_legal_hold": CopyObject_invalid_legal_hold,
"CopyObject_invalid_object_lock_mode": CopyObject_invalid_object_lock_mode,
"CopyObject_with_legal_hold": CopyObject_with_legal_hold,
"CopyObject_with_retention_lock": CopyObject_with_retention_lock,
"CopyObject_invalid_checksum_algorithm": CopyObject_invalid_checksum_algorithm,
@@ -948,6 +958,8 @@ func GetIntTests() IntTests {
"CreateMultipartUpload_with_object_lock_not_enabled": CreateMultipartUpload_with_object_lock_not_enabled,
"CreateMultipartUpload_with_object_lock_invalid_retention": CreateMultipartUpload_with_object_lock_invalid_retention,
"CreateMultipartUpload_past_retain_until_date": CreateMultipartUpload_past_retain_until_date,
"CreateMultipartUpload_invalid_legal_hold": CreateMultipartUpload_invalid_legal_hold,
"CreateMultipartUpload_invalid_object_lock_mode": CreateMultipartUpload_invalid_object_lock_mode,
"CreateMultipartUpload_invalid_checksum_algorithm": CreateMultipartUpload_invalid_checksum_algorithm,
"CreateMultipartUpload_empty_checksum_algorithm_with_checksum_type": CreateMultipartUpload_empty_checksum_algorithm_with_checksum_type,
"CreateMultipartUpload_invalid_checksum_type": CreateMultipartUpload_invalid_checksum_type,

View File

@@ -2924,6 +2924,31 @@ func PutObject_with_object_lock(s *S3Conf) error {
return nil
}
func PutObject_invalid_legal_hold(s *S3Conf) error {
testName := "PutObject_invalid_legal_hold"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
_, err := putObjectWithData(10, &s3.PutObjectInput{
Bucket: &bucket,
Key: getPtr("foo"),
ObjectLockLegalHoldStatus: types.ObjectLockLegalHoldStatus("invalid_status"),
}, s3client)
return checkApiErr(err, s3err.GetAPIError(s3err.ErrInvalidLegalHoldStatus))
}, withLock())
}
func PutObject_invalid_object_lock_mode(s *S3Conf) error {
testName := "PutObject_invalid_object_lock_mode"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
rDate := time.Now().Add(time.Hour * 10)
_, err := putObjectWithData(10, &s3.PutObjectInput{
Bucket: &bucket,
Key: getPtr("foo"),
ObjectLockRetainUntilDate: &rDate,
ObjectLockMode: types.ObjectLockMode("invalid_mode"),
}, s3client)
return checkApiErr(err, s3err.GetAPIError(s3err.ErrInvalidObjectLockMode))
}, withLock())
}
func PutObject_checksum_algorithm_and_header_mismatch(s *S3Conf) error {
testName := "PutObject_checksum_algorithm_and_header_mismatch"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
@@ -6294,6 +6319,55 @@ func CopyObject_should_replace_meta_props(s *S3Conf) error {
})
}
func CopyObject_invalid_legal_hold(s *S3Conf) error {
testName := "CopyObject_invalid_legal_hold"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
srcObj, dstObj := "source-object", "dst-object"
_, err := putObjectWithData(10, &s3.PutObjectInput{
Bucket: &bucket,
Key: &srcObj,
}, s3client)
if err != nil {
return err
}
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
_, err = s3client.CopyObject(ctx, &s3.CopyObjectInput{
Bucket: &bucket,
Key: &dstObj,
CopySource: getPtr(fmt.Sprintf("%v/%v", bucket, srcObj)),
ObjectLockLegalHoldStatus: types.ObjectLockLegalHoldStatus("invalid_status"),
})
cancel()
return checkApiErr(err, s3err.GetAPIError(s3err.ErrInvalidLegalHoldStatus))
}, withLock())
}
func CopyObject_invalid_object_lock_mode(s *S3Conf) error {
testName := "CopyObject_invalid_object_lock_mode"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
srcObj, dstObj := "source-object", "dst-object"
_, err := putObjectWithData(10, &s3.PutObjectInput{
Bucket: &bucket,
Key: &srcObj,
}, s3client)
if err != nil {
return err
}
rDate := time.Now().Add(time.Hour * 20)
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
_, err = s3client.CopyObject(ctx, &s3.CopyObjectInput{
Bucket: &bucket,
Key: &dstObj,
CopySource: getPtr(fmt.Sprintf("%v/%v", bucket, srcObj)),
ObjectLockRetainUntilDate: &rDate,
ObjectLockMode: types.ObjectLockMode("invalid_mode"),
})
cancel()
return checkApiErr(err, s3err.GetAPIError(s3err.ErrInvalidObjectLockMode))
}, withLock())
}
func CopyObject_with_legal_hold(s *S3Conf) error {
testName := "CopyObject_with_legal_hold"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
@@ -7217,6 +7291,36 @@ func CreateMultipartUpload_past_retain_until_date(s *S3Conf) error {
})
}
func CreateMultipartUpload_invalid_legal_hold(s *S3Conf) error {
testName := "CreateMultipartUpload_invalid_legal_hold"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
_, err := s3client.CreateMultipartUpload(ctx, &s3.CreateMultipartUploadInput{
Bucket: &bucket,
Key: getPtr("foo"),
ObjectLockLegalHoldStatus: types.ObjectLockLegalHoldStatus("invalid_status"),
})
cancel()
return checkApiErr(err, s3err.GetAPIError(s3err.ErrInvalidLegalHoldStatus))
}, withLock())
}
func CreateMultipartUpload_invalid_object_lock_mode(s *S3Conf) error {
testName := "CreateMultipartUpload_invalid_object_lock_mode"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
rDate := time.Now().Add(time.Hour * 10)
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
_, err := s3client.CreateMultipartUpload(ctx, &s3.CreateMultipartUploadInput{
Bucket: &bucket,
Key: getPtr("foo"),
ObjectLockMode: types.ObjectLockMode("invalid_mode"),
ObjectLockRetainUntilDate: &rDate,
})
cancel()
return checkApiErr(err, s3err.GetAPIError(s3err.ErrInvalidObjectLockMode))
}, withLock())
}
func CreateMultipartUpload_invalid_checksum_algorithm(s *S3Conf) error {
testName := "CreateMultipartUpload_invalid_checksum_algorithm"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {