diff --git a/auth/bucket_policy_actions.go b/auth/bucket_policy_actions.go index 2f5b65f7..8721c931 100644 --- a/auth/bucket_policy_actions.go +++ b/auth/bucket_policy_actions.go @@ -66,6 +66,8 @@ const ( GetEncryptionConfigurationAction Action = "s3:GetEncryptionConfiguration" PutIntelligentTieringConfigurationAction Action = "s3:PutIntelligentTieringConfiguration" GetIntelligentTieringConfigurationAction Action = "s3:GetIntelligentTieringConfiguration" + PutInventoryConfigurationAction Action = "s3:PutInventoryConfiguration" + GetInventoryConfigurationAction Action = "s3:GetInventoryConfiguration" AllActions Action = "s3:*" ) diff --git a/metrics/actions.go b/metrics/actions.go index c25a3d1e..a207e107 100644 --- a/metrics/actions.go +++ b/metrics/actions.go @@ -86,6 +86,10 @@ var ( ActionGetBucketIntelligentTieringConfiguration = "s3_GetBucketIntelligentTieringConfiguration" ActionListBucketIntelligentTieringConfigurations = "s3_ListBucketIntelligentTieringConfigurations" ActionDeleteBucketIntelligentTieringConfiguration = "s3_DeleteBucketIntelligentTieringConfiguration" + ActionPutBucketInventoryConfiguration = "s3_PutBucketInventoryConfiguration" + ActionGetBucketInventoryConfiguration = "s3_GetBucketInventoryConfiguration" + ActionListBucketInventoryConfigurations = "s3_ListBucketInventoryConfigurations" + ActionDeleteBucketInventoryConfiguration = "s3_DeleteBucketInventoryConfiguration" // Admin actions ActionAdminCreateUser = "admin_CreateUser" diff --git a/s3api/router.go b/s3api/router.go index c4ac04e6..28be6af9 100644 --- a/s3api/router.go +++ b/s3api/router.go @@ -237,6 +237,20 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ middlewares.ParseAcl(be), ), ) + bucketRouter.Put("", + middlewares.MatchQueryArgs("inventory"), + controllers.ProcessHandlers( + ctrl.HandleErrorRoute(s3err.GetAPIError(s3err.ErrNotImplemented)), + metrics.ActionPutBucketInventoryConfiguration, + services, + middlewares.BucketObjectNameValidator(), + middlewares.AuthorizePublicBucketAccess(be, metrics.ActionPutBucketInventoryConfiguration, auth.PutInventoryConfigurationAction, auth.PermissionWrite), + middlewares.VerifyPresignedV4Signature(root, iam, region, debug), + middlewares.VerifyV4Signature(root, iam, region, debug), + middlewares.VerifyMD5Body(), + middlewares.ParseAcl(be), + ), + ) bucketRouter.Put("", controllers.ProcessHandlers( ctrl.CreateBucket, @@ -358,6 +372,20 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ middlewares.ParseAcl(be), ), ) + bucketRouter.Delete("", + middlewares.MatchQueryArgs("inventory"), + controllers.ProcessHandlers( + ctrl.HandleErrorRoute(s3err.GetAPIError(s3err.ErrNotImplemented)), + metrics.ActionDeleteBucketInventoryConfiguration, + services, + middlewares.BucketObjectNameValidator(), + middlewares.AuthorizePublicBucketAccess(be, metrics.ActionDeleteBucketInventoryConfiguration, auth.PutInventoryConfigurationAction, auth.PermissionWrite), + middlewares.VerifyPresignedV4Signature(root, iam, region, debug), + middlewares.VerifyV4Signature(root, iam, region, debug), + middlewares.VerifyMD5Body(), + middlewares.ParseAcl(be), + ), + ) bucketRouter.Delete("", controllers.ProcessHandlers( ctrl.DeleteBucket, @@ -559,6 +587,34 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ middlewares.ParseAcl(be), ), ) + bucketRouter.Get("", + middlewares.MatchQueryArgs("inventory", "id"), + controllers.ProcessHandlers( + ctrl.HandleErrorRoute(s3err.GetAPIError(s3err.ErrNotImplemented)), + metrics.ActionGetBucketInventoryConfiguration, + services, + middlewares.BucketObjectNameValidator(), + middlewares.AuthorizePublicBucketAccess(be, metrics.ActionGetBucketInventoryConfiguration, auth.GetInventoryConfigurationAction, auth.PermissionRead), + middlewares.VerifyPresignedV4Signature(root, iam, region, debug), + middlewares.VerifyV4Signature(root, iam, region, debug), + middlewares.VerifyMD5Body(), + middlewares.ParseAcl(be), + ), + ) + bucketRouter.Get("", + middlewares.MatchQueryArgs("inventory"), + controllers.ProcessHandlers( + ctrl.HandleErrorRoute(s3err.GetAPIError(s3err.ErrNotImplemented)), + metrics.ActionListBucketInventoryConfigurations, + services, + middlewares.BucketObjectNameValidator(), + middlewares.AuthorizePublicBucketAccess(be, metrics.ActionListBucketInventoryConfigurations, auth.GetInventoryConfigurationAction, auth.PermissionRead), + middlewares.VerifyPresignedV4Signature(root, iam, region, debug), + middlewares.VerifyV4Signature(root, iam, region, debug), + middlewares.VerifyMD5Body(), + middlewares.ParseAcl(be), + ), + ) bucketRouter.Get("", middlewares.MatchQueryArgWithValue("list-type", "2"), controllers.ProcessHandlers( diff --git a/tests/integration/group-tests.go b/tests/integration/group-tests.go index f8aeb6f8..19fbd85f 100644 --- a/tests/integration/group-tests.go +++ b/tests/integration/group-tests.go @@ -598,6 +598,11 @@ func TestNotImplementedActions(s *S3Conf) { GetBucketIntelligentTieringConfiguration_not_implemented(s) ListBucketIntelligentTieringConfiguration_not_implemented(s) DeleteBucketIntelligentTieringConfiguration_not_implemented(s) + // bucket inventory configuration actions + PutBucketInventoryConfiguration_not_implemented(s) + GetBucketInventoryConfiguration_not_implemented(s) + ListBucketInventoryConfiguration_not_implemented(s) + DeleteBucketInventoryConfiguration_not_implemented(s) } func TestWORMProtection(s *S3Conf) { @@ -1316,6 +1321,10 @@ func GetIntTests() IntTests { "GetBucketIntelligentTieringConfiguration_not_implemented": GetBucketIntelligentTieringConfiguration_not_implemented, "ListBucketIntelligentTieringConfiguration_not_implemented": ListBucketIntelligentTieringConfiguration_not_implemented, "DeleteBucketIntelligentTieringConfiguration_not_implemented": DeleteBucketIntelligentTieringConfiguration_not_implemented, + "PutBucketInventoryConfiguration_not_implemented": PutBucketInventoryConfiguration_not_implemented, + "GetBucketInventoryConfiguration_not_implemented": GetBucketInventoryConfiguration_not_implemented, + "ListBucketInventoryConfiguration_not_implemented": ListBucketInventoryConfiguration_not_implemented, + "DeleteBucketInventoryConfiguration_not_implemented": DeleteBucketInventoryConfiguration_not_implemented, "WORMProtection_bucket_object_lock_configuration_compliance_mode": WORMProtection_bucket_object_lock_configuration_compliance_mode, "WORMProtection_bucket_object_lock_configuration_governance_mode": WORMProtection_bucket_object_lock_configuration_governance_mode, "WORMProtection_bucket_object_lock_governance_bypass_delete": WORMProtection_bucket_object_lock_governance_bypass_delete, diff --git a/tests/integration/tests.go b/tests/integration/tests.go index 1bb76c14..c70b3b13 100644 --- a/tests/integration/tests.go +++ b/tests/integration/tests.go @@ -14788,6 +14788,85 @@ func DeleteBucketIntelligentTieringConfiguration_not_implemented(s *S3Conf) erro }) } +func PutBucketInventoryConfiguration_not_implemented(s *S3Conf) error { + testName := "PutBucketInventoryConfiguration_not_implemented" + return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { + enabled := true + ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) + _, err := s3client.PutBucketInventoryConfiguration(ctx, + &s3.PutBucketInventoryConfigurationInput{ + Bucket: &bucket, + Id: getPtr("unique_id"), + InventoryConfiguration: &types.InventoryConfiguration{ + Destination: &types.InventoryDestination{ + S3BucketDestination: &types.InventoryS3BucketDestination{ + Bucket: &bucket, + Format: types.InventoryFormatCsv, + Encryption: &types.InventoryEncryption{ + SSEKMS: &types.SSEKMS{ + KeyId: getPtr("my-key-id"), + }, + }, + }, + }, + Id: getPtr("my-id"), + IncludedObjectVersions: types.InventoryIncludedObjectVersionsAll, + IsEnabled: &enabled, + Schedule: &types.InventorySchedule{ + Frequency: types.InventoryFrequencyDaily, + }, + }, + }) + cancel() + + return checkApiErr(err, s3err.GetAPIError(s3err.ErrNotImplemented)) + }) +} + +func GetBucketInventoryConfiguration_not_implemented(s *S3Conf) error { + testName := "GetBucketInventoryConfiguration_not_implemented" + return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { + ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) + _, err := s3client.GetBucketInventoryConfiguration(ctx, + &s3.GetBucketInventoryConfigurationInput{ + Bucket: &bucket, + Id: getPtr("unique_id"), + }) + cancel() + + return checkApiErr(err, s3err.GetAPIError(s3err.ErrNotImplemented)) + }) +} + +func ListBucketInventoryConfiguration_not_implemented(s *S3Conf) error { + testName := "ListBucketInventoryConfiguration_not_implemented" + return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { + ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) + _, err := s3client.ListBucketInventoryConfigurations(ctx, + &s3.ListBucketInventoryConfigurationsInput{ + Bucket: &bucket, + }) + cancel() + + return checkApiErr(err, s3err.GetAPIError(s3err.ErrNotImplemented)) + }) +} + +func DeleteBucketInventoryConfiguration_not_implemented(s *S3Conf) error { + testName := "DeleteBucketInventoryConfiguration_not_implemented" + return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { + ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) + _, err := s3client.DeleteBucketInventoryConfiguration(ctx, + &s3.DeleteBucketInventoryConfigurationInput{ + Bucket: &bucket, + Id: getPtr("unique_id"), + }) + cancel() + + return checkApiErr(err, s3err.GetAPIError(s3err.ErrNotImplemented)) + }) +} + func WORMProtection_bucket_object_lock_configuration_compliance_mode(s *S3Conf) error { testName := "WORMProtection_bucket_object_lock_configuration_compliance_mode" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {