[#842] object/acl: Check owner and key only if sticky bit is set

In previous implementation node returns "access denied" on Object.Put with
object with unset owner. Although object owner must be set, its absence
should not be considered as access error. The same applies to sender key.

Check owner ID and public key emptiness only if sticky bit is set.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2021-11-08 13:49:20 +03:00 committed by Alex Vanin
parent 5e5211305c
commit d421022547
2 changed files with 41 additions and 4 deletions

View file

@ -581,10 +581,6 @@ func basicACLCheck(info requestInfo) bool {
}
func stickyBitCheck(info requestInfo, owner *owner.ID) bool {
if owner == nil || len(info.senderKey) == 0 {
return false
}
// According to NeoFS specification sticky bit has no effect on system nodes
// for correct intra-container work with objects (in particular, replication).
if info.requestRole == acl.RoleSystem {
@ -595,6 +591,10 @@ func stickyBitCheck(info requestInfo, owner *owner.ID) bool {
return true
}
if owner == nil || len(info.senderKey) == 0 {
return false
}
requestSenderKey := unmarshalPublicKey(info.senderKey)
return isOwnerFromKey(owner, requestSenderKey)

View file

@ -4,6 +4,7 @@ import (
"testing"
"github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
ownertest "github.com/nspcc-dev/neofs-api-go/pkg/owner/test"
"github.com/nspcc-dev/neofs-api-go/v2/acl"
acltest "github.com/nspcc-dev/neofs-api-go/v2/acl/test"
@ -50,4 +51,40 @@ func TestStickyCheck(t *testing.T) {
info.basicACL.ResetSticky()
require.True(t, stickyBitCheck(info, ownertest.Generate()))
})
t.Run("owner ID and/or public key emptiness", func(t *testing.T) {
var info requestInfo
info.requestRole = eacl.RoleOthers // should be non-system role
assertFn := func(isSticky, withKey, withOwner, expected bool) {
if isSticky {
info.basicACL.SetSticky()
} else {
info.basicACL.ResetSticky()
}
if withKey {
info.senderKey = make([]byte, 33)
} else {
info.senderKey = nil
}
var ownerID *owner.ID
if withOwner {
ownerID = ownertest.Generate()
}
require.Equal(t, expected, stickyBitCheck(info, ownerID))
}
assertFn(true, false, false, false)
assertFn(true, true, false, false)
assertFn(true, false, true, false)
assertFn(false, false, false, true)
assertFn(false, true, false, true)
assertFn(false, false, true, true)
assertFn(false, true, true, true)
})
}