From d4210225476c0b7fa187c63af8660c1f09b900e4 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Mon, 8 Nov 2021 13:49:20 +0300 Subject: [PATCH] [#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 --- pkg/services/object/acl/acl.go | 8 +++---- pkg/services/object/acl/acl_test.go | 37 +++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/pkg/services/object/acl/acl.go b/pkg/services/object/acl/acl.go index 66fbeb7394..6b0ba2e68f 100644 --- a/pkg/services/object/acl/acl.go +++ b/pkg/services/object/acl/acl.go @@ -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) diff --git a/pkg/services/object/acl/acl_test.go b/pkg/services/object/acl/acl_test.go index 22173d8362..23aa5e91e9 100644 --- a/pkg/services/object/acl/acl_test.go +++ b/pkg/services/object/acl/acl_test.go @@ -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) + }) }