// Copyright 2023 Versity Software // This file is licensed under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package integration import ( "context" "net/http" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/s3/types" "github.com/versity/versitygw/s3err" ) func PutBucketAcl_non_existing_bucket(s *S3Conf) error { testName := "PutBucketAcl_non_existing_bucket" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) _, err := s3client.PutBucketAcl(ctx, &s3.PutBucketAclInput{ Bucket: getPtr(getBucketName()), }) cancel() if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrNoSuchBucket)); err != nil { return err } return nil }) } func PutBucketAcl_disabled(s *S3Conf) error { testName := "PutBucketAcl_disabled" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) _, err := s3client.PutBucketAcl(ctx, &s3.PutBucketAclInput{ Bucket: &bucket, ACL: types.BucketCannedACLPublicRead, GrantRead: &s.awsID, }) cancel() if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrAclNotSupported)); err != nil { return err } return nil }) } func PutBucketAcl_none_of_the_options_specified(s *S3Conf) error { testName := "PutBucketAcl_none_of_the_options_specified" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) _, err := s3client.PutBucketAcl(ctx, &s3.PutBucketAclInput{ Bucket: &bucket, }) cancel() if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrMissingSecurityHeader)); err != nil { return err } return nil }, withOwnership(types.ObjectOwnershipBucketOwnerPreferred)) } func PutBucketAcl_invalid_canned_acl(s *S3Conf) error { testName := "PutBucketAcl_invalid_canned_acl" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) _, err := s3client.PutBucketAcl(ctx, &s3.PutBucketAclInput{ Bucket: &bucket, ACL: types.BucketCannedACL("invalid_acl"), }) cancel() // the expected error message is empty for this case // only check the error Code return checkSdkApiErr(err, "InvalidArgument") }, withOwnership(types.ObjectOwnershipBucketOwnerPreferred)) } func PutBucketAcl_invalid_acl_canned_and_acp(s *S3Conf) error { testName := "PutBucketAcl_invalid_acl_canned_and_acp" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) _, err := s3client.PutBucketAcl(ctx, &s3.PutBucketAclInput{ Bucket: &bucket, ACL: types.BucketCannedACLPrivate, GrantRead: getPtr("testuser1"), }) cancel() if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrBothCannedAndHeaderGrants)); err != nil { return err } return nil }, withOwnership(types.ObjectOwnershipBucketOwnerPreferred)) } func PutBucketAcl_invalid_acl_canned_and_grants(s *S3Conf) error { testName := "PutBucketAcl_invalid_acl_canned_and_grants" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) _, err := s3client.PutBucketAcl(ctx, &s3.PutBucketAclInput{ Bucket: &bucket, ACL: types.BucketCannedACLPrivate, AccessControlPolicy: &types.AccessControlPolicy{ Grants: []types.Grant{ { Grantee: &types.Grantee{ ID: getPtr("awsID"), Type: types.TypeCanonicalUser, }, Permission: types.PermissionFullControl, }, }, Owner: &types.Owner{ ID: &s.awsID, }, }, }) cancel() if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrUnexpectedContent)); err != nil { return err } return nil }, withOwnership(types.ObjectOwnershipBucketOwnerPreferred)) } func PutBucketAcl_invalid_acl_acp_and_grants(s *S3Conf) error { testName := "PutBucketAcl_invalid_acl_acp_and_grants" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) _, err := s3client.PutBucketAcl(ctx, &s3.PutBucketAclInput{ Bucket: &bucket, GrantFullControl: getPtr("userAccess"), AccessControlPolicy: &types.AccessControlPolicy{ Grants: []types.Grant{ { Grantee: &types.Grantee{ ID: getPtr("awsID"), Type: types.TypeCanonicalUser, }, Permission: types.PermissionFullControl, }, }, Owner: &types.Owner{ ID: &s.awsID, }, }, }) cancel() if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrUnexpectedContent)); err != nil { return err } return nil }, withOwnership(types.ObjectOwnershipBucketOwnerPreferred)) } func PutBucketAcl_invalid_owner(s *S3Conf) error { testName := "PutBucketAcl_invalid_owner" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { testuser := getUser("user") if err := createUsers(s, []user{testuser}); err != nil { return err } if err := changeBucketsOwner(s, []string{bucket}, testuser.access); err != nil { return err } userClient := s.getUserClient(testuser) ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) _, err := userClient.PutBucketAcl(ctx, &s3.PutBucketAclInput{ Bucket: &bucket, AccessControlPolicy: &types.AccessControlPolicy{ Grants: []types.Grant{ { Grantee: &types.Grantee{ ID: getPtr(testuser.access), Type: types.TypeCanonicalUser, }, Permission: types.PermissionRead, }, }, Owner: &types.Owner{ ID: getPtr("invalidOwner"), }, }, }) cancel() if err := checkApiErr(err, s3err.APIError{ Code: "InvalidArgument", Description: "Invalid id", HTTPStatusCode: http.StatusBadRequest, }); err != nil { return err } return nil }, withOwnership(types.ObjectOwnershipBucketOwnerPreferred)) } func PutBucketAcl_invalid_owner_not_in_body(s *S3Conf) error { testName := "PutBucketAcl_invalid_owner_not_in_body" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) _, err := s3client.PutBucketAcl(ctx, &s3.PutBucketAclInput{ Bucket: &bucket, AccessControlPolicy: &types.AccessControlPolicy{ Grants: []types.Grant{ { Grantee: &types.Grantee{ Type: types.TypeCanonicalUser, ID: getPtr("grt1"), }, Permission: types.PermissionRead, }, }, }, }) cancel() if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrMalformedACL)); err != nil { return err } return nil }, withOwnership(types.ObjectOwnershipBucketOwnerPreferred)) } func PutBucketAcl_invalid_empty_owner_id_in_body(s *S3Conf) error { testName := "PutBucketAcl_invalid_empty_owner_id_in_body" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) _, err := s3client.PutBucketAcl(ctx, &s3.PutBucketAclInput{ Bucket: &bucket, AccessControlPolicy: &types.AccessControlPolicy{ Grants: []types.Grant{ { Grantee: &types.Grantee{ Type: types.TypeCanonicalUser, ID: getPtr("grt1"), }, Permission: types.PermissionRead, }, }, // Empty owner ID Owner: &types.Owner{}, }, }) cancel() if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrMalformedACL)); err != nil { return err } return nil }, withOwnership(types.ObjectOwnershipBucketOwnerPreferred)) } func PutBucketAcl_invalid_permission_in_body(s *S3Conf) error { testName := "PutBucketAcl_invalid_permission_in_body" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) _, err := s3client.PutBucketAcl(ctx, &s3.PutBucketAclInput{ Bucket: &bucket, AccessControlPolicy: &types.AccessControlPolicy{ Grants: []types.Grant{ { Grantee: &types.Grantee{ Type: types.TypeCanonicalUser, ID: getPtr("grt1"), }, Permission: types.Permission("invalid_permission"), }, }, Owner: &types.Owner{ ID: &s.awsID, }, }, }) cancel() if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrMalformedACL)); err != nil { return err } return nil }, withOwnership(types.ObjectOwnershipBucketOwnerPreferred)) } func PutBucketAcl_invalid_grantee_type_in_body(s *S3Conf) error { testName := "PutBucketAcl_invalid_grantee_type_in_body" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) _, err := s3client.PutBucketAcl(ctx, &s3.PutBucketAclInput{ Bucket: &bucket, AccessControlPolicy: &types.AccessControlPolicy{ Grants: []types.Grant{ { Grantee: &types.Grantee{ Type: types.Type("invalid_type"), ID: getPtr("grt1"), }, Permission: types.PermissionRead, }, }, Owner: &types.Owner{ ID: &s.awsID, }, }, }) cancel() if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrMalformedACL)); err != nil { return err } return nil }, withOwnership(types.ObjectOwnershipBucketOwnerPreferred)) } func PutBucketAcl_empty_grantee_ID_in_body(s *S3Conf) error { testName := "PutBucketAcl_empty_grantee_ID_in_body" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) _, err := s3client.PutBucketAcl(ctx, &s3.PutBucketAclInput{ Bucket: &bucket, AccessControlPolicy: &types.AccessControlPolicy{ Grants: []types.Grant{ { Grantee: &types.Grantee{ Type: types.TypeCanonicalUser, }, Permission: types.PermissionRead, }, }, Owner: &types.Owner{ ID: &s.awsID, }, }, }) cancel() if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrMalformedACL)); err != nil { return err } return nil }, withOwnership(types.ObjectOwnershipBucketOwnerPreferred)) } func PutBucketAcl_success_access_denied(s *S3Conf) error { testName := "PutBucketAcl_success_access_denied" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { testuser := getUser("user") err := createUsers(s, []user{testuser}) if err != nil { return err } ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) _, err = s3client.PutBucketAcl(ctx, &s3.PutBucketAclInput{ Bucket: &bucket, AccessControlPolicy: &types.AccessControlPolicy{ Grants: []types.Grant{ { Grantee: &types.Grantee{ ID: getPtr(testuser.access), Type: types.TypeCanonicalUser, }, Permission: types.PermissionRead, }, }, Owner: &types.Owner{ ID: &s.awsID, }, }, }) cancel() if err != nil { return err } userClient := s.getUserClient(testuser) _, err = putObjects(userClient, []string{"my-obj"}, bucket) if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrAccessDenied)); err != nil { return err } return nil }, withOwnership(types.ObjectOwnershipBucketOwnerPreferred)) } func PutBucketAcl_success_canned_acl(s *S3Conf) error { testName := "PutBucketAcl_success_canned_acl" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { testuser := getUser("user") err := createUsers(s, []user{testuser}) if err != nil { return err } ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) _, err = s3client.PutBucketAcl(ctx, &s3.PutBucketAclInput{ Bucket: &bucket, ACL: types.BucketCannedACLPublicReadWrite, }) cancel() if err != nil { return err } userClient := s.getUserClient(testuser) _, err = putObjects(userClient, []string{"my-obj"}, bucket) if err != nil { return err } return nil }, withOwnership(types.ObjectOwnershipBucketOwnerPreferred)) } func PutBucketAcl_success_acp(s *S3Conf) error { testName := "PutBucketAcl_success_acp" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { testuser := getUser("user") err := createUsers(s, []user{testuser}) if err != nil { return err } ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) _, err = s3client.PutBucketAcl(ctx, &s3.PutBucketAclInput{ Bucket: &bucket, GrantRead: &testuser.access, }) cancel() if err != nil { return err } userClient := s.getUserClient(testuser) _, err = putObjects(userClient, []string{"my-obj"}, bucket) if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrAccessDenied)); err != nil { return err } ctx, cancel = context.WithTimeout(context.Background(), shortTimeout) _, err = userClient.HeadBucket(ctx, &s3.HeadBucketInput{ Bucket: &bucket, }) cancel() if err != nil { return err } return nil }, withOwnership(types.ObjectOwnershipBucketOwnerPreferred)) } func PutBucketAcl_success_grants(s *S3Conf) error { testName := "PutBucketAcl_success_grants" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { testuser := getUser("user") err := createUsers(s, []user{testuser}) if err != nil { return err } ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) _, err = s3client.PutBucketAcl(ctx, &s3.PutBucketAclInput{ Bucket: &bucket, AccessControlPolicy: &types.AccessControlPolicy{ Grants: []types.Grant{ { Grantee: &types.Grantee{ ID: &testuser.access, Type: types.TypeCanonicalUser, }, Permission: types.PermissionFullControl, }, }, Owner: &types.Owner{ ID: &s.awsID, }, }, }) cancel() if err != nil { return err } userClient := s.getUserClient(testuser) _, err = putObjects(userClient, []string{"my-obj"}, bucket) if err != nil { return err } return nil }, withOwnership(types.ObjectOwnershipBucketOwnerPreferred)) }