[#1628] tree: Make ACL checks the same way as for object requests

1. Do not require a request to be signed by the container owner if a
bearer token is missing
2. Do not check the system role since public requests are not expected to
be signed by IR or a container node (unlike the object requests)

Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
Pavel Karpy 2022-09-08 15:44:27 +03:00 committed by fyrchik
parent 4f18893d9b
commit 876e014b5d
5 changed files with 171 additions and 72 deletions

View file

@ -7,11 +7,12 @@ import (
"testing"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neofs-api-go/v2/acl"
aclV2 "github.com/nspcc-dev/neofs-api-go/v2/acl"
containercore "github.com/nspcc-dev/neofs-node/pkg/core/container"
"github.com/nspcc-dev/neofs-node/pkg/core/netmap"
"github.com/nspcc-dev/neofs-sdk-go/bearer"
"github.com/nspcc-dev/neofs-sdk-go/container"
"github.com/nspcc-dev/neofs-sdk-go/container/acl"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
eaclSDK "github.com/nspcc-dev/neofs-sdk-go/eacl"
@ -63,15 +64,17 @@ func TestMessageSign(t *testing.T) {
var ownerID user.ID
user.IDFromKey(&ownerID, (ecdsa.PublicKey)(*privs[0].PublicKey()))
cnr := &containercore.Container{
Value: testContainer(ownerID),
}
s := &Service{
cfg: cfg{
log: zaptest.NewLogger(t),
key: &privs[0].PrivateKey,
nmSource: dummyNetmapSource{},
cnrSource: dummyContainerSource{
cid1.String(): &containercore.Container{
Value: testContainer(ownerID),
},
cid1.String(): cnr,
},
},
}
@ -90,26 +93,43 @@ func TestMessageSign(t *testing.T) {
},
}
op := acl.OpObjectPut
cnr.Value.SetBasicACL(acl.PublicRW)
t.Run("missing signature, no panic", func(t *testing.T) {
require.Error(t, s.verifyClient(req, cid2, nil, eaclSDK.OperationUnknown))
require.Error(t, s.verifyClient(req, cid2, nil, op))
})
require.NoError(t, signMessage(req, &privs[0].PrivateKey))
require.NoError(t, s.verifyClient(req, cid1, nil, eaclSDK.OperationUnknown))
require.NoError(t, s.verifyClient(req, cid1, nil, op))
t.Run("invalid CID", func(t *testing.T) {
require.Error(t, s.verifyClient(req, cid2, nil, eaclSDK.OperationUnknown))
require.Error(t, s.verifyClient(req, cid2, nil, op))
})
cnr.Value.SetBasicACL(acl.Private)
t.Run("extension disabled", func(t *testing.T) {
require.NoError(t, signMessage(req, &privs[0].PrivateKey))
require.Error(t, s.verifyClient(req, cid2, nil, op))
})
t.Run("invalid key", func(t *testing.T) {
require.NoError(t, signMessage(req, &privs[1].PrivateKey))
require.Error(t, s.verifyClient(req, cid1, nil, eaclSDK.OperationUnknown))
require.Error(t, s.verifyClient(req, cid1, nil, op))
})
t.Run("bearer", func(t *testing.T) {
bACL := acl.PrivateExtended
bACL.AllowBearerRules(op)
cnr.Value.SetBasicACL(bACL)
bACL.DisableExtension()
t.Run("invalid bearer", func(t *testing.T) {
req.Body.BearerToken = []byte{0xFF}
require.NoError(t, signMessage(req, &privs[0].PrivateKey))
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), eaclSDK.OperationPut))
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
})
t.Run("invalid bearer CID", func(t *testing.T) {
@ -118,7 +138,7 @@ func TestMessageSign(t *testing.T) {
req.Body.BearerToken = bt.Marshal()
require.NoError(t, signMessage(req, &privs[1].PrivateKey))
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), eaclSDK.OperationPut))
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
})
t.Run("invalid bearer owner", func(t *testing.T) {
bt := testBearerToken(cid1, privs[1].PublicKey(), privs[2].PublicKey())
@ -126,47 +146,48 @@ func TestMessageSign(t *testing.T) {
req.Body.BearerToken = bt.Marshal()
require.NoError(t, signMessage(req, &privs[1].PrivateKey))
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), eaclSDK.OperationPut))
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
})
t.Run("invalid bearer signature", func(t *testing.T) {
bt := testBearerToken(cid1, privs[1].PublicKey(), privs[2].PublicKey())
require.NoError(t, bt.Sign(privs[0].PrivateKey))
var bv2 acl.BearerToken
var bv2 aclV2.BearerToken
bt.WriteToV2(&bv2)
bv2.GetSignature().SetSign([]byte{1, 2, 3})
req.Body.BearerToken = bv2.StableMarshal(nil)
require.NoError(t, signMessage(req, &privs[1].PrivateKey))
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), eaclSDK.OperationPut))
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
})
bt := testBearerToken(cid1, privs[1].PublicKey(), privs[2].PublicKey())
require.NoError(t, bt.Sign(privs[0].PrivateKey))
req.Body.BearerToken = bt.Marshal()
cnr.Value.SetBasicACL(acl.PublicRWExtended)
t.Run("put and get", func(t *testing.T) {
require.NoError(t, signMessage(req, &privs[1].PrivateKey))
require.NoError(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), eaclSDK.OperationPut))
require.NoError(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), eaclSDK.OperationGet))
require.NoError(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
require.NoError(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectGet))
})
t.Run("only get", func(t *testing.T) {
require.NoError(t, signMessage(req, &privs[2].PrivateKey))
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), eaclSDK.OperationPut))
require.NoError(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), eaclSDK.OperationGet))
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
require.NoError(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectGet))
})
t.Run("none", func(t *testing.T) {
require.NoError(t, signMessage(req, &privs[3].PrivateKey))
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), eaclSDK.OperationPut))
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), eaclSDK.OperationGet))
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectGet))
})
})
}
func testBearerToken(cid cid.ID, forPut, forGet *keys.PublicKey) bearer.Token {
func testBearerToken(cid cid.ID, forPutGet, forGet *keys.PublicKey) bearer.Token {
tgtGet := eaclSDK.NewTarget()
tgtGet.SetRole(eaclSDK.RoleUnknown)
tgtGet.SetBinaryKeys([][]byte{forPut.Bytes(), forGet.Bytes()})
tgtGet.SetBinaryKeys([][]byte{forPutGet.Bytes(), forGet.Bytes()})
rGet := eaclSDK.NewRecord()
rGet.SetAction(eaclSDK.ActionAllow)
@ -175,7 +196,7 @@ func testBearerToken(cid cid.ID, forPut, forGet *keys.PublicKey) bearer.Token {
tgtPut := eaclSDK.NewTarget()
tgtPut.SetRole(eaclSDK.RoleUnknown)
tgtPut.SetBinaryKeys([][]byte{forPut.Bytes()})
tgtPut.SetBinaryKeys([][]byte{forPutGet.Bytes()})
rPut := eaclSDK.NewRecord()
rPut.SetAction(eaclSDK.ActionAllow)