From be79fc249d33cae7245fda7c9f88b114e5f91ad9 Mon Sep 17 00:00:00 2001 From: niksis02 Date: Thu, 21 Aug 2025 20:10:29 +0400 Subject: [PATCH] feat: adds not implemented routes for bucket public access block actions Closes #1451 Adds `NotImplemented` routes for bucket public access block S3 actions: - `PutPublicAccessBlock` - `GetPublicAccessBlock` - `DeletePublicAccessBlock` --- auth/bucket_policy_actions.go | 4 +++ metrics/actions.go | 15 +++++++++++ s3api/router.go | 42 +++++++++++++++++++++++++++++ tests/integration/group-tests.go | 7 +++++ tests/integration/tests.go | 45 ++++++++++++++++++++++++++++++++ 5 files changed, 113 insertions(+) diff --git a/auth/bucket_policy_actions.go b/auth/bucket_policy_actions.go index 5d9694c..13a8eec 100644 --- a/auth/bucket_policy_actions.go +++ b/auth/bucket_policy_actions.go @@ -78,6 +78,8 @@ const ( GetMetricsConfigurationAction Action = "s3:GetMetricsConfiguration" PutReplicationConfigurationAction Action = "s3:PutReplicationConfiguration" GetReplicationConfigurationAction Action = "s3:GetReplicationConfiguration" + PutBucketPublicAccessBlockAction Action = "s3:PutBucketPublicAccessBlock" + GetBucketPublicAccessBlockAction Action = "s3:GetBucketPublicAccessBlock" AllActions Action = "s3:*" ) @@ -139,6 +141,8 @@ var supportedActionList = map[Action]struct{}{ GetMetricsConfigurationAction: {}, PutReplicationConfigurationAction: {}, GetReplicationConfigurationAction: {}, + PutBucketPublicAccessBlockAction: {}, + GetBucketPublicAccessBlockAction: {}, AllActions: {}, } diff --git a/metrics/actions.go b/metrics/actions.go index 82ed7a6..20f7ab1 100644 --- a/metrics/actions.go +++ b/metrics/actions.go @@ -105,6 +105,9 @@ var ( ActionPutBucketReplication = "s3_PutBucketReplication" ActionGetBucketReplication = "s3_GetBucketReplication" ActionDeleteBucketReplication = "s3_DeleteBucketReplication" + ActionPutPublicAccessBlock = "s3_PutPublicAccessBlock" + ActionGetPublicAccessBlock = "s3_GetPublicAccessBlock" + ActionDeletePublicAccessBlock = "s3_DeletePublicAccessBlock" // Admin actions ActionAdminCreateUser = "admin_CreateUser" @@ -443,4 +446,16 @@ func init() { Name: "DeleteBucketReplication", Service: "s3", } + ActionMap[ActionPutPublicAccessBlock] = Action{ + Name: "PutPublicAccessBlock", + Service: "s3", + } + ActionMap[ActionGetPublicAccessBlock] = Action{ + Name: "GetPublicAccessBlock", + Service: "s3", + } + ActionMap[ActionDeletePublicAccessBlock] = Action{ + Name: "DeletePublicAccessBlock", + Service: "s3", + } } diff --git a/s3api/router.go b/s3api/router.go index a7a9c0c..d01fa44 100644 --- a/s3api/router.go +++ b/s3api/router.go @@ -328,6 +328,20 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ middlewares.ParseAcl(be), ), ) + bucketRouter.Put("", + middlewares.MatchQueryArgs("publicAccessBlock"), + controllers.ProcessHandlers( + ctrl.HandleErrorRoute(s3err.GetAPIError(s3err.ErrNotImplemented)), + metrics.ActionPutPublicAccessBlock, + services, + middlewares.BucketObjectNameValidator(), + middlewares.AuthorizePublicBucketAccess(be, metrics.ActionPutPublicAccessBlock, auth.PutBucketPublicAccessBlockAction, 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, @@ -512,6 +526,20 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ middlewares.ParseAcl(be), ), ) + bucketRouter.Delete("", + middlewares.MatchQueryArgs("publicAccessBlock"), + controllers.ProcessHandlers( + ctrl.HandleErrorRoute(s3err.GetAPIError(s3err.ErrNotImplemented)), + metrics.ActionDeletePublicAccessBlock, + services, + middlewares.BucketObjectNameValidator(), + middlewares.AuthorizePublicBucketAccess(be, metrics.ActionDeletePublicAccessBlock, auth.PutBucketPublicAccessBlockAction, 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, @@ -835,6 +863,20 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ middlewares.ParseAcl(be), ), ) + bucketRouter.Get("", + middlewares.MatchQueryArgs("publicAccessBlock"), + controllers.ProcessHandlers( + ctrl.HandleErrorRoute(s3err.GetAPIError(s3err.ErrNotImplemented)), + metrics.ActionGetPublicAccessBlock, + services, + middlewares.BucketObjectNameValidator(), + middlewares.AuthorizePublicBucketAccess(be, metrics.ActionGetPublicAccessBlock, auth.GetBucketPublicAccessBlockAction, 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 eb8bbc1..eee9e4d 100644 --- a/tests/integration/group-tests.go +++ b/tests/integration/group-tests.go @@ -659,6 +659,10 @@ func TestNotImplementedActions(s *S3Conf) { PutBucketReplication_not_implemented(s) GetBucketReplication_not_implemented(s) DeleteBucketReplication_not_implemented(s) + // bucket public access block actions + PutPublicAccessBlock_not_implemented(s) + GetPublicAccessBlock_not_implemented(s) + DeletePublicAccessBlock_not_implemented(s) } func TestWORMProtection(s *S3Conf) { @@ -1421,6 +1425,9 @@ func GetIntTests() IntTests { "PutBucketReplication_not_implemented": PutBucketReplication_not_implemented, "GetBucketReplication_not_implemented": GetBucketReplication_not_implemented, "DeleteBucketReplication_not_implemented": DeleteBucketReplication_not_implemented, + "PutPublicAccessBlock_not_implemented": PutPublicAccessBlock_not_implemented, + "GetPublicAccessBlock_not_implemented": GetPublicAccessBlock_not_implemented, + "DeletePublicAccessBlock_not_implemented": DeletePublicAccessBlock_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 d8c8e9e..df9e46e 100644 --- a/tests/integration/tests.go +++ b/tests/integration/tests.go @@ -15889,6 +15889,51 @@ func DeleteBucketReplication_not_implemented(s *S3Conf) error { }) } +func PutPublicAccessBlock_not_implemented(s *S3Conf) error { + testName := "PutPublicAccessBlock_not_implemented" + return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { + ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) + _, err := s3client.PutPublicAccessBlock(ctx, + &s3.PutPublicAccessBlockInput{ + Bucket: &bucket, + PublicAccessBlockConfiguration: &types.PublicAccessBlockConfiguration{ + BlockPublicPolicy: getPtr(true), + }, + }) + cancel() + + return checkApiErr(err, s3err.GetAPIError(s3err.ErrNotImplemented)) + }) +} + +func GetPublicAccessBlock_not_implemented(s *S3Conf) error { + testName := "GetPublicAccessBlock_not_implemented" + return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { + ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) + _, err := s3client.GetPublicAccessBlock(ctx, + &s3.GetPublicAccessBlockInput{ + Bucket: &bucket, + }) + cancel() + + return checkApiErr(err, s3err.GetAPIError(s3err.ErrNotImplemented)) + }) +} + +func DeletePublicAccessBlock_not_implemented(s *S3Conf) error { + testName := "DeletePublicAccessBlock_not_implemented" + return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { + ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) + _, err := s3client.DeletePublicAccessBlock(ctx, + &s3.DeletePublicAccessBlockInput{ + Bucket: &bucket, + }) + 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 {