diff --git a/s3api/controllers/base.go b/s3api/controllers/base.go index 39c96c41..b5ccb725 100644 --- a/s3api/controllers/base.go +++ b/s3api/controllers/base.go @@ -1405,11 +1405,21 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { if ctx.Request().URI().QueryArgs().Has("legal-hold") { var legalHold types.ObjectLockLegalHold if err := xml.Unmarshal(ctx.Body(), &legalHold); err != nil { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), &MetaOpts{ - Logger: c.logger, - Action: "PutObjectLegalHold", - BucketOwner: parsedAcl.Owner, - }) + return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), + &MetaOpts{ + Logger: c.logger, + Action: "PutObjectLegalHold", + BucketOwner: parsedAcl.Owner, + }) + } + + if legalHold.Status != types.ObjectLockLegalHoldStatusOff && legalHold.Status != types.ObjectLockLegalHoldStatusOn { + return SendResponse(ctx, s3err.GetAPIError(s3err.ErrMalformedXML), + &MetaOpts{ + Logger: c.logger, + Action: "PutObjectLegalHold", + BucketOwner: parsedAcl.Owner, + }) } if err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ diff --git a/s3api/controllers/base_test.go b/s3api/controllers/base_test.go index 540898cd..abbbbc5b 100644 --- a/s3api/controllers/base_test.go +++ b/s3api/controllers/base_test.go @@ -896,7 +896,7 @@ func TestS3ApiController_PutActions(t *testing.T) { legalHoldBody := ` - string + ON ` diff --git a/tests/integration/group-tests.go b/tests/integration/group-tests.go index c1e0abed..a070f101 100644 --- a/tests/integration/group-tests.go +++ b/tests/integration/group-tests.go @@ -345,6 +345,7 @@ func TestPutObjectLegalHold(s *S3Conf) { PutObjectLegalHold_non_existing_bucket(s) PutObjectLegalHold_non_existing_object(s) PutObjectLegalHold_invalid_body(s) + PutObjectLegalHold_invalid_status(s) PutObjectLegalHold_unset_bucket_object_lock_config(s) PutObjectLegalHold_disabled_bucket_object_lock_config(s) PutObjectLegalHold_success(s) @@ -656,6 +657,7 @@ func GetIntTests() IntTests { "PutObjectLegalHold_non_existing_bucket": PutObjectLegalHold_non_existing_bucket, "PutObjectLegalHold_non_existing_object": PutObjectLegalHold_non_existing_object, "PutObjectLegalHold_invalid_body": PutObjectLegalHold_invalid_body, + "PutObjectLegalHold_invalid_status": PutObjectLegalHold_invalid_status, "PutObjectLegalHold_unset_bucket_object_lock_config": PutObjectLegalHold_unset_bucket_object_lock_config, "PutObjectLegalHold_disabled_bucket_object_lock_config": PutObjectLegalHold_disabled_bucket_object_lock_config, "PutObjectLegalHold_success": PutObjectLegalHold_success, diff --git a/tests/integration/tests.go b/tests/integration/tests.go index a47a8ce2..2d873704 100644 --- a/tests/integration/tests.go +++ b/tests/integration/tests.go @@ -6955,6 +6955,26 @@ func PutObjectLegalHold_invalid_body(s *S3Conf) error { }) } +func PutObjectLegalHold_invalid_status(s *S3Conf) error { + testName := "PutObjectLegalHold_invalid_status" + return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { + ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) + _, err := s3client.PutObjectLegalHold(ctx, &s3.PutObjectLegalHoldInput{ + Bucket: &bucket, + Key: getPtr("my-obj"), + LegalHold: &types.ObjectLockLegalHold{ + Status: types.ObjectLockLegalHoldStatus("invalid_status"), + }, + }) + cancel() + if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrMalformedXML)); err != nil { + return err + } + + return nil + }) +} + func PutObjectLegalHold_unset_bucket_object_lock_config(s *S3Conf) error { testName := "PutObjectLegalHold_unset_bucket_object_lock_config" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {