mirror of
https://github.com/versity/versitygw.git
synced 2026-09-18 22:14:24 +00:00
feat: implements tagging support for CreateBucket
Closes #1595 This implementation diverges from AWS S3 behavior. The `CreateBucket` request body is no longer ignored. Based on the S3 request body schema, the gateway parses only the `LocationConstraint` and `Tags` fields. If the `LocationConstraint` does not match the gateway’s region, it returns an `InvalidLocationConstraint` error. In AWS S3, tagging during bucket creation is supported only for directory buckets. The gateway extends this support to general-purpose buckets. If the request body is malformed, the gateway returns a `MalformedXML` error.
This commit is contained in:
@@ -533,6 +533,32 @@ func (c S3ApiController) CreateBucket(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, s3err.GetAPIError(s3err.ErrBothCannedAndHeaderGrants)
|
||||
}
|
||||
|
||||
var body s3response.CreateBucketConfiguration
|
||||
if len(ctx.Body()) != 0 {
|
||||
// request body is optional for CreateBucket
|
||||
err := xml.Unmarshal(ctx.Body(), &body)
|
||||
if err != nil {
|
||||
debuglogger.Logf("failed to parse the request body: %v", err)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: acct.Access,
|
||||
},
|
||||
}, s3err.GetAPIError(s3err.ErrMalformedXML)
|
||||
}
|
||||
|
||||
if body.LocationConstraint != "" {
|
||||
region := utils.ContextKeyRegion.Get(ctx).(string)
|
||||
if body.LocationConstraint != region {
|
||||
debuglogger.Logf("invalid location constraint: %s", body.LocationConstraint)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: acct.Access,
|
||||
},
|
||||
}, s3err.GetAPIError(s3err.ErrInvalidLocationConstraint)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defACL := auth.ACL{
|
||||
Owner: acct.Access,
|
||||
}
|
||||
@@ -562,6 +588,9 @@ func (c S3ApiController) CreateBucket(ctx *fiber.Ctx) (*Response, error) {
|
||||
Bucket: &bucket,
|
||||
ObjectOwnership: objectOwnership,
|
||||
ObjectLockEnabledForBucket: &lockEnabled,
|
||||
CreateBucketConfiguration: &types.CreateBucketConfiguration{
|
||||
Tags: body.TagSet,
|
||||
},
|
||||
}, updAcl)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
|
||||
@@ -695,6 +695,11 @@ func TestS3ApiController_CreateBucket(t *testing.T) {
|
||||
Role: auth.RoleUser,
|
||||
}
|
||||
|
||||
invLocConstBody, err := xml.Marshal(s3response.CreateBucketConfiguration{
|
||||
LocationConstraint: "us-west-1",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input testInput
|
||||
@@ -729,6 +734,37 @@ func TestS3ApiController_CreateBucket(t *testing.T) {
|
||||
err: s3err.GetAPIError(s3err.ErrInvalidBucketName),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "malformed body",
|
||||
input: testInput{
|
||||
locals: map[utils.ContextKey]any{
|
||||
utils.ContextKeyAccount: adminAcc,
|
||||
},
|
||||
body: []byte("invalid_body"),
|
||||
},
|
||||
output: testOutput{
|
||||
response: &Response{
|
||||
MetaOpts: &MetaOptions{BucketOwner: adminAcc.Access},
|
||||
},
|
||||
err: s3err.GetAPIError(s3err.ErrMalformedXML),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid location constraint",
|
||||
input: testInput{
|
||||
locals: map[utils.ContextKey]any{
|
||||
utils.ContextKeyAccount: adminAcc,
|
||||
utils.ContextKeyRegion: "us-east-1",
|
||||
},
|
||||
body: invLocConstBody,
|
||||
},
|
||||
output: testOutput{
|
||||
response: &Response{
|
||||
MetaOpts: &MetaOptions{BucketOwner: adminAcc.Access},
|
||||
},
|
||||
err: s3err.GetAPIError(s3err.ErrInvalidLocationConstraint),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid ownership",
|
||||
input: testInput{
|
||||
|
||||
Reference in New Issue
Block a user