diff --git a/auth/acl.go b/auth/acl.go index 45731b2..80dec11 100644 --- a/auth/acl.go +++ b/auth/acl.go @@ -34,7 +34,7 @@ type ACL struct { } type Grantee struct { - Permission types.Permission + Permission Permission Access string Type types.Type } @@ -61,20 +61,124 @@ type AccessControlPolicy struct { Owner *types.Owner } +func (acp *AccessControlPolicy) Validate() error { + if !acp.AccessControlList.isValid() { + return s3err.GetAPIError(s3err.ErrMalformedACL) + } + + // The Owner can't be nil + if acp.Owner == nil { + return s3err.GetAPIError(s3err.ErrMalformedACL) + } + + // The Owner ID can't be empty + if acp.Owner.ID == nil || *acp.Owner.ID == "" { + return s3err.GetAPIError(s3err.ErrMalformedACL) + } + + return nil +} + type AccessControlList struct { Grants []Grant `xml:"Grant"` } +// Validates the AccessControlList +func (acl *AccessControlList) isValid() bool { + for _, el := range acl.Grants { + if !el.isValid() { + return false + } + } + + return true +} + +type Permission string + +const ( + PermissionFullControl Permission = "FULL_CONTROL" + PermissionWrite Permission = "WRITE" + PermissionWriteAcp Permission = "WRITE_ACP" + PermissionRead Permission = "READ" + PermissionReadAcp Permission = "READ_ACP" +) + +// Check if the permission is valid +func (p Permission) isValid() bool { + return p == PermissionFullControl || + p == PermissionRead || + p == PermissionReadAcp || + p == PermissionWrite || + p == PermissionWriteAcp +} + type Grant struct { - Grantee *Grt - Permission types.Permission + Grantee *Grt `xml:"Grantee"` + Permission Permission `xml:"Permission"` +} + +// Checks if Grant is valid +func (g *Grant) isValid() bool { + return g.Permission.isValid() && g.Grantee.isValid() } type Grt struct { - XMLNS string `xml:"xmlns:xsi,attr"` - XMLXSI types.Type `xml:"xsi:type,attr"` - Type types.Type `xml:"Type"` - ID string `xml:"ID"` + XMLNS string `xml:"xmlns:xsi,attr"` + Type types.Type `xml:"xsi:type,attr"` + ID string `xml:"ID"` +} + +// Custom Unmarshalling for Grt to parse xsi:type properly +func (g *Grt) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + // Iterate through the XML tokens to process the attributes + for _, attr := range start.Attr { + // Check if the attribute is xsi:type and belongs to the xsi namespace + if attr.Name.Space == "http://www.w3.org/2001/XMLSchema-instance" && attr.Name.Local == "type" { + g.Type = types.Type(attr.Value) + } + // Handle xmlns:xsi + if attr.Name.Local == "xmlns:xsi" { + g.XMLNS = attr.Value + } + } + + // Decode the inner XML elements like ID + for { + t, err := d.Token() + if err != nil { + return err + } + + switch se := t.(type) { + case xml.StartElement: + if se.Name.Local == "ID" { + if err := d.DecodeElement(&g.ID, &se); err != nil { + return err + } + } + case xml.EndElement: + if se.Name.Local == start.Name.Local { + return nil + } + } + } +} + +// Validates Grt +func (g *Grt) isValid() bool { + // Validate the Type + // Only these 2 types are supported in the gateway + if g.Type != types.TypeCanonicalUser && g.Type != types.TypeGroup { + return false + } + + // The ID prop shouldn't be empty + if g.ID == "" { + return false + } + + return true } func ParseACL(data []byte) (ACL, error) { @@ -101,10 +205,9 @@ func ParseACLOutput(data []byte) (GetBucketAclOutput, error) { acs := elem.Access grants = append(grants, Grant{ Grantee: &Grt{ - XMLNS: "http://www.w3.org/2001/XMLSchema-instance", - XMLXSI: elem.Type, - ID: acs, - Type: elem.Type, + XMLNS: "http://www.w3.org/2001/XMLSchema-instance", + ID: acs, + Type: elem.Type, }, Permission: elem.Permission, }) @@ -127,7 +230,7 @@ func UpdateACL(input *PutBucketAclInput, acl ACL, iam IAMService, isAdmin bool) defaultGrantees := []Grantee{ { - Permission: types.PermissionFullControl, + Permission: PermissionFullControl, Access: acl.Owner, Type: types.TypeCanonicalUser, }, @@ -138,19 +241,19 @@ func UpdateACL(input *PutBucketAclInput, acl ACL, iam IAMService, isAdmin bool) switch input.ACL { case types.BucketCannedACLPublicRead: defaultGrantees = append(defaultGrantees, Grantee{ - Permission: types.PermissionRead, + Permission: PermissionRead, Access: "all-users", Type: types.TypeGroup, }) case types.BucketCannedACLPublicReadWrite: defaultGrantees = append(defaultGrantees, []Grantee{ { - Permission: types.PermissionRead, + Permission: PermissionRead, Access: "all-users", Type: types.TypeGroup, }, { - Permission: types.PermissionWrite, + Permission: PermissionWrite, Access: "all-users", Type: types.TypeGroup, }, @@ -167,7 +270,7 @@ func UpdateACL(input *PutBucketAclInput, acl ACL, iam IAMService, isAdmin bool) for _, str := range fullControlList { defaultGrantees = append(defaultGrantees, Grantee{ Access: str, - Permission: types.PermissionFullControl, + Permission: PermissionFullControl, Type: types.TypeCanonicalUser, }) } @@ -177,7 +280,7 @@ func UpdateACL(input *PutBucketAclInput, acl ACL, iam IAMService, isAdmin bool) for _, str := range readList { defaultGrantees = append(defaultGrantees, Grantee{ Access: str, - Permission: types.PermissionRead, + Permission: PermissionRead, Type: types.TypeCanonicalUser, }) } @@ -187,7 +290,7 @@ func UpdateACL(input *PutBucketAclInput, acl ACL, iam IAMService, isAdmin bool) for _, str := range readACPList { defaultGrantees = append(defaultGrantees, Grantee{ Access: str, - Permission: types.PermissionReadAcp, + Permission: PermissionReadAcp, Type: types.TypeCanonicalUser, }) } @@ -197,7 +300,7 @@ func UpdateACL(input *PutBucketAclInput, acl ACL, iam IAMService, isAdmin bool) for _, str := range writeList { defaultGrantees = append(defaultGrantees, Grantee{ Access: str, - Permission: types.PermissionWrite, + Permission: PermissionWrite, Type: types.TypeCanonicalUser, }) } @@ -207,7 +310,7 @@ func UpdateACL(input *PutBucketAclInput, acl ACL, iam IAMService, isAdmin bool) for _, str := range writeACPList { defaultGrantees = append(defaultGrantees, Grantee{ Access: str, - Permission: types.PermissionWriteAcp, + Permission: PermissionWriteAcp, Type: types.TypeCanonicalUser, }) } @@ -288,7 +391,7 @@ func splitUnique(s, divider string) []string { return result } -func verifyACL(acl ACL, access string, permission types.Permission) error { +func verifyACL(acl ACL, access string, permission Permission) error { grantee := Grantee{ Access: access, Permission: permission, @@ -296,7 +399,7 @@ func verifyACL(acl ACL, access string, permission types.Permission) error { } granteeFullCtrl := Grantee{ Access: access, - Permission: types.PermissionFullControl, + Permission: PermissionFullControl, Type: types.TypeCanonicalUser, } granteeAllUsers := Grantee{ @@ -355,7 +458,7 @@ func IsAdminOrOwner(acct Account, isRoot bool, acl ACL) error { type AccessOptions struct { Acl ACL - AclPermission types.Permission + AclPermission Permission IsRoot bool Acc Account Bucket string @@ -366,7 +469,7 @@ type AccessOptions struct { func VerifyAccess(ctx context.Context, be backend.Backend, opts AccessOptions) error { if opts.Readonly { - if opts.AclPermission == types.PermissionWrite || opts.AclPermission == types.PermissionWriteAcp { + if opts.AclPermission == PermissionWrite || opts.AclPermission == PermissionWriteAcp { return s3err.GetAPIError(s3err.ErrAccessDenied) } } @@ -424,7 +527,7 @@ func VerifyObjectCopyAccess(ctx context.Context, be backend.Backend, copySource if err := VerifyAccess(ctx, be, AccessOptions{ Acl: srcBucketAcl, - AclPermission: types.PermissionRead, + AclPermission: PermissionRead, IsRoot: opts.IsRoot, Acc: opts.Acc, Bucket: srcBucket, diff --git a/s3api/controllers/admin.go b/s3api/controllers/admin.go index e56b783..fda224d 100644 --- a/s3api/controllers/admin.go +++ b/s3api/controllers/admin.go @@ -167,7 +167,7 @@ func (c AdminController) ChangeBucketOwner(ctx *fiber.Ctx) error { Owner: owner, Grantees: []auth.Grantee{ { - Permission: types.PermissionFullControl, + Permission: auth.PermissionFullControl, Access: owner, Type: types.TypeCanonicalUser, }, diff --git a/s3api/controllers/base.go b/s3api/controllers/base.go index d9662fc..a17ebe9 100644 --- a/s3api/controllers/base.go +++ b/s3api/controllers/base.go @@ -126,7 +126,7 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -175,7 +175,7 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -217,7 +217,7 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -282,7 +282,7 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error { err = auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -319,7 +319,7 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionReadAcp, + AclPermission: auth.PermissionReadAcp, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -352,7 +352,7 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -468,7 +468,7 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -637,7 +637,7 @@ func (c S3ApiController) ListActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -685,7 +685,7 @@ func (c S3ApiController) ListActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -722,7 +722,7 @@ func (c S3ApiController) ListActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -762,7 +762,7 @@ func (c S3ApiController) ListActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -792,7 +792,7 @@ func (c S3ApiController) ListActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -845,7 +845,7 @@ func (c S3ApiController) ListActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -886,7 +886,7 @@ func (c S3ApiController) ListActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionReadAcp, + AclPermission: auth.PermissionReadAcp, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -926,7 +926,7 @@ func (c S3ApiController) ListActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -977,7 +977,7 @@ func (c S3ApiController) ListActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -1027,7 +1027,7 @@ func (c S3ApiController) ListActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -1127,7 +1127,7 @@ func (c S3ApiController) PutBucketActions(ctx *fiber.Ctx) error { err = auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -1180,7 +1180,7 @@ func (c S3ApiController) PutBucketActions(ctx *fiber.Ctx) error { if err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -1210,7 +1210,7 @@ func (c S3ApiController) PutBucketActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -1272,7 +1272,7 @@ func (c S3ApiController) PutBucketActions(ctx *fiber.Ctx) error { if err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -1313,7 +1313,7 @@ func (c S3ApiController) PutBucketActions(ctx *fiber.Ctx) error { err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -1384,7 +1384,7 @@ func (c S3ApiController) PutBucketActions(ctx *fiber.Ctx) error { auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWriteAcp, + AclPermission: auth.PermissionWriteAcp, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -1415,13 +1415,12 @@ func (c S3ApiController) PutBucketActions(ctx *fiber.Ctx) error { }) } - if accessControlPolicy.Owner == nil || - accessControlPolicy.Owner.ID == nil || - *accessControlPolicy.Owner.ID == "" { + err = accessControlPolicy.Validate() + if err != nil { if c.debug { - log.Println("empty access control policy owner") + log.Printf("invalid access control policy: %v\n", err) } - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrMalformedACL), + return SendResponse(ctx, err, &MetaOpts{ Logger: c.logger, Action: metrics.ActionPutBucketAcl, @@ -1733,7 +1732,7 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { err = auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -1766,7 +1765,7 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { if err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -1839,7 +1838,7 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { if err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -1903,7 +1902,7 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { err = auth.VerifyObjectCopyAccess(ctx.Context(), c.be, copySource, auth.AccessOptions{ Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -1967,7 +1966,7 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -2073,7 +2072,7 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { ID: &grt.Grantee.ID, Type: grt.Grantee.Type, }, - Permission: grt.Permission, + Permission: types.Permission(grt.Permission), }) } @@ -2174,7 +2173,7 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { err = auth.VerifyObjectCopyAccess(ctx.Context(), c.be, copySource, auth.AccessOptions{ Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -2306,7 +2305,7 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -2437,7 +2436,7 @@ func (c S3ApiController) DeleteBucket(ctx *fiber.Ctx) error { auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -2469,7 +2468,7 @@ func (c S3ApiController) DeleteBucket(ctx *fiber.Ctx) error { auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -2501,7 +2500,7 @@ func (c S3ApiController) DeleteBucket(ctx *fiber.Ctx) error { auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -2532,7 +2531,7 @@ func (c S3ApiController) DeleteBucket(ctx *fiber.Ctx) error { auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -2585,7 +2584,7 @@ func (c S3ApiController) DeleteObjects(ctx *fiber.Ctx) error { auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -2658,7 +2657,7 @@ func (c S3ApiController) DeleteActions(ctx *fiber.Ctx) error { auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -2696,7 +2695,7 @@ func (c S3ApiController) DeleteActions(ctx *fiber.Ctx) error { auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -2737,7 +2736,7 @@ func (c S3ApiController) DeleteActions(ctx *fiber.Ctx) error { auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -2826,7 +2825,7 @@ func (c S3ApiController) HeadBucket(ctx *fiber.Ctx) error { auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -2909,7 +2908,7 @@ func (c S3ApiController) HeadObject(ctx *fiber.Ctx) error { auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -3080,7 +3079,7 @@ func (c S3ApiController) CreateActions(ctx *fiber.Ctx) error { auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -3135,7 +3134,7 @@ func (c S3ApiController) CreateActions(ctx *fiber.Ctx) error { auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionRead, + AclPermission: auth.PermissionRead, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -3207,7 +3206,7 @@ func (c S3ApiController) CreateActions(ctx *fiber.Ctx) error { auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, @@ -3267,7 +3266,7 @@ func (c S3ApiController) CreateActions(ctx *fiber.Ctx) error { auth.AccessOptions{ Readonly: c.readonly, Acl: parsedAcl, - AclPermission: types.PermissionWrite, + AclPermission: auth.PermissionWrite, IsRoot: isRoot, Acc: acct, Bucket: bucket, diff --git a/tests/integration/group-tests.go b/tests/integration/group-tests.go index 6c7b9c3..8137600 100644 --- a/tests/integration/group-tests.go +++ b/tests/integration/group-tests.go @@ -336,6 +336,10 @@ func TestPutBucketAcl(s *S3Conf) { PutBucketAcl_invalid_acl_acp_and_grants(s) PutBucketAcl_invalid_owner(s) PutBucketAcl_invalid_owner_not_in_body(s) + PutBucketAcl_invalid_empty_owner_id_in_body(s) + PutBucketAcl_invalid_permission_in_body(s) + PutBucketAcl_invalid_grantee_type_in_body(s) + PutBucketAcl_empty_grantee_ID_in_body(s) PutBucketAcl_success_access_denied(s) PutBucketAcl_success_grants(s) PutBucketAcl_success_canned_acl(s) @@ -861,6 +865,10 @@ func GetIntTests() IntTests { "PutBucketAcl_invalid_acl_acp_and_grants": PutBucketAcl_invalid_acl_acp_and_grants, "PutBucketAcl_invalid_owner": PutBucketAcl_invalid_owner, "PutBucketAcl_invalid_owner_not_in_body": PutBucketAcl_invalid_owner_not_in_body, + "PutBucketAcl_invalid_empty_owner_id_in_body": PutBucketAcl_invalid_empty_owner_id_in_body, + "PutBucketAcl_invalid_permission_in_body": PutBucketAcl_invalid_permission_in_body, + "PutBucketAcl_invalid_grantee_type_in_body": PutBucketAcl_invalid_grantee_type_in_body, + "PutBucketAcl_empty_grantee_ID_in_body": PutBucketAcl_empty_grantee_ID_in_body, "PutBucketAcl_success_access_denied": PutBucketAcl_success_access_denied, "PutBucketAcl_success_grants": PutBucketAcl_success_grants, "PutBucketAcl_success_canned_acl": PutBucketAcl_success_canned_acl, diff --git a/tests/integration/tests.go b/tests/integration/tests.go index 78ec389..17483e8 100644 --- a/tests/integration/tests.go +++ b/tests/integration/tests.go @@ -7653,6 +7653,7 @@ func PutBucketAcl_invalid_acl_canned_and_grants(s *S3Conf) error { ID: getPtr("awsID"), Type: types.TypeCanonicalUser, }, + Permission: types.PermissionFullControl, }, }, Owner: &types.Owner{ @@ -7683,6 +7684,7 @@ func PutBucketAcl_invalid_acl_acp_and_grants(s *S3Conf) error { ID: getPtr("awsID"), Type: types.TypeCanonicalUser, }, + Permission: types.PermissionFullControl, }, }, Owner: &types.Owner{ @@ -7728,6 +7730,7 @@ func PutBucketAcl_invalid_owner(s *S3Conf) error { ID: getPtr(usr.access), Type: types.TypeCanonicalUser, }, + Permission: types.PermissionRead, }, }, Owner: &types.Owner{ @@ -7775,6 +7778,124 @@ func PutBucketAcl_invalid_owner_not_in_body(s *S3Conf) error { }, 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 {