From d8889fca56ea04d9f758d0305f28822ea6a5631c Mon Sep 17 00:00:00 2001 From: Roman Loginov Date: Wed, 10 Apr 2024 09:59:01 +0300 Subject: [PATCH] [#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 --- api/handler/acl.go | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/api/handler/acl.go b/api/handler/acl.go index 6574cb42b..96d676ebf 100644 --- a/api/handler/acl.go +++ b/api/handler/acl.go @@ -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{