feat: Implemented logic to add bucket ACL on bucket creation

This commit is contained in:
jonaustin09
2024-01-26 03:54:19 -05:00
committed by Ben McClelland
parent 99d0d9a007
commit 0d3a238ceb
4 changed files with 133 additions and 10 deletions

View File

@@ -268,11 +268,9 @@ func getAction(tf testFunc) func(*cli.Context) error {
func extractIntTests() (commands []*cli.Command) {
tests := integration.GetIntTests()
for key, val := range tests {
testKey := key
testFunc := val
commands = append(commands, &cli.Command{
Name: testKey,
Usage: fmt.Sprintf("Runs %v integration test", testKey),
Name: key,
Usage: fmt.Sprintf("Runs %v integration test", key),
Action: func(ctx *cli.Context) error {
opts := []integration.Option{
integration.WithAccess(awsID),
@@ -285,7 +283,7 @@ func extractIntTests() (commands []*cli.Command) {
}
s := integration.NewS3Conf(opts...)
err := testFunc(s)
err := val(s)
return err
},
})

View File

@@ -26,6 +26,8 @@ func TestCreateBucket(s *S3Conf) {
CreateBucket_invalid_bucket_name(s)
CreateBucket_existing_bucket(s)
CreateBucket_as_user(s)
CreateBucket_default_acl(s)
CreateBucket_non_default_acl(s)
CreateDeleteBucket_success(s)
}
@@ -251,6 +253,8 @@ func GetIntTests() IntTests {
"CreateBucket_existing_bucket": CreateBucket_existing_bucket,
"CreateBucket_as_user": CreateBucket_as_user,
"CreateDeleteBucket_success": CreateDeleteBucket_success,
"CreateBucket_default_acl": CreateBucket_default_acl,
"CreateBucket_non_default_acl": CreateBucket_non_default_acl,
"HeadBucket_non_existing_bucket": HeadBucket_non_existing_bucket,
"HeadBucket_success": HeadBucket_success,
"ListBuckets_as_user": ListBuckets_as_user,
@@ -263,7 +267,6 @@ func GetIntTests() IntTests {
"PutObject_special_chars": PutObject_special_chars,
"PutObject_invalid_long_tags": PutObject_invalid_long_tags,
"PutObject_success": PutObject_success,
"PutObject_invalid_credentials": PutObject_invalid_credentials,
"HeadObject_non_existing_object": HeadObject_non_existing_object,
"HeadObject_success": HeadObject_success,
"GetObject_non_existing_key": GetObject_non_existing_key,

View File

@@ -706,6 +706,116 @@ func CreateBucket_existing_bucket(s *S3Conf) error {
return nil
}
func CreateBucket_default_acl(s *S3Conf) error {
testName := "CreateBucket_default_acl"
runF(testName)
bucket := getBucketName()
client := s3.NewFromConfig(s.Config())
err := setup(s, bucket)
if err != nil {
failF("%v: %v", testName, err)
return fmt.Errorf("%v: %w", testName, err)
}
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
out, err := client.GetBucketAcl(ctx, &s3.GetBucketAclInput{Bucket: &bucket})
cancel()
if err != nil {
failF("%v: %v", testName, err)
return fmt.Errorf("%v: %w", testName, err)
}
if *out.Owner.ID != s.awsID {
failF("%v: expected bucket owner to be %v, instead got %v", testName, s.awsID, *out.Owner.ID)
return fmt.Errorf("%v: expected bucket owner to be %v, instead got %v", testName, s.awsID, *out.Owner.ID)
}
if len(out.Grants) != 0 {
failF("%v: expected grants to be empty instead got %v", testName, len(out.Grants))
return fmt.Errorf("%v: expected grants to be empty instead got %v", testName, len(out.Grants))
}
err = teardown(s, bucket)
if err != nil {
failF("%v: %v", err)
return fmt.Errorf("%v: %w", testName, err)
}
passF(testName)
return nil
}
func CreateBucket_non_default_acl(s *S3Conf) error {
testName := "CreateBucket_non_default_acl"
runF(testName)
err := createUsers(s, []user{
{"grt1", "grt1secret", "user"},
{"grt2", "grt2secret", "user"},
{"grt3", "grt3secret", "user"},
})
if err != nil {
failF("%v: %v", err)
return fmt.Errorf("%v: %w", testName, err)
}
grants := []types.Grant{
{
Grantee: &types.Grantee{
ID: getPtr("grt1"),
},
Permission: types.PermissionFullControl,
},
{
Grantee: &types.Grantee{
ID: getPtr("grt2"),
},
Permission: types.PermissionReadAcp,
},
{
Grantee: &types.Grantee{
ID: getPtr("grt3"),
},
Permission: types.PermissionWrite,
},
}
bucket := getBucketName()
client := s3.NewFromConfig(s.Config())
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
_, err = client.CreateBucket(ctx, &s3.CreateBucketInput{Bucket: &bucket, GrantFullControl: getPtr("grt1"), GrantReadACP: getPtr("grt2"), GrantWrite: getPtr("grt3")})
cancel()
if err != nil {
failF("%v: %v", err)
return fmt.Errorf("%v: %w", testName, err)
}
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
out, err := client.GetBucketAcl(ctx, &s3.GetBucketAclInput{Bucket: &bucket})
cancel()
if err != nil {
failF("%v: %v", testName, err)
return fmt.Errorf("%v: %w", testName, err)
}
if !compareGrants(out.Grants, grants) {
failF("%v: expected bucket acl grants to be %v, instead got %v", testName, grants, out.Grants)
return fmt.Errorf("%v: expected bucket acl grants to be %v, instead got %v", testName, grants, out.Grants)
}
err = teardown(s, bucket)
if err != nil {
failF("%v: %v", err)
return fmt.Errorf("%v: %w", testName, err)
}
passF(testName)
return nil
}
func HeadBucket_non_existing_bucket(s *S3Conf) error {
testName := "HeadBucket_non_existing_bucket"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {

View File

@@ -16,7 +16,6 @@ package controllers
import (
"bytes"
"encoding/json"
"encoding/xml"
"errors"
"fmt"
@@ -408,16 +407,29 @@ func (c S3ApiController) PutBucketActions(ctx *fiber.Ctx) error {
return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidBucketName), &MetaOpts{Logger: c.logger, Action: "CreateBucket"})
}
if acl != "" && grants != "" {
return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), &MetaOpts{Logger: c.logger, Action: "PutBucketAcl", BucketOwner: acct.Access})
}
defACL := auth.ACL{ACL: "private", Owner: acct.Access, Grantees: []auth.Grantee{}}
jsonACL, err := json.Marshal(defACL)
updAcl, err := auth.UpdateACL(&s3.PutBucketAclInput{
GrantFullControl: &grantFullControl,
GrantRead: &grantRead,
GrantReadACP: &grantReadACP,
GrantWrite: &granWrite,
GrantWriteACP: &grantWriteACP,
AccessControlPolicy: &types.AccessControlPolicy{Owner: &types.Owner{ID: &acct.Access}},
ACL: types.BucketCannedACL(acl),
}, defACL, c.iam)
if err != nil {
return SendResponse(ctx, fmt.Errorf("marshal acl: %w", err), &MetaOpts{Logger: c.logger, Action: "CreateBucket", BucketOwner: acct.Access})
return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "CreateBucket", BucketOwner: acct.Access})
}
err = c.be.CreateBucket(ctx.Context(), &s3.CreateBucketInput{
Bucket: &bucket,
ObjectOwnership: types.ObjectOwnership(acct.Access),
}, jsonACL)
}, updAcl)
return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "CreateBucket", BucketOwner: acct.Access})
}