[#340] Fix encode object acl

In the process of encode the acl of an object,
we use a map. As a result, when traversing the
map, we can get a different sequence of permissions
each time. Therefore, a list is used instead of a map.

Signed-off-by: Roman Loginov <r.loginov@yadro.com>
This commit is contained in:
Roman Loginov 2024-04-10 09:59:01 +03:00 committed by Alexey Vanin
parent 61ff4702a2
commit d8889fca56

View file

@ -1630,6 +1630,26 @@ func isWriteOperation(op eacl.Operation) bool {
return op == eacl.OperationDelete || op == eacl.OperationPut return op == eacl.OperationDelete || op == eacl.OperationPut
} }
type access struct {
recipient string
operations []eacl.Operation
}
type accessList struct {
list []access
}
func (c *accessList) addAccess(recipient string, operation eacl.Operation) {
for i, v := range c.list {
if v.recipient == recipient {
c.list[i].operations = append(c.list[i].operations, operation)
return
}
}
c.list = append(c.list, access{recipient, []eacl.Operation{operation}})
}
func (h *handler) encodeObjectACL(ctx context.Context, bucketACL *layer.BucketACL, bucketName, objectVersion string) *AccessControlPolicy { func (h *handler) encodeObjectACL(ctx context.Context, bucketACL *layer.BucketACL, bucketName, objectVersion string) *AccessControlPolicy {
res := &AccessControlPolicy{ res := &AccessControlPolicy{
Owner: Owner{ Owner: Owner{
@ -1638,7 +1658,7 @@ func (h *handler) encodeObjectACL(ctx context.Context, bucketACL *layer.BucketAC
}, },
} }
m := make(map[string][]eacl.Operation) m := &accessList{}
astList := tableToAst(bucketACL.EACL, bucketName) astList := tableToAst(bucketACL.EACL, bucketName)
@ -1653,22 +1673,20 @@ func (h *handler) encodeObjectACL(ctx context.Context, bucketACL *layer.BucketAC
} }
if len(op.Users) == 0 { if len(op.Users) == 0 {
list := append(m[allUsersGroup], op.Op) m.addAccess(allUsersGroup, op.Op)
m[allUsersGroup] = list
} else { } else {
for _, user := range op.Users { for _, user := range op.Users {
list := append(m[user], op.Op) m.addAccess(user, op.Op)
m[user] = list
} }
} }
} }
} }
for key, val := range m { for _, val := range m.list {
permission := aclFullControl permission := aclFullControl
read := true read := true
for op := eacl.OperationGet; op <= eacl.OperationRangeHash; op++ { for op := eacl.OperationGet; op <= eacl.OperationRangeHash; op++ {
if !contains(val, op) && !isWriteOperation(op) { if !contains(val.operations, op) && !isWriteOperation(op) {
read = false read = false
} }
} }
@ -1680,12 +1698,12 @@ func (h *handler) encodeObjectACL(ctx context.Context, bucketACL *layer.BucketAC
} }
var grantee *Grantee var grantee *Grantee
if key == allUsersGroup { if val.recipient == allUsersGroup {
grantee = NewGrantee(acpGroup) grantee = NewGrantee(acpGroup)
grantee.URI = allUsersGroup grantee.URI = allUsersGroup
} else { } else {
grantee = NewGrantee(acpCanonicalUser) grantee = NewGrantee(acpCanonicalUser)
grantee.ID = key grantee.ID = val.recipient
} }
grant := &Grant{ grant := &Grant{