diff --git a/auth/bucket_policy_actions.go b/auth/bucket_policy_actions.go index 35b5d99..ad49200 100644 --- a/auth/bucket_policy_actions.go +++ b/auth/bucket_policy_actions.go @@ -60,6 +60,8 @@ const ( GetBucketOwnershipControlsAction Action = "s3:GetBucketOwnershipControls" PutBucketCorsAction Action = "s3:PutBucketCORS" GetBucketCorsAction Action = "s3:GetBucketCORS" + PutAnalyticsConfiguration Action = "s3:PutAnalyticsConfiguration" + GetAnalyticsConfiguration Action = "s3:GetAnalyticsConfiguration" AllActions Action = "s3:*" ) diff --git a/metrics/actions.go b/metrics/actions.go index 683ca90..d5fc974 100644 --- a/metrics/actions.go +++ b/metrics/actions.go @@ -24,57 +24,61 @@ var ( ) var ( - ActionUndetected = "ActionUnDetected" - ActionAbortMultipartUpload = "s3_AbortMultipartUpload" - ActionCompleteMultipartUpload = "s3_CompleteMultipartUpload" - ActionCopyObject = "s3_CopyObject" - ActionCreateBucket = "s3_CreateBucket" - ActionCreateMultipartUpload = "s3_CreateMultipartUpload" - ActionDeleteBucket = "s3_DeleteBucket" - ActionDeleteBucketPolicy = "s3_DeleteBucketPolicy" - ActionDeleteBucketTagging = "s3_DeleteBucketTagging" - ActionDeleteObject = "s3_DeleteObject" - ActionDeleteObjectTagging = "s3_DeleteObjectTagging" - ActionDeleteObjects = "s3_DeleteObjects" - ActionGetBucketAcl = "s3_GetBucketAcl" - ActionGetBucketPolicy = "s3_GetBucketPolicy" - ActionGetBucketTagging = "s3_GetBucketTagging" - ActionGetBucketVersioning = "s3_GetBucketVersioning" - ActionGetObject = "s3_GetObject" - ActionGetObjectAcl = "s3_GetObjectAcl" - ActionGetObjectAttributes = "s3_GetObjectAttributes" - ActionGetObjectLegalHold = "s3_GetObjectLegalHold" - ActionGetObjectLockConfiguration = "s3_GetObjectLockConfiguration" - ActionGetObjectRetention = "s3_GetObjectRetention" - ActionGetObjectTagging = "s3_GetObjectTagging" - ActionHeadBucket = "s3_HeadBucket" - ActionHeadObject = "s3_HeadObject" - ActionListAllMyBuckets = "s3_ListAllMyBuckets" - ActionListMultipartUploads = "s3_ListMultipartUploads" - ActionListObjectVersions = "s3_ListObjectVersions" - ActionListObjects = "s3_ListObjects" - ActionListObjectsV2 = "s3_ListObjectsV2" - ActionListParts = "s3_ListParts" - ActionPutBucketAcl = "s3_PutBucketAcl" - ActionPutBucketPolicy = "s3_PutBucketPolicy" - ActionPutBucketTagging = "s3_PutBucketTagging" - ActionPutBucketVersioning = "s3_PutBucketVersioning" - ActionPutObject = "s3_PutObject" - ActionPutObjectAcl = "s3_PutObjectAcl" - ActionPutObjectLegalHold = "s3_PutObjectLegalHold" - ActionPutObjectLockConfiguration = "s3_PutObjectLockConfiguration" - ActionPutObjectRetention = "s3_PutObjectRetention" - ActionPutObjectTagging = "s3_PutObjectTagging" - ActionRestoreObject = "s3_RestoreObject" - ActionSelectObjectContent = "s3_SelectObjectContent" - ActionUploadPart = "s3_UploadPart" - ActionUploadPartCopy = "s3_UploadPartCopy" - ActionPutBucketOwnershipControls = "s3_PutBucketOwnershipControls" - ActionGetBucketOwnershipControls = "s3_GetBucketOwnershipControls" - ActionDeleteBucketOwnershipControls = "s3_DeleteBucketOwnershipControls" - ActionPutBucketCors = "s3_PutBucketCors" - ActionGetBucketCors = "s3_GetBucketCors" - ActionDeleteBucketCors = "s3_DeleteBucketCors" + ActionUndetected = "ActionUnDetected" + ActionAbortMultipartUpload = "s3_AbortMultipartUpload" + ActionCompleteMultipartUpload = "s3_CompleteMultipartUpload" + ActionCopyObject = "s3_CopyObject" + ActionCreateBucket = "s3_CreateBucket" + ActionCreateMultipartUpload = "s3_CreateMultipartUpload" + ActionDeleteBucket = "s3_DeleteBucket" + ActionDeleteBucketPolicy = "s3_DeleteBucketPolicy" + ActionDeleteBucketTagging = "s3_DeleteBucketTagging" + ActionDeleteObject = "s3_DeleteObject" + ActionDeleteObjectTagging = "s3_DeleteObjectTagging" + ActionDeleteObjects = "s3_DeleteObjects" + ActionGetBucketAcl = "s3_GetBucketAcl" + ActionGetBucketPolicy = "s3_GetBucketPolicy" + ActionGetBucketTagging = "s3_GetBucketTagging" + ActionGetBucketVersioning = "s3_GetBucketVersioning" + ActionGetObject = "s3_GetObject" + ActionGetObjectAcl = "s3_GetObjectAcl" + ActionGetObjectAttributes = "s3_GetObjectAttributes" + ActionGetObjectLegalHold = "s3_GetObjectLegalHold" + ActionGetObjectLockConfiguration = "s3_GetObjectLockConfiguration" + ActionGetObjectRetention = "s3_GetObjectRetention" + ActionGetObjectTagging = "s3_GetObjectTagging" + ActionHeadBucket = "s3_HeadBucket" + ActionHeadObject = "s3_HeadObject" + ActionListAllMyBuckets = "s3_ListAllMyBuckets" + ActionListMultipartUploads = "s3_ListMultipartUploads" + ActionListObjectVersions = "s3_ListObjectVersions" + ActionListObjects = "s3_ListObjects" + ActionListObjectsV2 = "s3_ListObjectsV2" + ActionListParts = "s3_ListParts" + ActionPutBucketAcl = "s3_PutBucketAcl" + ActionPutBucketPolicy = "s3_PutBucketPolicy" + ActionPutBucketTagging = "s3_PutBucketTagging" + ActionPutBucketVersioning = "s3_PutBucketVersioning" + ActionPutObject = "s3_PutObject" + ActionPutObjectAcl = "s3_PutObjectAcl" + ActionPutObjectLegalHold = "s3_PutObjectLegalHold" + ActionPutObjectLockConfiguration = "s3_PutObjectLockConfiguration" + ActionPutObjectRetention = "s3_PutObjectRetention" + ActionPutObjectTagging = "s3_PutObjectTagging" + ActionRestoreObject = "s3_RestoreObject" + ActionSelectObjectContent = "s3_SelectObjectContent" + ActionUploadPart = "s3_UploadPart" + ActionUploadPartCopy = "s3_UploadPartCopy" + ActionPutBucketOwnershipControls = "s3_PutBucketOwnershipControls" + ActionGetBucketOwnershipControls = "s3_GetBucketOwnershipControls" + ActionDeleteBucketOwnershipControls = "s3_DeleteBucketOwnershipControls" + ActionPutBucketCors = "s3_PutBucketCors" + ActionGetBucketCors = "s3_GetBucketCors" + ActionDeleteBucketCors = "s3_DeleteBucketCors" + ActionPutBucketAnalyticsConfiguration = "s3_PutBucketAnalyticsConfiguration" + ActionGetBucketAnalyticsConfiguration = "s3_GetBucketAnalyticsConfiguration" + ActionListBucketAnalyticsConfigurations = "s3_ListBucketAnalyticsConfigurations" + ActionDeleteBucketAnalyticsConfiguration = "s3_DeleteBucketAnalyticsConfiguration" // Admin actions ActionAdminCreateUser = "admin_CreateUser" diff --git a/s3api/router.go b/s3api/router.go index c0694b3..59bf396 100644 --- a/s3api/router.go +++ b/s3api/router.go @@ -195,6 +195,20 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ middlewares.VerifyMD5Body(), middlewares.ParseAcl(be), )) + bucketRouter.Put("", + middlewares.MatchQueryArgs("analytics"), + controllers.ProcessHandlers( + ctrl.HandleErrorRoute(s3err.GetAPIError(s3err.ErrNotImplemented)), + metrics.ActionPutBucketAnalyticsConfiguration, + services, + middlewares.BucketObjectNameValidator(), + middlewares.AuthorizePublicBucketAccess(be, metrics.ActionPutBucketAnalyticsConfiguration, auth.PutAnalyticsConfiguration, 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, @@ -274,6 +288,20 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ middlewares.VerifyMD5Body(), middlewares.ParseAcl(be), )) + bucketRouter.Delete("", + middlewares.MatchQueryArgs("analytics"), + controllers.ProcessHandlers( + ctrl.HandleErrorRoute(s3err.GetAPIError(s3err.ErrNotImplemented)), + metrics.ActionDeleteBucketAnalyticsConfiguration, + services, + middlewares.BucketObjectNameValidator(), + middlewares.AuthorizePublicBucketAccess(be, metrics.ActionDeleteBucketAnalyticsConfiguration, auth.PutAnalyticsConfiguration, 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, @@ -405,6 +433,34 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ middlewares.VerifyMD5Body(), middlewares.ParseAcl(be), )) + bucketRouter.Get("", + middlewares.MatchQueryArgs("analytics", "id"), + controllers.ProcessHandlers( + ctrl.HandleErrorRoute(s3err.GetAPIError(s3err.ErrNotImplemented)), + metrics.ActionGetBucketAnalyticsConfiguration, + services, + middlewares.BucketObjectNameValidator(), + middlewares.AuthorizePublicBucketAccess(be, metrics.ActionGetBucketAnalyticsConfiguration, auth.GetAnalyticsConfiguration, auth.PermissionRead), + middlewares.VerifyPresignedV4Signature(root, iam, region, debug), + middlewares.VerifyV4Signature(root, iam, region, debug), + middlewares.VerifyMD5Body(), + middlewares.ParseAcl(be), + ), + ) + bucketRouter.Get("", + middlewares.MatchQueryArgs("analytics"), + controllers.ProcessHandlers( + ctrl.HandleErrorRoute(s3err.GetAPIError(s3err.ErrNotImplemented)), + metrics.ActionListBucketAnalyticsConfigurations, + services, + middlewares.BucketObjectNameValidator(), + middlewares.AuthorizePublicBucketAccess(be, metrics.ActionListBucketAnalyticsConfigurations, auth.GetAnalyticsConfiguration, 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 6cd36124..9eb1137 100644 --- a/tests/integration/group-tests.go +++ b/tests/integration/group-tests.go @@ -583,6 +583,13 @@ func TestGetObjectLegalHold(s *S3Conf) { GetObjectLegalHold_success(s) } +func TestNotImplementedActions(s *S3Conf) { + PutBucketAnalyticsConfiguration_not_implemented(s) + GetBucketAnalyticsConfiguration_not_implemented(s) + ListBucketAnalyticsConfiguration_not_implemented(s) + DeleteBucketAnalyticsConfiguration_not_implemented(s) +} + func TestWORMProtection(s *S3Conf) { WORMProtection_bucket_object_lock_configuration_compliance_mode(s) WORMProtection_bucket_object_lock_configuration_governance_mode(s) @@ -1288,6 +1295,10 @@ func GetIntTests() IntTests { "GetObjectLegalHold_disabled_lock": GetObjectLegalHold_disabled_lock, "GetObjectLegalHold_unset_config": GetObjectLegalHold_unset_config, "GetObjectLegalHold_success": GetObjectLegalHold_success, + "PutBucketAnalyticsConfiguration_not_implemented": PutBucketAnalyticsConfiguration_not_implemented, + "GetBucketAnalyticsConfiguration_not_implemented": GetBucketAnalyticsConfiguration_not_implemented, + "ListBucketAnalyticsConfiguration_not_implemented": ListBucketAnalyticsConfiguration_not_implemented, + "DeleteBucketAnalyticsConfiguration_not_implemented": DeleteBucketAnalyticsConfiguration_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 6c18c43..beccf4f 100644 --- a/tests/integration/tests.go +++ b/tests/integration/tests.go @@ -14594,6 +14594,79 @@ func GetObjectLegalHold_success(s *S3Conf) error { }, withLock()) } +func PutBucketAnalyticsConfiguration_not_implemented(s *S3Conf) error { + testName := "PutBucketAnalyticsConfiguration_not_implemented" + return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { + ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) + _, err := s3client.PutBucketAnalyticsConfiguration(ctx, + &s3.PutBucketAnalyticsConfigurationInput{ + Bucket: &bucket, + Id: getPtr("uniquie_id"), + AnalyticsConfiguration: &types.AnalyticsConfiguration{ + Id: getPtr("my-id"), + StorageClassAnalysis: &types.StorageClassAnalysis{ + DataExport: &types.StorageClassAnalysisDataExport{ + OutputSchemaVersion: types.StorageClassAnalysisSchemaVersionV1, + Destination: &types.AnalyticsExportDestination{ + S3BucketDestination: &types.AnalyticsS3BucketDestination{ + Bucket: &bucket, + Format: types.AnalyticsS3ExportFileFormatCsv, + }, + }, + }, + }, + }, + }) + cancel() + + return checkApiErr(err, s3err.GetAPIError(s3err.ErrNotImplemented)) + }) +} + +func GetBucketAnalyticsConfiguration_not_implemented(s *S3Conf) error { + testName := "GetBucketAnalyticsConfiguration_not_implemented" + return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { + ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) + _, err := s3client.GetBucketAnalyticsConfiguration(ctx, + &s3.GetBucketAnalyticsConfigurationInput{ + Bucket: &bucket, + Id: getPtr("uniquie_id"), + }) + cancel() + + return checkApiErr(err, s3err.GetAPIError(s3err.ErrNotImplemented)) + }) +} + +func ListBucketAnalyticsConfiguration_not_implemented(s *S3Conf) error { + testName := "ListBucketAnalyticsConfiguration_not_implemented" + return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { + ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) + _, err := s3client.ListBucketAnalyticsConfigurations(ctx, + &s3.ListBucketAnalyticsConfigurationsInput{ + Bucket: &bucket, + }) + cancel() + + return checkApiErr(err, s3err.GetAPIError(s3err.ErrNotImplemented)) + }) +} + +func DeleteBucketAnalyticsConfiguration_not_implemented(s *S3Conf) error { + testName := "DeleteBucketAnalyticsConfiguration_not_implemented" + return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { + ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) + _, err := s3client.DeleteBucketAnalyticsConfiguration(ctx, + &s3.DeleteBucketAnalyticsConfigurationInput{ + Bucket: &bucket, + Id: getPtr("uniquie_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 {