Upstream versity/versitygw state of the touched files before 3d4c24e2e1
This commit is contained in:
1 parent
deab0fc412
commit
3fee7f49c9
4 files changed
+1787
No files matched your search
@@ -0,0 +1,663 @@
|
||||
// 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"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"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 CreateBucket_invalid_bucket_name(s *S3Conf) error {
|
||||
testName := "CreateBucket_invalid_bucket_name"
|
||||
runF(testName)
|
||||
err := setup(s, "aa")
|
||||
if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrInvalidBucketName)); err != nil {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
|
||||
err = setup(s, ".gitignore")
|
||||
if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrInvalidBucketName)); err != nil {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
|
||||
err = setup(s, "my-bucket.")
|
||||
if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrInvalidBucketName)); err != nil {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
|
||||
err = setup(s, "bucket-%")
|
||||
if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrInvalidBucketName)); err != nil {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
passF(testName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateBucket_as_user(s *S3Conf) error {
|
||||
testName := "CreateBucket_as_user"
|
||||
runF(testName)
|
||||
|
||||
testuser := getUser("user")
|
||||
cfg := *s
|
||||
cfg.awsID = testuser.access
|
||||
cfg.awsSecret = testuser.secret
|
||||
err := createUsers(s, []user{testuser})
|
||||
if err != nil {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
|
||||
err = setup(&cfg, getBucketName())
|
||||
if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrAccessDenied)); err != nil {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
|
||||
passF(testName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateBucket_existing_bucket(s *S3Conf) error {
|
||||
testName := "CreateBucket_existing_bucket"
|
||||
runF(testName)
|
||||
bucket := getBucketName()
|
||||
adminUser := getUser("admin")
|
||||
if err := createUsers(s, []user{adminUser}); err != nil {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
|
||||
adminCfg := *s
|
||||
adminCfg.awsID = adminUser.access
|
||||
adminCfg.awsSecret = adminUser.secret
|
||||
|
||||
err := setup(&adminCfg, bucket)
|
||||
if err != nil {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
err = setup(s, bucket)
|
||||
var bne *types.BucketAlreadyExists
|
||||
if !errors.As(err, &bne) {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
|
||||
err = teardown(s, bucket)
|
||||
if err != nil {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
passF(testName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateBucket_owned_by_you(s *S3Conf) error {
|
||||
testName := "CreateBucket_owned_by_you"
|
||||
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err := s3client.CreateBucket(ctx, &s3.CreateBucketInput{
|
||||
Bucket: &bucket,
|
||||
})
|
||||
cancel()
|
||||
var bErr *types.BucketAlreadyOwnedByYou
|
||||
if !errors.As(err, &bErr) {
|
||||
return fmt.Errorf("expected error to be %w, instead got %w", s3err.GetAPIError(s3err.ErrBucketAlreadyOwnedByYou), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func CreateBucket_invalid_ownership(s *S3Conf) error {
|
||||
testName := "CreateBucket_invalid_ownership"
|
||||
runF(testName)
|
||||
|
||||
invalidOwnership := types.ObjectOwnership("invalid_ownership")
|
||||
err := setup(s, getBucketName(), withOwnership(invalidOwnership))
|
||||
if err := checkApiErr(err, s3err.GetInvalidArgObjectOwnership(string(invalidOwnership))); err != nil {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
|
||||
passF(testName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateBucket_ownership_with_acl(s *S3Conf) error {
|
||||
testName := "CreateBucket_ownership_with_acl"
|
||||
|
||||
runF(testName)
|
||||
client := s.GetClient()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err := client.CreateBucket(ctx, &s3.CreateBucketInput{
|
||||
Bucket: getPtr(getBucketName()),
|
||||
ObjectOwnership: types.ObjectOwnershipBucketOwnerEnforced,
|
||||
ACL: types.BucketCannedACLPublicRead,
|
||||
})
|
||||
cancel()
|
||||
if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrInvalidBucketAclWithObjectOwnership)); err != nil {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
|
||||
passF(testName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateBucket_default_acl(s *S3Conf) error {
|
||||
testName := "CreateBucket_default_acl"
|
||||
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
out, err := s3client.GetBucketAcl(ctx, &s3.GetBucketAclInput{Bucket: &bucket})
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if getString(out.Owner.ID) != s.awsID {
|
||||
return fmt.Errorf("expected bucket owner to be %v, instead got %v",
|
||||
s.awsID, getString(out.Owner.ID))
|
||||
}
|
||||
if len(out.Grants) != 1 {
|
||||
return fmt.Errorf("expected grants length to be 1, instead got %v",
|
||||
len(out.Grants))
|
||||
}
|
||||
grt := out.Grants[0]
|
||||
if grt.Permission != types.PermissionFullControl {
|
||||
return fmt.Errorf("expected the grantee to have full-control permission, instead got %v",
|
||||
grt.Permission)
|
||||
}
|
||||
if getString(grt.Grantee.ID) != s.awsID {
|
||||
return fmt.Errorf("expected the grantee id to be %v, instead got %v",
|
||||
s.awsID, getString(grt.Grantee.ID))
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func CreateBucket_non_default_acl(s *S3Conf) error {
|
||||
testName := "CreateBucket_non_default_acl"
|
||||
runF(testName)
|
||||
|
||||
testuser1, testuser2, testuser3 := getUser("user"), getUser("user"), getUser("user")
|
||||
err := createUsers(s, []user{testuser1, testuser2, testuser3})
|
||||
if err != nil {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
|
||||
grants := []types.Grant{
|
||||
{
|
||||
Grantee: &types.Grantee{
|
||||
ID: &s.awsID,
|
||||
Type: types.TypeCanonicalUser,
|
||||
},
|
||||
Permission: types.PermissionFullControl,
|
||||
},
|
||||
{
|
||||
Grantee: &types.Grantee{
|
||||
ID: &testuser1.access,
|
||||
Type: types.TypeCanonicalUser,
|
||||
},
|
||||
Permission: types.PermissionFullControl,
|
||||
},
|
||||
{
|
||||
Grantee: &types.Grantee{
|
||||
ID: &testuser2.access,
|
||||
Type: types.TypeCanonicalUser,
|
||||
},
|
||||
Permission: types.PermissionReadAcp,
|
||||
},
|
||||
{
|
||||
Grantee: &types.Grantee{
|
||||
ID: &testuser3.access,
|
||||
Type: types.TypeCanonicalUser,
|
||||
},
|
||||
Permission: types.PermissionWrite,
|
||||
},
|
||||
}
|
||||
|
||||
bucket := getBucketName()
|
||||
client := s.GetClient()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err = client.CreateBucket(ctx, &s3.CreateBucketInput{
|
||||
Bucket: &bucket,
|
||||
GrantFullControl: &testuser1.access,
|
||||
GrantReadACP: &testuser2.access,
|
||||
GrantWrite: &testuser3.access,
|
||||
ObjectOwnership: types.ObjectOwnershipBucketOwnerPreferred,
|
||||
})
|
||||
cancel()
|
||||
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 !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", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
|
||||
passF(testName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateBucket_private_canned_acl(s *S3Conf) error {
|
||||
testName := "CreateBucket_private_canned_acl"
|
||||
return actionHandlerNoSetup(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err := s3client.CreateBucket(ctx, &s3.CreateBucketInput{
|
||||
Bucket: &bucket,
|
||||
ACL: types.BucketCannedACLPrivate,
|
||||
})
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
||||
res, err := s3client.GetBucketAcl(ctx, &s3.GetBucketAclInput{
|
||||
Bucket: &bucket,
|
||||
})
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if getString(res.Owner.ID) != s.awsID {
|
||||
return fmt.Errorf("expected bucket owner to be %v, instead got %v",
|
||||
s.awsID, getString(res.Owner.ID))
|
||||
}
|
||||
if len(res.Grants) != 1 {
|
||||
return fmt.Errorf("expected grants length to be 1, instead got %v",
|
||||
len(res.Grants))
|
||||
}
|
||||
grt := res.Grants[0]
|
||||
if grt.Permission != types.PermissionFullControl {
|
||||
return fmt.Errorf("expected the grantee to have full-control permission, instead got %v",
|
||||
grt.Permission)
|
||||
}
|
||||
if getString(grt.Grantee.ID) != s.awsID {
|
||||
return fmt.Errorf("expected the grantee id to be %v, instead got %v",
|
||||
s.awsID, getString(grt.Grantee.ID))
|
||||
}
|
||||
|
||||
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
||||
out, err := s3client.GetBucketOwnershipControls(ctx, &s3.GetBucketOwnershipControlsInput{
|
||||
Bucket: &bucket,
|
||||
})
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if out.OwnershipControls == nil {
|
||||
return fmt.Errorf("unexpected nil OwnershipControls")
|
||||
}
|
||||
if len(out.OwnershipControls.Rules) != 1 {
|
||||
return fmt.Errorf("expected the OwnershipControls rules length to be 1, instead got %v", len(out.OwnershipControls.Rules))
|
||||
}
|
||||
if out.OwnershipControls.Rules[0].ObjectOwnership != types.ObjectOwnershipBucketOwnerPreferred {
|
||||
return fmt.Errorf("expected the ObjectOwnership to be %s, instead got %s", types.ObjectOwnershipBucketOwnerPreferred, out.OwnershipControls.Rules[0].ObjectOwnership)
|
||||
}
|
||||
|
||||
return teardown(s, bucket)
|
||||
})
|
||||
}
|
||||
|
||||
func CreateBucket_private_canned_acl_bucket_owner_enforced_ownership(s *S3Conf) error {
|
||||
testName := "CreateBucket_private_canned_acl_bucket_owner_enforced_ownership"
|
||||
return actionHandlerNoSetup(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err := s3client.CreateBucket(ctx, &s3.CreateBucketInput{
|
||||
Bucket: &bucket,
|
||||
ACL: types.BucketCannedACLPrivate,
|
||||
ObjectOwnership: types.ObjectOwnershipBucketOwnerEnforced,
|
||||
})
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
||||
res, err := s3client.GetBucketAcl(ctx, &s3.GetBucketAclInput{
|
||||
Bucket: &bucket,
|
||||
})
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if getString(res.Owner.ID) != s.awsID {
|
||||
return fmt.Errorf("expected bucket owner to be %v, instead got %v",
|
||||
s.awsID, getString(res.Owner.ID))
|
||||
}
|
||||
if len(res.Grants) != 1 {
|
||||
return fmt.Errorf("expected grants length to be 1, instead got %v",
|
||||
len(res.Grants))
|
||||
}
|
||||
grt := res.Grants[0]
|
||||
if grt.Permission != types.PermissionFullControl {
|
||||
return fmt.Errorf("expected the grantee to have full-control permission, instead got %v",
|
||||
grt.Permission)
|
||||
}
|
||||
if getString(grt.Grantee.ID) != s.awsID {
|
||||
return fmt.Errorf("expected the grantee id to be %v, instead got %v",
|
||||
s.awsID, getString(grt.Grantee.ID))
|
||||
}
|
||||
|
||||
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
||||
out, err := s3client.GetBucketOwnershipControls(ctx, &s3.GetBucketOwnershipControlsInput{
|
||||
Bucket: &bucket,
|
||||
})
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if out.OwnershipControls == nil {
|
||||
return fmt.Errorf("unexpected nil OwnershipControls")
|
||||
}
|
||||
if len(out.OwnershipControls.Rules) != 1 {
|
||||
return fmt.Errorf("expected the OwnershipControls rules length to be 1, instead got %v", len(out.OwnershipControls.Rules))
|
||||
}
|
||||
if out.OwnershipControls.Rules[0].ObjectOwnership != types.ObjectOwnershipBucketOwnerEnforced {
|
||||
return fmt.Errorf("expected the ObjectOwnership to be %s, instead got %s", types.ObjectOwnershipBucketOwnerEnforced, out.OwnershipControls.Rules[0].ObjectOwnership)
|
||||
}
|
||||
|
||||
return teardown(s, bucket)
|
||||
})
|
||||
}
|
||||
|
||||
func CreateBucket_default_object_lock(s *S3Conf) error {
|
||||
testName := "CreateBucket_default_object_lock"
|
||||
runF(testName)
|
||||
|
||||
bucket := getBucketName()
|
||||
lockEnabled := true
|
||||
|
||||
client := s.GetClient()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err := client.CreateBucket(ctx, &s3.CreateBucketInput{
|
||||
Bucket: &bucket,
|
||||
ObjectLockEnabledForBucket: &lockEnabled,
|
||||
})
|
||||
cancel()
|
||||
if err != nil {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
|
||||
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
||||
resp, err := client.GetObjectLockConfiguration(ctx, &s3.GetObjectLockConfigurationInput{
|
||||
Bucket: &bucket,
|
||||
})
|
||||
cancel()
|
||||
if err != nil {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
|
||||
if resp.ObjectLockConfiguration.ObjectLockEnabled != types.ObjectLockEnabledEnabled {
|
||||
failF("%v: expected object lock to be enabled", testName)
|
||||
return fmt.Errorf("%v: expected object lock to be enabled", testName)
|
||||
}
|
||||
|
||||
err = teardown(s, bucket)
|
||||
if err != nil {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
|
||||
passF(testName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateBucket_invalid_location_constraint(s *S3Conf) error {
|
||||
testName := "CreateBucket_invalid_location_constraint"
|
||||
return actionHandlerNoSetup(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
var region types.BucketLocationConstraint
|
||||
if types.BucketLocationConstraint(s.awsID) == types.BucketLocationConstraintUsWest1 {
|
||||
region = types.BucketLocationConstraintUsWest2
|
||||
} else {
|
||||
region = types.BucketLocationConstraintUsWest1
|
||||
}
|
||||
|
||||
createBucket := func(region types.BucketLocationConstraint) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err := s3client.CreateBucket(ctx, &s3.CreateBucketInput{
|
||||
Bucket: &bucket,
|
||||
CreateBucketConfiguration: &types.CreateBucketConfiguration{
|
||||
LocationConstraint: region,
|
||||
},
|
||||
})
|
||||
cancel()
|
||||
|
||||
return checkApiErr(err, s3err.GetAPIError(s3err.ErrInvalidLocationConstraint))
|
||||
}
|
||||
|
||||
for _, lConstraint := range []types.BucketLocationConstraint{region, "us-east-1"} {
|
||||
err := createBucket(lConstraint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func CreateBucket_long_tags(s *S3Conf) error {
|
||||
testName := "CreateBucket_long_tags"
|
||||
return actionHandlerNoSetup(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
tagging := []types.Tag{{Key: getPtr(genRandString(200)), Value: getPtr("val")}}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err := s3client.CreateBucket(ctx, &s3.CreateBucketInput{
|
||||
Bucket: &bucket,
|
||||
CreateBucketConfiguration: &types.CreateBucketConfiguration{
|
||||
Tags: tagging,
|
||||
},
|
||||
})
|
||||
cancel()
|
||||
if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrInvalidTagKey)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tagging = []types.Tag{{Key: getPtr("key"), Value: getPtr(genRandString(300))}}
|
||||
|
||||
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err = s3client.CreateBucket(ctx, &s3.CreateBucketInput{
|
||||
Bucket: &bucket,
|
||||
CreateBucketConfiguration: &types.CreateBucketConfiguration{
|
||||
Tags: tagging,
|
||||
},
|
||||
})
|
||||
cancel()
|
||||
if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrInvalidTagValue)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func CreateBucket_invalid_tags(s *S3Conf) error {
|
||||
testName := "CreateBucket_invalid_tags"
|
||||
return actionHandlerNoSetup(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
for i, test := range []struct {
|
||||
tags []types.Tag
|
||||
err s3err.APIError
|
||||
}{
|
||||
// invalid tag key tests
|
||||
{[]types.Tag{{Key: getPtr("user!name"), Value: getPtr("value")}}, s3err.GetAPIError(s3err.ErrInvalidTagKey)},
|
||||
{[]types.Tag{{Key: getPtr("foo#bar"), Value: getPtr("value")}}, s3err.GetAPIError(s3err.ErrInvalidTagKey)},
|
||||
{[]types.Tag{
|
||||
{Key: getPtr("validkey"), Value: getPtr("validvalue")},
|
||||
{Key: getPtr("data%20"), Value: getPtr("value")},
|
||||
}, s3err.GetAPIError(s3err.ErrInvalidTagKey)},
|
||||
{[]types.Tag{
|
||||
{Key: getPtr("abcd"), Value: getPtr("xyz123")},
|
||||
{Key: getPtr("a*b"), Value: getPtr("value")},
|
||||
}, s3err.GetAPIError(s3err.ErrInvalidTagKey)},
|
||||
// invalid tag value tests
|
||||
{[]types.Tag{
|
||||
{Key: getPtr("hello"), Value: getPtr("world")},
|
||||
{Key: getPtr("key"), Value: getPtr("name?test")},
|
||||
}, s3err.GetAPIError(s3err.ErrInvalidTagValue)},
|
||||
{[]types.Tag{
|
||||
{Key: getPtr("foo"), Value: getPtr("bar")},
|
||||
{Key: getPtr("key"), Value: getPtr("`path")},
|
||||
}, s3err.GetAPIError(s3err.ErrInvalidTagValue)},
|
||||
{[]types.Tag{{Key: getPtr("valid"), Value: getPtr("comma,separated")}}, s3err.GetAPIError(s3err.ErrInvalidTagValue)},
|
||||
{[]types.Tag{{Key: getPtr("valid"), Value: getPtr("semicolon;test")}}, s3err.GetAPIError(s3err.ErrInvalidTagValue)},
|
||||
{[]types.Tag{{Key: getPtr("valid"), Value: getPtr("(parentheses)")}}, s3err.GetAPIError(s3err.ErrInvalidTagValue)},
|
||||
} {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err := s3client.CreateBucket(ctx, &s3.CreateBucketInput{
|
||||
Bucket: &bucket,
|
||||
CreateBucketConfiguration: &types.CreateBucketConfiguration{
|
||||
Tags: test.tags,
|
||||
},
|
||||
})
|
||||
cancel()
|
||||
if err == nil {
|
||||
return fmt.Errorf("test %v failed: expected err %w, instead got nil", i+1, test.err)
|
||||
}
|
||||
|
||||
if err := checkApiErr(err, test.err); err != nil {
|
||||
return fmt.Errorf("test %v failed: %w", i+1, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func CreateBucket_duplicate_keys(s *S3Conf) error {
|
||||
testName := "CreateBucket_duplicate_keys"
|
||||
return actionHandlerNoSetup(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
tagging := []types.Tag{
|
||||
{Key: getPtr("key"), Value: getPtr("value")},
|
||||
{Key: getPtr("key"), Value: getPtr("value-1")},
|
||||
{Key: getPtr("key-1"), Value: getPtr("value-2")},
|
||||
{Key: getPtr("key-2"), Value: getPtr("value-3")},
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err := s3client.CreateBucket(ctx, &s3.CreateBucketInput{
|
||||
Bucket: &bucket,
|
||||
CreateBucketConfiguration: &types.CreateBucketConfiguration{
|
||||
Tags: tagging,
|
||||
},
|
||||
})
|
||||
cancel()
|
||||
if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrDuplicateTagKey)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func CreateBucket_tag_count_limit(s *S3Conf) error {
|
||||
testName := "CreateBucket_tag_count_limit"
|
||||
return actionHandlerNoSetup(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
tagSet := []types.Tag{}
|
||||
|
||||
for i := range 51 {
|
||||
tagSet = append(tagSet, types.Tag{
|
||||
Key: getPtr(fmt.Sprintf("key-%v", i)),
|
||||
Value: getPtr(genRandString(10)),
|
||||
})
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err := s3client.CreateBucket(ctx, &s3.CreateBucketInput{
|
||||
Bucket: &bucket,
|
||||
CreateBucketConfiguration: &types.CreateBucketConfiguration{
|
||||
Tags: tagSet,
|
||||
},
|
||||
})
|
||||
cancel()
|
||||
return checkApiErr(err, s3err.GetAPIError(s3err.ErrBucketTaggingLimited))
|
||||
})
|
||||
}
|
||||
|
||||
func CreateBucket_invalid_canned_acl(s *S3Conf) error {
|
||||
testName := "CreateBucket_invalid_canned_acl"
|
||||
return actionHandlerNoSetup(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err := s3client.CreateBucket(ctx, &s3.CreateBucketInput{
|
||||
Bucket: &bucket,
|
||||
ACL: types.BucketCannedACL("invalid_acl"),
|
||||
})
|
||||
cancel()
|
||||
return checkSdkApiErr(err, "InvalidArgument")
|
||||
})
|
||||
}
|
||||
|
||||
func CreateBucket_success(s *S3Conf) error {
|
||||
testName := "CreateBucket_success"
|
||||
return actionHandlerNoSetup(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
res, err := s3client.CreateBucket(ctx, &s3.CreateBucketInput{
|
||||
Bucket: &bucket,
|
||||
})
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
expectedLocation := "/" + bucket
|
||||
if getString(res.Location) != expectedLocation {
|
||||
return fmt.Errorf("expected the bucket Location to be %s, instead got %s", expectedLocation, getString(res.Location))
|
||||
}
|
||||
expectedArn := "arn:aws:s3:::" + bucket
|
||||
if getString(res.BucketArn) != expectedArn {
|
||||
return fmt.Errorf("expected the bucket arn to be %s, instead got %s", expectedArn, getString(res.BucketArn))
|
||||
}
|
||||
|
||||
return teardown(s, bucket)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,367 @@
|
||||
// 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"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
"github.com/versity/versitygw/s3response"
|
||||
)
|
||||
|
||||
func IAM_user_access_denied(s *S3Conf) error {
|
||||
testName := "IAM_user_access_denied"
|
||||
runF(testName)
|
||||
|
||||
testuser := getUser("user")
|
||||
err := createUsers(s, []user{testuser})
|
||||
if err != nil {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
|
||||
out, err := execCommand(s.getAdminCommand("-a", testuser.access, "-s", testuser.secret, "-er", s.endpoint, "delete-user", "-a", "random_access")...)
|
||||
if err == nil {
|
||||
failF("%v: expected cmd error", testName)
|
||||
return fmt.Errorf("%v: expected cmd error", testName)
|
||||
}
|
||||
if !strings.Contains(string(out), s3err.GetAPIError(s3err.ErrAdminAccessDenied).Code) {
|
||||
failF("%v: expected response error message to be %v, instead got %s",
|
||||
testName, s3err.GetAPIError(s3err.ErrAdminAccessDenied).Error(), out)
|
||||
return fmt.Errorf("%v: expected response error message to be %v, instead got %s",
|
||||
testName, s3err.GetAPIError(s3err.ErrAdminAccessDenied).Error(), out)
|
||||
}
|
||||
|
||||
passF(testName)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func IAM_userplus_access_denied(s *S3Conf) error {
|
||||
testName := "IAM_userplus_access_denied"
|
||||
runF(testName)
|
||||
|
||||
testuser := getUser("userplus")
|
||||
err := createUsers(s, []user{testuser})
|
||||
if err != nil {
|
||||
failF("%v: %v", testName, err)
|
||||
return fmt.Errorf("%v: %w", testName, err)
|
||||
}
|
||||
|
||||
out, err := execCommand(s.getAdminCommand("-a", testuser.access, "-s", testuser.secret, "-er", s.endpoint, "delete-user", "-a", "random_access")...)
|
||||
if err == nil {
|
||||
failF("%v: expected cmd error", testName)
|
||||
return fmt.Errorf("%v: expected cmd error", testName)
|
||||
}
|
||||
if !strings.Contains(string(out), s3err.GetAPIError(s3err.ErrAdminAccessDenied).Code) {
|
||||
failF("%v: expected response error message to be %v, instead got %s",
|
||||
testName, s3err.GetAPIError(s3err.ErrAdminAccessDenied).Error(), out)
|
||||
return fmt.Errorf("%v: expected response error message to be %v, instead got %s",
|
||||
testName, s3err.GetAPIError(s3err.ErrAdminAccessDenied).Error(), out)
|
||||
}
|
||||
|
||||
passF(testName)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func IAM_userplus_CreateBucket(s *S3Conf) error {
|
||||
testName := "IAM_userplus_CreateBucket"
|
||||
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
testuser := getUser("userplus")
|
||||
err := createUsers(s, []user{testuser})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg := *s
|
||||
cfg.awsID = testuser.access
|
||||
cfg.awsSecret = testuser.secret
|
||||
|
||||
bckt := getBucketName()
|
||||
err = setup(&cfg, bckt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err = s3client.HeadBucket(ctx, &s3.HeadBucketInput{Bucket: &bckt})
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = teardown(&cfg, bckt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func IAM_admin_ChangeBucketOwner(s *S3Conf) error {
|
||||
testName := "IAM_admin_ChangeBucketOwner"
|
||||
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
testuser, adminuser := getUser("user"), getUser("admin")
|
||||
err := createUsers(s, []user{adminuser, testuser})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = changeBucketsOwner(s, []string{bucket}, testuser.access)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
resp, err := s3client.GetBucketAcl(ctx, &s3.GetBucketAclInput{Bucket: &bucket})
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if getString(resp.Owner.ID) != testuser.access {
|
||||
return fmt.Errorf("expected the bucket owner to be %v, instead got %v",
|
||||
testuser.access, getString(resp.Owner.ID))
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func IAM_ChangeBucketOwner_back_to_root(s *S3Conf) error {
|
||||
testName := "IAM_ChangeBucketOwner_back_to_root"
|
||||
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
testuser := getUser("user")
|
||||
if err := createUsers(s, []user{testuser}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Change the bucket ownership to a random user
|
||||
if err := changeBucketsOwner(s, []string{bucket}, testuser.access); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Change the bucket ownership back to the root user
|
||||
if err := changeBucketsOwner(s, []string{bucket}, s.awsID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func IAM_ListBuckets(s *S3Conf) error {
|
||||
testName := "IAM_ListBuckets"
|
||||
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
return listBuckets(s)
|
||||
})
|
||||
}
|
||||
|
||||
func IAM_CreateBucket_empty_owner_header(s *S3Conf) error {
|
||||
testName := "IAM_CreateBucket_empty_owner_header"
|
||||
return actionHandlerNoSetup(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
req, err := createSignedReq(
|
||||
http.MethodPatch,
|
||||
s.endpoint,
|
||||
fmt.Sprintf("%s/create", bucket),
|
||||
s.awsID,
|
||||
s.awsSecret,
|
||||
"s3",
|
||||
s.awsRegion,
|
||||
"",
|
||||
nil,
|
||||
time.Now(),
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := s.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrAdminEmptyBucketOwnerHeader))
|
||||
})
|
||||
}
|
||||
|
||||
func IAM_CreateBucket_non_existing_user(s *S3Conf) error {
|
||||
testName := "IAM_CreateBucket_non_existing_user"
|
||||
return actionHandlerNoSetup(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
req, err := createSignedReq(
|
||||
http.MethodPatch,
|
||||
s.endpoint,
|
||||
fmt.Sprintf("%s/create", bucket),
|
||||
s.awsID,
|
||||
s.awsSecret,
|
||||
"s3",
|
||||
s.awsRegion,
|
||||
"",
|
||||
nil,
|
||||
time.Now(),
|
||||
map[string]string{
|
||||
"x-vgw-owner": "non-existing-user",
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := s.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrAdminUserNotFound))
|
||||
})
|
||||
}
|
||||
|
||||
func IAM_CreateBucket_success(s *S3Conf) error {
|
||||
testName := "IAM_CreateBucket_success"
|
||||
return actionHandlerNoSetup(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
tagSet := []types.Tag{
|
||||
{Key: getPtr("key"), Value: getPtr("value")},
|
||||
}
|
||||
body, err := xml.Marshal(s3response.CreateBucketConfiguration{
|
||||
TagSet: tagSet,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
testUser1, testUser2 := getUser("user"), getUser("user")
|
||||
err = createUsers(s, []user{testUser1, testUser2})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req, err := createSignedReq(
|
||||
http.MethodPatch,
|
||||
s.endpoint,
|
||||
fmt.Sprintf("%s/create", bucket),
|
||||
s.awsID,
|
||||
s.awsSecret,
|
||||
"s3",
|
||||
s.awsRegion,
|
||||
"",
|
||||
body,
|
||||
time.Now(),
|
||||
map[string]string{
|
||||
"x-amz-bucket-object-lock-enabled": "true",
|
||||
"x-amz-object-ownership": string(types.ObjectOwnershipBucketOwnerPreferred),
|
||||
"x-amz-grant-read": testUser2.access,
|
||||
"x-vgw-owner": testUser1.access,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := s.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusCreated {
|
||||
return fmt.Errorf("expected the response status code to be %v, instead got %v", http.StatusCreated, resp.StatusCode)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
tagging, err := s3client.GetBucketTagging(ctx, &s3.GetBucketTaggingInput{
|
||||
Bucket: &bucket,
|
||||
})
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !areTagsSame(tagSet, tagging.TagSet) {
|
||||
return fmt.Errorf("expected the bucket tagging to be %v, instead got %v", tagSet, tagging.TagSet)
|
||||
}
|
||||
|
||||
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
||||
ownership, err := s3client.GetBucketOwnershipControls(ctx, &s3.GetBucketOwnershipControlsInput{
|
||||
Bucket: &bucket,
|
||||
})
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var ownershipControls types.ObjectOwnership
|
||||
if ownership.OwnershipControls != nil && len(ownership.OwnershipControls.Rules) == 1 {
|
||||
ownershipControls = ownership.OwnershipControls.Rules[0].ObjectOwnership
|
||||
}
|
||||
|
||||
if ownershipControls != types.ObjectOwnershipBucketOwnerPreferred {
|
||||
return fmt.Errorf("expected the bucket ownership controls to be %s, instaed got %s", types.ObjectOwnershipBucketOwnerPreferred, ownershipControls)
|
||||
}
|
||||
|
||||
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
||||
acl, err := s3client.GetBucketAcl(ctx, &s3.GetBucketAclInput{
|
||||
Bucket: &bucket,
|
||||
})
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(acl.Grants) != 2 {
|
||||
return fmt.Errorf("expected the length of acl grants to be 2, instead got %v", len(acl.Grants))
|
||||
}
|
||||
|
||||
var granteeChecked bool
|
||||
var ownerChecked bool
|
||||
for _, grant := range acl.Grants {
|
||||
// owner
|
||||
if getString(grant.Grantee.ID) == testUser1.access {
|
||||
ownerChecked = true
|
||||
if grant.Permission != types.PermissionFullControl {
|
||||
return fmt.Errorf("expected the owner '%s' to have %s permission, instead got %s", testUser1.access, types.PermissionFullControl, grant.Permission)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if getString(grant.Grantee.ID) != testUser2.access {
|
||||
return fmt.Errorf("expected the grantee ID to be %v, instaed got %v", testUser2.access, getString(grant.Grantee.ID))
|
||||
}
|
||||
if grant.Permission != types.PermissionRead {
|
||||
return fmt.Errorf("expected the %v user permission to be %s, instead got %s", testUser2.access, types.PermissionRead, grant.Permission)
|
||||
}
|
||||
|
||||
granteeChecked = true
|
||||
}
|
||||
|
||||
if !ownerChecked {
|
||||
return fmt.Errorf("missing the owner '%s' full control acl", testUser1.access)
|
||||
}
|
||||
if !granteeChecked {
|
||||
return fmt.Errorf("missing the user %s in read grantees acl", testUser2.access)
|
||||
}
|
||||
|
||||
return teardown(s, bucket)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
# Copyright 2024 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.
|
||||
|
||||
load ./bats-support/load
|
||||
load ./bats-assert/load
|
||||
|
||||
source ./tests/commands/put_object.sh
|
||||
source ./tests/drivers/file.sh
|
||||
source ./tests/drivers/create_bucket/create_bucket_rest.sh
|
||||
source ./tests/drivers/get_bucket_acl/get_bucket_acl_rest.sh
|
||||
source ./tests/logger.sh
|
||||
source ./tests/setup.sh
|
||||
source ./tests/util/util_object.sh
|
||||
source ./tests/util/util_public_access_block.sh
|
||||
|
||||
export RUN_USERS=true
|
||||
|
||||
if [ "$SKIP_ACL_TESTING" == "true" ] || [ "$SKIP_USERS_TESTS" == "true" ]; then
|
||||
skip "Skipping ACL tests"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# tags: curl,minimal-request,GetBucketAcl
|
||||
@test "REST - get ACL" {
|
||||
run get_bucket_name "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
bucket_name="$output"
|
||||
|
||||
run setup_bucket_v2 "$bucket_name"
|
||||
assert_success
|
||||
|
||||
run get_and_check_acl_rest "$bucket_name"
|
||||
assert_success
|
||||
}
|
||||
|
||||
# tags: curl,minimal-request,PutBucketAcl
|
||||
@test "REST - put ACL" {
|
||||
run get_bucket_name "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
bucket_name="$output"
|
||||
|
||||
test_file="test_file"
|
||||
run setup_bucket_and_file_v2 "$bucket_name" "$test_file"
|
||||
assert_success
|
||||
|
||||
run put_bucket_ownership_controls "$bucket_name" "BucketOwnerPreferred"
|
||||
assert_success
|
||||
|
||||
run put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file"
|
||||
assert_success
|
||||
|
||||
run create_versitygw_acl_user_or_get_direct_user "$USERNAME_ONE" "$PASSWORD_ONE"
|
||||
assert_success
|
||||
canonical_id=${lines[0]}
|
||||
user_canonical_id=${lines[1]}
|
||||
username=${lines[2]}
|
||||
password=${lines[3]}
|
||||
|
||||
run setup_acl "$TEST_FILE_FOLDER/acl-file.txt" "CanonicalUser" "$user_canonical_id" "READ" "$canonical_id"
|
||||
assert_success
|
||||
|
||||
run list_objects_with_user_rest_verify_access_denied "$bucket_name" "$username" "$password"
|
||||
assert_success
|
||||
|
||||
run put_bucket_acl_rest "$bucket_name" "$TEST_FILE_FOLDER/acl-file.txt"
|
||||
assert_success
|
||||
|
||||
if [ "$DIRECT" == "true" ]; then
|
||||
sleep 5
|
||||
fi
|
||||
|
||||
run list_objects_with_user_rest_verify_success "$bucket_name" "$username" "$password" "$test_file"
|
||||
assert_success
|
||||
}
|
||||
|
||||
# tags: curl,PutBucketAcl,x-amz-acl
|
||||
@test "REST - put public-read canned acl" {
|
||||
run get_bucket_name "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
bucket_name="$output"
|
||||
|
||||
test_file="test_file"
|
||||
run setup_bucket_and_file_v2 "$bucket_name" "$test_file"
|
||||
assert_success
|
||||
|
||||
run put_bucket_ownership_controls "$bucket_name" "BucketOwnerPreferred"
|
||||
assert_success
|
||||
|
||||
run put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file"
|
||||
assert_success
|
||||
|
||||
run create_versitygw_acl_user_or_get_direct_user "$USERNAME_ONE" "$PASSWORD_ONE"
|
||||
assert_success
|
||||
canonical_id=${lines[0]}
|
||||
user_canonical_id=${lines[1]}
|
||||
username=${lines[2]}
|
||||
password=${lines[3]}
|
||||
|
||||
run list_objects_with_user_rest_verify_access_denied "$bucket_name" "$username" "$password"
|
||||
assert_success
|
||||
|
||||
if [ "$DIRECT" == "true" ]; then
|
||||
run allow_public_access "$bucket_name"
|
||||
assert_success
|
||||
fi
|
||||
run put_canned_acl_rest "$bucket_name" "public-read"
|
||||
assert_success
|
||||
|
||||
run list_objects_with_user_rest_verify_success "$bucket_name" "$username" "$password" "$test_file"
|
||||
assert_success
|
||||
}
|
||||
|
||||
# tags: curl,minimal-request,PutBucketAcl
|
||||
@test "REST - put invalid ACL" {
|
||||
run get_bucket_name "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
bucket_name="$output"
|
||||
|
||||
run setup_bucket_v2 "$bucket_name"
|
||||
assert_success
|
||||
|
||||
run put_bucket_ownership_controls "$bucket_name" "BucketOwnerPreferred"
|
||||
assert_success
|
||||
|
||||
run create_versitygw_acl_user_or_get_direct_user "$USERNAME_ONE" "$PASSWORD_ONE"
|
||||
assert_success
|
||||
canonical_id=${lines[0]}
|
||||
user_canonical_id=${lines[1]}
|
||||
username=${lines[2]}
|
||||
password=${lines[3]}
|
||||
|
||||
run setup_acl "$TEST_FILE_FOLDER/acl-file.txt" "CanonicalUser" "$user_canonical_id" "READD" "$canonical_id"
|
||||
assert_success
|
||||
|
||||
if [ "$DIRECT" == "true" ]; then
|
||||
run allow_public_access "$bucket_name"
|
||||
assert_success
|
||||
fi
|
||||
run put_invalid_acl_rest_verify_failure "$bucket_name" "$TEST_FILE_FOLDER/acl-file.txt"
|
||||
assert_success
|
||||
}
|
||||
|
||||
# tags: curl,PutBucketAcl,x-amz-acl
|
||||
@test "REST - put public-read-write canned acl" {
|
||||
run get_bucket_name "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
bucket_name="$output"
|
||||
|
||||
test_file="test_file"
|
||||
run setup_bucket_and_file_v2 "$bucket_name" "$test_file"
|
||||
assert_success
|
||||
|
||||
run put_bucket_ownership_controls "$bucket_name" "BucketOwnerPreferred"
|
||||
assert_success
|
||||
|
||||
run create_versitygw_acl_user_or_get_direct_user "$USERNAME_ONE" "$PASSWORD_ONE"
|
||||
assert_success
|
||||
canonical_id=${lines[0]}
|
||||
user_canonical_id=${lines[1]}
|
||||
username=${lines[2]}
|
||||
password=${lines[3]}
|
||||
|
||||
run put_object_with_user "s3api" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" "$username" "$password"
|
||||
assert_failure
|
||||
|
||||
if [ "$DIRECT" == "true" ]; then
|
||||
run allow_public_access "$bucket_name"
|
||||
assert_success
|
||||
fi
|
||||
run put_canned_acl_rest "$bucket_name" "public-read-write"
|
||||
assert_success
|
||||
|
||||
run put_object_with_user "s3api" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" "$username" "$password"
|
||||
assert_success
|
||||
}
|
||||
|
||||
# tags: curl,PutBucketAcl,x-amz-acl
|
||||
@test "REST - invalid canned acl" {
|
||||
if [ "$DIRECT" != "true" ]; then
|
||||
skip "https://github.com/versity/versitygw/issues/1367"
|
||||
fi
|
||||
run get_bucket_name "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
bucket_name="$output"
|
||||
|
||||
test_file="test_file"
|
||||
run setup_bucket_and_file_v2 "$bucket_name" "$test_file"
|
||||
assert_success
|
||||
|
||||
run put_bucket_ownership_controls "$bucket_name" "BucketOwnerPreferred"
|
||||
assert_success
|
||||
|
||||
run put_bucket_acl_rest_canned_invalid "$bucket_name" "privatee"
|
||||
assert_success
|
||||
}
|
||||
|
||||
# tags: curl,GetBucketAcl,x-amz-grant-read-acp
|
||||
@test "REST - FULL_CONTROL permission not returned for owner after CreateBucket with GRANT_READ_ACP" {
|
||||
if [ "$DIRECT" != "true" ]; then
|
||||
skip "https://github.com/versity/versitygw/issues/1407"
|
||||
fi
|
||||
run get_bucket_name "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
bucket_name="$output"
|
||||
|
||||
run create_versitygw_acl_user_or_get_direct_user "$USERNAME_ONE" "$PASSWORD_ONE"
|
||||
assert_success
|
||||
canonical_id=${lines[0]}
|
||||
user_canonical_id=${lines[1]}
|
||||
username=${lines[2]}
|
||||
password=${lines[3]}
|
||||
|
||||
run bucket_cleanup_if_bucket_exists "$bucket_name"
|
||||
assert_success
|
||||
if [ "$DIRECT" == "true" ]; then
|
||||
id="id=$user_canonical_id"
|
||||
else
|
||||
id="$user_canonical_id"
|
||||
fi
|
||||
|
||||
envs="GRANT_READ_ACP=$id OBJECT_OWNERSHIP=BucketOwnerPreferred"
|
||||
run create_bucket_rest_expect_success "$bucket_name" "$envs"
|
||||
assert_success
|
||||
|
||||
run get_bucket_acl_rest "$bucket_name" "" "check_that_acl_xml_does_not_have_owner_permission"
|
||||
assert_success
|
||||
}
|
||||
Reference in new issue
Block a user