[#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
}
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 {
res := &AccessControlPolicy{
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)
@ -1653,22 +1673,20 @@ func (h *handler) encodeObjectACL(ctx context.Context, bucketACL *layer.BucketAC
}
if len(op.Users) == 0 {
list := append(m[allUsersGroup], op.Op)
m[allUsersGroup] = list
m.addAccess(allUsersGroup, op.Op)
} else {
for _, user := range op.Users {
list := append(m[user], op.Op)
m[user] = list
m.addAccess(user, op.Op)
}
}
}
}
for key, val := range m {
for _, val := range m.list {
permission := aclFullControl
read := true
for op := eacl.OperationGet; op <= eacl.OperationRangeHash; op++ {
if !contains(val, op) && !isWriteOperation(op) {
if !contains(val.operations, op) && !isWriteOperation(op) {
read = false
}
}
@ -1680,12 +1698,12 @@ func (h *handler) encodeObjectACL(ctx context.Context, bucketACL *layer.BucketAC
}
var grantee *Grantee
if key == allUsersGroup {
if val.recipient == allUsersGroup {
grantee = NewGrantee(acpGroup)
grantee.URI = allUsersGroup
} else {
grantee = NewGrantee(acpCanonicalUser)
grantee.ID = key
grantee.ID = val.recipient
}
grant := &Grant{