diff --git a/s3api/utils/utils.go b/s3api/utils/utils.go index 7f10ae1f..2bf2f556 100644 --- a/s3api/utils/utils.go +++ b/s3api/utils/utils.go @@ -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{ diff --git a/s3err/s3err.go b/s3err/s3err.go index 6c072d07..00745bcd 100644 --- a/s3err/s3err.go +++ b/s3err/s3err.go @@ -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.", diff --git a/tests/integration/group-tests.go b/tests/integration/group-tests.go index d918500d..920548b5 100644 --- a/tests/integration/group-tests.go +++ b/tests/integration/group-tests.go @@ -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, diff --git a/tests/integration/tests.go b/tests/integration/tests.go index cb8f164d..f741c991 100644 --- a/tests/integration/tests.go +++ b/tests/integration/tests.go @@ -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 {