Compare commits
3 commits
master
...
feat/ape_s
Author | SHA1 | Date | |
---|---|---|---|
75881cf908 | |||
ea668cf6cd | |||
55cb411185 |
8 changed files with 207 additions and 40 deletions
|
@ -9,6 +9,7 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
|
||||||
|
@ -27,8 +28,10 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||||
policyengine "git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
policyengine "git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
||||||
|
commonschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/common"
|
||||||
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
"google.golang.org/grpc/peer"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -88,7 +91,7 @@ func (ac *apeChecker) Delete(ctx context.Context, req *container.DeleteRequest)
|
||||||
ctx, span := tracing.StartSpanFromContext(ctx, "apeChecker.Delete")
|
ctx, span := tracing.StartSpanFromContext(ctx, "apeChecker.Delete")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if err := ac.validateContainerBoundedOperation(req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(),
|
if err := ac.validateContainerBoundedOperation(ctx, req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(),
|
||||||
nativeschema.MethodDeleteContainer); err != nil {
|
nativeschema.MethodDeleteContainer); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -100,7 +103,7 @@ func (ac *apeChecker) Get(ctx context.Context, req *container.GetRequest) (*cont
|
||||||
ctx, span := tracing.StartSpanFromContext(ctx, "apeChecker.Get")
|
ctx, span := tracing.StartSpanFromContext(ctx, "apeChecker.Get")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if err := ac.validateContainerBoundedOperation(req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(),
|
if err := ac.validateContainerBoundedOperation(ctx, req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(),
|
||||||
nativeschema.MethodGetContainer); err != nil {
|
nativeschema.MethodGetContainer); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -112,7 +115,7 @@ func (ac *apeChecker) GetExtendedACL(ctx context.Context, req *container.GetExte
|
||||||
ctx, span := tracing.StartSpanFromContext(ctx, "apeChecker.GetExtendedACL")
|
ctx, span := tracing.StartSpanFromContext(ctx, "apeChecker.GetExtendedACL")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if err := ac.validateContainerBoundedOperation(req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(),
|
if err := ac.validateContainerBoundedOperation(ctx, req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(),
|
||||||
nativeschema.MethodGetContainerEACL); err != nil {
|
nativeschema.MethodGetContainerEACL); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -138,6 +141,11 @@ func (ac *apeChecker) List(ctx context.Context, req *container.ListRequest) (*co
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if p, ok := peer.FromContext(ctx); ok {
|
||||||
|
if tcpAddr, ok := p.Addr.(*net.TCPAddr); ok {
|
||||||
|
reqProps[commonschema.PropertyKeyFrostFSSourceIP] = tcpAddr.IP.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace, err := ac.namespaceByOwner(req.GetBody().GetOwnerID())
|
namespace, err := ac.namespaceByOwner(req.GetBody().GetOwnerID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -191,6 +199,11 @@ func (ac *apeChecker) Put(ctx context.Context, req *container.PutRequest) (*cont
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if p, ok := peer.FromContext(ctx); ok {
|
||||||
|
if tcpAddr, ok := p.Addr.(*net.TCPAddr); ok {
|
||||||
|
reqProps[commonschema.PropertyKeyFrostFSSourceIP] = tcpAddr.IP.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace, err := ac.namespaceByOwner(req.GetBody().GetContainer().GetOwnerID())
|
namespace, err := ac.namespaceByOwner(req.GetBody().GetContainer().GetOwnerID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -264,7 +277,7 @@ func (ac *apeChecker) SetExtendedACL(ctx context.Context, req *container.SetExte
|
||||||
ctx, span := tracing.StartSpanFromContext(ctx, "apeChecker.SetExtendedACL")
|
ctx, span := tracing.StartSpanFromContext(ctx, "apeChecker.SetExtendedACL")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if err := ac.validateContainerBoundedOperation(req.GetBody().GetEACL().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(),
|
if err := ac.validateContainerBoundedOperation(ctx, req.GetBody().GetEACL().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(),
|
||||||
nativeschema.MethodSetContainerEACL); err != nil {
|
nativeschema.MethodSetContainerEACL); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -272,7 +285,7 @@ func (ac *apeChecker) SetExtendedACL(ctx context.Context, req *container.SetExte
|
||||||
return ac.next.SetExtendedACL(ctx, req)
|
return ac.next.SetExtendedACL(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ac *apeChecker) validateContainerBoundedOperation(containerID *refs.ContainerID, mh *session.RequestMetaHeader, vh *session.RequestVerificationHeader, op string) error {
|
func (ac *apeChecker) validateContainerBoundedOperation(ctx context.Context, containerID *refs.ContainerID, mh *session.RequestMetaHeader, vh *session.RequestVerificationHeader, op string) error {
|
||||||
if vh == nil {
|
if vh == nil {
|
||||||
return errMissingVerificationHeader
|
return errMissingVerificationHeader
|
||||||
}
|
}
|
||||||
|
@ -287,7 +300,7 @@ func (ac *apeChecker) validateContainerBoundedOperation(containerID *refs.Contai
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
reqProps, pk, err := ac.getRequestProps(mh, vh, cont, id)
|
reqProps, pk, err := ac.getRequestProps(ctx, mh, vh, cont, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -358,7 +371,7 @@ func (ac *apeChecker) getContainerProps(c *containercore.Container) map[string]s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ac *apeChecker) getRequestProps(mh *session.RequestMetaHeader, vh *session.RequestVerificationHeader,
|
func (ac *apeChecker) getRequestProps(ctx context.Context, mh *session.RequestMetaHeader, vh *session.RequestVerificationHeader,
|
||||||
cont *containercore.Container, cnrID cid.ID,
|
cont *containercore.Container, cnrID cid.ID,
|
||||||
) (map[string]string, *keys.PublicKey, error) {
|
) (map[string]string, *keys.PublicKey, error) {
|
||||||
actor, pk, err := ac.getActorAndPublicKey(mh, vh, cnrID)
|
actor, pk, err := ac.getActorAndPublicKey(mh, vh, cnrID)
|
||||||
|
@ -377,6 +390,11 @@ func (ac *apeChecker) getRequestProps(mh *session.RequestMetaHeader, vh *session
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
if p, ok := peer.FromContext(ctx); ok {
|
||||||
|
if tcpAddr, ok := p.Addr.(*net.TCPAddr); ok {
|
||||||
|
reqProps[commonschema.PropertyKeyFrostFSSourceIP] = tcpAddr.IP.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
return reqProps, pk, nil
|
return reqProps, pk, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl"
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl"
|
||||||
|
@ -32,6 +33,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"google.golang.org/grpc/peer"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -45,6 +47,7 @@ func TestAPE(t *testing.T) {
|
||||||
t.Run("deny get container no rule found", testDenyGetContainerNoRuleFound)
|
t.Run("deny get container no rule found", testDenyGetContainerNoRuleFound)
|
||||||
t.Run("deny get container for others", testDenyGetContainerForOthers)
|
t.Run("deny get container for others", testDenyGetContainerForOthers)
|
||||||
t.Run("deny get container by user claim tag", testDenyGetContainerByUserClaimTag)
|
t.Run("deny get container by user claim tag", testDenyGetContainerByUserClaimTag)
|
||||||
|
t.Run("deny get container by IP", testDenyGetContainerByIP)
|
||||||
t.Run("deny get container by group id", testDenyGetContainerByGroupID)
|
t.Run("deny get container by group id", testDenyGetContainerByGroupID)
|
||||||
t.Run("deny set container eACL for IR", testDenySetContainerEACLForIR)
|
t.Run("deny set container eACL for IR", testDenySetContainerEACLForIR)
|
||||||
t.Run("deny get container eACL for IR with session token", testDenyGetContainerEACLForIRSessionToken)
|
t.Run("deny get container eACL for IR with session token", testDenyGetContainerEACLForIRSessionToken)
|
||||||
|
@ -55,6 +58,19 @@ func TestAPE(t *testing.T) {
|
||||||
t.Run("deny list containers by namespace invalidation", testDenyListContainersValidationNamespaceError)
|
t.Run("deny list containers by namespace invalidation", testDenyListContainersValidationNamespaceError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
incomingIP = "192.92.33.1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ctxWithPeerInfo() context.Context {
|
||||||
|
return peer.NewContext(context.Background(), &peer.Peer{
|
||||||
|
Addr: &net.TCPAddr{
|
||||||
|
IP: net.ParseIP(incomingIP),
|
||||||
|
Port: 41111,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func testAllowThenDenyGetContainerRuleDefined(t *testing.T) {
|
func testAllowThenDenyGetContainerRuleDefined(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
srv := &srvStub{
|
srv := &srvStub{
|
||||||
|
@ -353,6 +369,105 @@ func testDenyGetContainerByUserClaimTag(t *testing.T) {
|
||||||
require.ErrorAs(t, err, &errAccessDenied)
|
require.ErrorAs(t, err, &errAccessDenied)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testDenyGetContainerByIP(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
srv := &srvStub{
|
||||||
|
calls: map[string]int{},
|
||||||
|
}
|
||||||
|
router := inmemory.NewInMemory()
|
||||||
|
contRdr := &containerStub{
|
||||||
|
c: map[cid.ID]*containercore.Container{},
|
||||||
|
}
|
||||||
|
ir := &irStub{
|
||||||
|
keys: [][]byte{},
|
||||||
|
}
|
||||||
|
nm := &netmapStub{}
|
||||||
|
pk, err := keys.NewPrivateKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
frostfsIDSubjectReader := &frostfsidStub{
|
||||||
|
subjects: map[util.Uint160]*client.Subject{
|
||||||
|
pk.PublicKey().GetScriptHash(): {
|
||||||
|
KV: map[string]string{
|
||||||
|
"tag-attr1": "value1",
|
||||||
|
"tag-attr2": "value2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
subjectsExt: map[util.Uint160]*client.SubjectExtended{
|
||||||
|
pk.PublicKey().GetScriptHash(): {
|
||||||
|
KV: map[string]string{
|
||||||
|
"tag-attr1": "value1",
|
||||||
|
"tag-attr2": "value2",
|
||||||
|
},
|
||||||
|
Groups: []*client.Group{
|
||||||
|
{
|
||||||
|
ID: 19888,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
apeSrv := NewAPEServer(router, contRdr, ir, nm, frostfsIDSubjectReader, srv)
|
||||||
|
|
||||||
|
contID := cidtest.ID()
|
||||||
|
testContainer := containertest.Container()
|
||||||
|
pp := netmap.PlacementPolicy{}
|
||||||
|
require.NoError(t, pp.DecodeString("REP 1"))
|
||||||
|
testContainer.SetPlacementPolicy(pp)
|
||||||
|
contRdr.c[contID] = &containercore.Container{Value: testContainer}
|
||||||
|
|
||||||
|
nm.currentEpoch = 100
|
||||||
|
nm.netmaps = map[uint64]*netmap.NetMap{}
|
||||||
|
var testNetmap netmap.NetMap
|
||||||
|
testNetmap.SetEpoch(nm.currentEpoch)
|
||||||
|
testNetmap.SetNodes([]netmap.NodeInfo{{}})
|
||||||
|
nm.netmaps[nm.currentEpoch] = &testNetmap
|
||||||
|
nm.netmaps[nm.currentEpoch-1] = &testNetmap
|
||||||
|
|
||||||
|
_, _, err = router.MorphRuleChainStorage().AddMorphRuleChain(chain.Ingress, engine.ContainerTarget(contID.EncodeToString()), &chain.Chain{
|
||||||
|
Rules: []chain.Rule{
|
||||||
|
{
|
||||||
|
Status: chain.AccessDenied,
|
||||||
|
Actions: chain.Actions{
|
||||||
|
Names: []string{
|
||||||
|
nativeschema.MethodGetContainer,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Resources: chain.Resources{
|
||||||
|
Names: []string{
|
||||||
|
fmt.Sprintf(nativeschema.ResourceFormatRootContainer, contID.EncodeToString()),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Condition: []chain.Condition{
|
||||||
|
{
|
||||||
|
Kind: chain.KindRequest,
|
||||||
|
Key: commonschema.PropertyKeyFrostFSSourceIP,
|
||||||
|
Value: incomingIP + "/16",
|
||||||
|
Op: chain.CondIPAddress,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
req := &container.GetRequest{}
|
||||||
|
req.SetBody(&container.GetRequestBody{})
|
||||||
|
var refContID refs.ContainerID
|
||||||
|
contID.WriteToV2(&refContID)
|
||||||
|
req.GetBody().SetContainerID(&refContID)
|
||||||
|
|
||||||
|
require.NoError(t, signature.SignServiceMessage(&pk.PrivateKey, req))
|
||||||
|
|
||||||
|
resp, err := apeSrv.Get(ctxWithPeerInfo(), req)
|
||||||
|
require.Nil(t, resp)
|
||||||
|
var errAccessDenied *apistatus.ObjectAccessDenied
|
||||||
|
require.ErrorAs(t, err, &errAccessDenied)
|
||||||
|
require.Contains(t, errAccessDenied.Reason(), chain.AccessDenied.String())
|
||||||
|
}
|
||||||
|
|
||||||
func testDenyGetContainerByGroupID(t *testing.T) {
|
func testDenyGetContainerByGroupID(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
srv := &srvStub{
|
srv := &srvStub{
|
||||||
|
@ -1208,7 +1323,7 @@ func TestValidateContainerBoundedOperation(t *testing.T) {
|
||||||
|
|
||||||
req := initTestGetContainerRequest(t, contID)
|
req := initTestGetContainerRequest(t, contID)
|
||||||
|
|
||||||
err = components.apeChecker.validateContainerBoundedOperation(req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(), nativeschema.MethodGetContainer)
|
err = components.apeChecker.validateContainerBoundedOperation(ctxWithPeerInfo(), req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(), nativeschema.MethodGetContainer)
|
||||||
aErr := apeErr(nativeschema.MethodGetContainer, chain.AccessDenied)
|
aErr := apeErr(nativeschema.MethodGetContainer, chain.AccessDenied)
|
||||||
require.ErrorContains(t, err, aErr.Error())
|
require.ErrorContains(t, err, aErr.Error())
|
||||||
})
|
})
|
||||||
|
@ -1252,7 +1367,7 @@ func TestValidateContainerBoundedOperation(t *testing.T) {
|
||||||
|
|
||||||
req := initTestGetContainerRequest(t, contID)
|
req := initTestGetContainerRequest(t, contID)
|
||||||
|
|
||||||
err = components.apeChecker.validateContainerBoundedOperation(req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(), nativeschema.MethodGetContainer)
|
err = components.apeChecker.validateContainerBoundedOperation(ctxWithPeerInfo(), req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(), nativeschema.MethodGetContainer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1295,7 +1410,7 @@ func TestValidateContainerBoundedOperation(t *testing.T) {
|
||||||
|
|
||||||
req := initTestGetContainerRequest(t, contID)
|
req := initTestGetContainerRequest(t, contID)
|
||||||
|
|
||||||
err = components.apeChecker.validateContainerBoundedOperation(req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(), nativeschema.MethodGetContainer)
|
err = components.apeChecker.validateContainerBoundedOperation(ctxWithPeerInfo(), req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(), nativeschema.MethodGetContainer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1338,7 +1453,7 @@ func TestValidateContainerBoundedOperation(t *testing.T) {
|
||||||
|
|
||||||
req := initTestGetContainerRequest(t, contID)
|
req := initTestGetContainerRequest(t, contID)
|
||||||
|
|
||||||
err = components.apeChecker.validateContainerBoundedOperation(req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(), nativeschema.MethodGetContainer)
|
err = components.apeChecker.validateContainerBoundedOperation(ctxWithPeerInfo(), req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(), nativeschema.MethodGetContainer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1381,7 +1496,7 @@ func TestValidateContainerBoundedOperation(t *testing.T) {
|
||||||
|
|
||||||
req := initTestGetContainerRequest(t, contID)
|
req := initTestGetContainerRequest(t, contID)
|
||||||
|
|
||||||
err = components.apeChecker.validateContainerBoundedOperation(req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(), nativeschema.MethodGetContainer)
|
err = components.apeChecker.validateContainerBoundedOperation(ctxWithPeerInfo(), req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(), nativeschema.MethodGetContainer)
|
||||||
aErr := apeErr(nativeschema.MethodGetContainer, chain.AccessDenied)
|
aErr := apeErr(nativeschema.MethodGetContainer, chain.AccessDenied)
|
||||||
require.ErrorContains(t, err, aErr.Error())
|
require.ErrorContains(t, err, aErr.Error())
|
||||||
})
|
})
|
||||||
|
@ -1423,7 +1538,7 @@ func TestValidateContainerBoundedOperation(t *testing.T) {
|
||||||
|
|
||||||
req := initTestGetContainerRequest(t, contID)
|
req := initTestGetContainerRequest(t, contID)
|
||||||
|
|
||||||
err = components.apeChecker.validateContainerBoundedOperation(req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(), nativeschema.MethodGetContainer)
|
err = components.apeChecker.validateContainerBoundedOperation(ctxWithPeerInfo(), req.GetBody().GetContainerID(), req.GetMetaHeader(), req.GetVerificationHeader(), nativeschema.MethodGetContainer)
|
||||||
aErr := apeErr(nativeschema.MethodGetContainer, chain.AccessDenied)
|
aErr := apeErr(nativeschema.MethodGetContainer, chain.AccessDenied)
|
||||||
require.ErrorContains(t, err, aErr.Error())
|
require.ErrorContains(t, err, aErr.Error())
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||||
|
@ -15,8 +16,10 @@ import (
|
||||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
|
commonschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/common"
|
||||||
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
"google.golang.org/grpc/peer"
|
||||||
)
|
)
|
||||||
|
|
||||||
var defaultRequest = aperequest.Request{}
|
var defaultRequest = aperequest.Request{}
|
||||||
|
@ -129,6 +132,12 @@ func (c *checkerImpl) newAPERequest(ctx context.Context, prm Prm) (aperequest.Re
|
||||||
return defaultRequest, err
|
return defaultRequest, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if p, ok := peer.FromContext(ctx); ok {
|
||||||
|
if tcpAddr, ok := p.Addr.(*net.TCPAddr); ok {
|
||||||
|
reqProps[commonschema.PropertyKeyFrostFSSourceIP] = tcpAddr.IP.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return aperequest.NewRequest(
|
return aperequest.NewRequest(
|
||||||
prm.Method,
|
prm.Method,
|
||||||
aperequest.NewResource(
|
aperequest.NewResource(
|
||||||
|
|
|
@ -3,6 +3,7 @@ package ape
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||||
|
@ -14,12 +15,24 @@ import (
|
||||||
commonschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/common"
|
commonschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/common"
|
||||||
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"google.golang.org/grpc/peer"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
testOwnerID = "FPPtmAi9TCX329"
|
testOwnerID = "FPPtmAi9TCX329"
|
||||||
|
|
||||||
|
incomingIP = "192.92.33.1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func ctxWithPeerInfo() context.Context {
|
||||||
|
return peer.NewContext(context.Background(), &peer.Peer{
|
||||||
|
Addr: &net.TCPAddr{
|
||||||
|
IP: net.ParseIP(incomingIP),
|
||||||
|
Port: 41111,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestObjectProperties(t *testing.T) {
|
func TestObjectProperties(t *testing.T) {
|
||||||
for _, test := range []struct {
|
for _, test := range []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -253,7 +266,7 @@ func TestNewAPERequest(t *testing.T) {
|
||||||
frostFSIDClient: ffidProvider,
|
frostFSIDClient: ffidProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := c.newAPERequest(context.TODO(), prm)
|
r, err := c.newAPERequest(ctxWithPeerInfo(), prm)
|
||||||
if test.expectErr != nil {
|
if test.expectErr != nil {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.ErrorIs(t, err, test.expectErr)
|
require.ErrorIs(t, err, test.expectErr)
|
||||||
|
@ -276,6 +289,7 @@ func TestNewAPERequest(t *testing.T) {
|
||||||
fmt.Sprintf(commonschema.PropertyKeyFormatFrostFSIDUserClaim, "tag-attr1"): "value1",
|
fmt.Sprintf(commonschema.PropertyKeyFormatFrostFSIDUserClaim, "tag-attr1"): "value1",
|
||||||
fmt.Sprintf(commonschema.PropertyKeyFormatFrostFSIDUserClaim, "tag-attr2"): "value2",
|
fmt.Sprintf(commonschema.PropertyKeyFormatFrostFSIDUserClaim, "tag-attr2"): "value2",
|
||||||
commonschema.PropertyKeyFrostFSIDGroupID: "1",
|
commonschema.PropertyKeyFrostFSIDGroupID: "1",
|
||||||
|
commonschema.PropertyKeyFrostFSSourceIP: incomingIP,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package tree
|
package tree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/converter"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/converter"
|
||||||
|
@ -14,11 +16,13 @@ import (
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
||||||
|
commonschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/common"
|
||||||
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
"google.golang.org/grpc/peer"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Service) checkAPE(container *core.Container, cid cid.ID, operation acl.Op, role acl.Role, publicKey *keys.PublicKey) error {
|
func (s *Service) checkAPE(ctx context.Context, container *core.Container, cid cid.ID, operation acl.Op, role acl.Role, publicKey *keys.PublicKey) error {
|
||||||
namespace := ""
|
namespace := ""
|
||||||
cntNamespace, hasNamespace := strings.CutSuffix(cnrSDK.ReadDomain(container.Value).Zone(), ".ns")
|
cntNamespace, hasNamespace := strings.CutSuffix(cnrSDK.ReadDomain(container.Value).Zone(), ".ns")
|
||||||
if hasNamespace {
|
if hasNamespace {
|
||||||
|
@ -41,6 +45,11 @@ func (s *Service) checkAPE(container *core.Container, cid cid.ID, operation acl.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return apeErr(err)
|
return apeErr(err)
|
||||||
}
|
}
|
||||||
|
if p, ok := peer.FromContext(ctx); ok {
|
||||||
|
if tcpAddr, ok := p.Addr.(*net.TCPAddr); ok {
|
||||||
|
reqProps[commonschema.PropertyKeyFrostFSSourceIP] = tcpAddr.IP.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var resourceName string
|
var resourceName string
|
||||||
if namespace == "root" || namespace == "" {
|
if namespace == "root" || namespace == "" {
|
||||||
|
|
|
@ -105,7 +105,7 @@ func (s *Service) Add(ctx context.Context, req *AddRequest) (*AddResponse, error
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.verifyClient(req, cid, b.GetBearerToken(), acl.OpObjectPut)
|
err := s.verifyClient(ctx, req, cid, b.GetBearerToken(), acl.OpObjectPut)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,7 @@ func (s *Service) AddByPath(ctx context.Context, req *AddByPathRequest) (*AddByP
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.verifyClient(req, cid, b.GetBearerToken(), acl.OpObjectPut)
|
err := s.verifyClient(ctx, req, cid, b.GetBearerToken(), acl.OpObjectPut)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ func (s *Service) Remove(ctx context.Context, req *RemoveRequest) (*RemoveRespon
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.verifyClient(req, cid, b.GetBearerToken(), acl.OpObjectPut)
|
err := s.verifyClient(ctx, req, cid, b.GetBearerToken(), acl.OpObjectPut)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -274,7 +274,7 @@ func (s *Service) Move(ctx context.Context, req *MoveRequest) (*MoveResponse, er
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.verifyClient(req, cid, b.GetBearerToken(), acl.OpObjectPut)
|
err := s.verifyClient(ctx, req, cid, b.GetBearerToken(), acl.OpObjectPut)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -326,7 +326,7 @@ func (s *Service) GetNodeByPath(ctx context.Context, req *GetNodeByPathRequest)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.verifyClient(req, cid, b.GetBearerToken(), acl.OpObjectGet)
|
err := s.verifyClient(ctx, req, cid, b.GetBearerToken(), acl.OpObjectGet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -408,7 +408,7 @@ func (s *Service) GetSubTree(req *GetSubTreeRequest, srv TreeService_GetSubTreeS
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.verifyClient(req, cid, b.GetBearerToken(), acl.OpObjectGet)
|
err := s.verifyClient(srv.Context(), req, cid, b.GetBearerToken(), acl.OpObjectGet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package tree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -48,7 +49,7 @@ var (
|
||||||
// Operation must be one of:
|
// Operation must be one of:
|
||||||
// - 1. ObjectPut;
|
// - 1. ObjectPut;
|
||||||
// - 2. ObjectGet.
|
// - 2. ObjectGet.
|
||||||
func (s *Service) verifyClient(req message, cid cidSDK.ID, rawBearer []byte, op acl.Op) error {
|
func (s *Service) verifyClient(ctx context.Context, req message, cid cidSDK.ID, rawBearer []byte, op acl.Op) error {
|
||||||
err := verifyMessage(req)
|
err := verifyMessage(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -83,7 +84,7 @@ func (s *Service) verifyClient(req message, cid cidSDK.ID, rawBearer []byte, op
|
||||||
// FIXME(@aarifullin): tree service temporiraly performs APE checks on
|
// FIXME(@aarifullin): tree service temporiraly performs APE checks on
|
||||||
// object verbs, because tree verbs have not been introduced yet.
|
// object verbs, because tree verbs have not been introduced yet.
|
||||||
if basicACL == 0x0 {
|
if basicACL == 0x0 {
|
||||||
return s.checkAPE(cnr, cid, op, role, pubKey)
|
return s.checkAPE(ctx, cnr, cid, op, role, pubKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !basicACL.IsOpAllowed(op, role) {
|
if !basicACL.IsOpAllowed(op, role) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package tree
|
package tree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -132,26 +133,26 @@ func TestMessageSign(t *testing.T) {
|
||||||
cnr.Value.SetBasicACL(acl.PublicRW)
|
cnr.Value.SetBasicACL(acl.PublicRW)
|
||||||
|
|
||||||
t.Run("missing signature, no panic", func(t *testing.T) {
|
t.Run("missing signature, no panic", func(t *testing.T) {
|
||||||
require.Error(t, s.verifyClient(req, cid2, nil, op))
|
require.Error(t, s.verifyClient(context.Background(), req, cid2, nil, op))
|
||||||
})
|
})
|
||||||
|
|
||||||
require.NoError(t, SignMessage(req, &privs[0].PrivateKey))
|
require.NoError(t, SignMessage(req, &privs[0].PrivateKey))
|
||||||
require.NoError(t, s.verifyClient(req, cid1, nil, op))
|
require.NoError(t, s.verifyClient(context.Background(), req, cid1, nil, op))
|
||||||
|
|
||||||
t.Run("invalid CID", func(t *testing.T) {
|
t.Run("invalid CID", func(t *testing.T) {
|
||||||
require.Error(t, s.verifyClient(req, cid2, nil, op))
|
require.Error(t, s.verifyClient(context.Background(), req, cid2, nil, op))
|
||||||
})
|
})
|
||||||
|
|
||||||
cnr.Value.SetBasicACL(acl.Private)
|
cnr.Value.SetBasicACL(acl.Private)
|
||||||
|
|
||||||
t.Run("extension disabled", func(t *testing.T) {
|
t.Run("extension disabled", func(t *testing.T) {
|
||||||
require.NoError(t, SignMessage(req, &privs[0].PrivateKey))
|
require.NoError(t, SignMessage(req, &privs[0].PrivateKey))
|
||||||
require.Error(t, s.verifyClient(req, cid2, nil, op))
|
require.Error(t, s.verifyClient(context.Background(), req, cid2, nil, op))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("invalid key", func(t *testing.T) {
|
t.Run("invalid key", func(t *testing.T) {
|
||||||
require.NoError(t, SignMessage(req, &privs[1].PrivateKey))
|
require.NoError(t, SignMessage(req, &privs[1].PrivateKey))
|
||||||
require.Error(t, s.verifyClient(req, cid1, nil, op))
|
require.Error(t, s.verifyClient(context.Background(), req, cid1, nil, op))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("bearer", func(t *testing.T) {
|
t.Run("bearer", func(t *testing.T) {
|
||||||
|
@ -164,7 +165,7 @@ func TestMessageSign(t *testing.T) {
|
||||||
t.Run("invalid bearer", func(t *testing.T) {
|
t.Run("invalid bearer", func(t *testing.T) {
|
||||||
req.Body.BearerToken = []byte{0xFF}
|
req.Body.BearerToken = []byte{0xFF}
|
||||||
require.NoError(t, SignMessage(req, &privs[0].PrivateKey))
|
require.NoError(t, SignMessage(req, &privs[0].PrivateKey))
|
||||||
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
|
require.Error(t, s.verifyClient(context.Background(), req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("invalid bearer CID", func(t *testing.T) {
|
t.Run("invalid bearer CID", func(t *testing.T) {
|
||||||
|
@ -173,7 +174,7 @@ func TestMessageSign(t *testing.T) {
|
||||||
req.Body.BearerToken = bt.Marshal()
|
req.Body.BearerToken = bt.Marshal()
|
||||||
|
|
||||||
require.NoError(t, SignMessage(req, &privs[1].PrivateKey))
|
require.NoError(t, SignMessage(req, &privs[1].PrivateKey))
|
||||||
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
|
require.Error(t, s.verifyClient(context.Background(), req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
|
||||||
})
|
})
|
||||||
t.Run("invalid bearer owner", func(t *testing.T) {
|
t.Run("invalid bearer owner", func(t *testing.T) {
|
||||||
bt := testBearerToken(cid1, privs[1].PublicKey(), privs[2].PublicKey())
|
bt := testBearerToken(cid1, privs[1].PublicKey(), privs[2].PublicKey())
|
||||||
|
@ -181,7 +182,7 @@ func TestMessageSign(t *testing.T) {
|
||||||
req.Body.BearerToken = bt.Marshal()
|
req.Body.BearerToken = bt.Marshal()
|
||||||
|
|
||||||
require.NoError(t, SignMessage(req, &privs[1].PrivateKey))
|
require.NoError(t, SignMessage(req, &privs[1].PrivateKey))
|
||||||
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
|
require.Error(t, s.verifyClient(context.Background(), req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
|
||||||
})
|
})
|
||||||
t.Run("invalid bearer signature", func(t *testing.T) {
|
t.Run("invalid bearer signature", func(t *testing.T) {
|
||||||
bt := testBearerToken(cid1, privs[1].PublicKey(), privs[2].PublicKey())
|
bt := testBearerToken(cid1, privs[1].PublicKey(), privs[2].PublicKey())
|
||||||
|
@ -193,7 +194,7 @@ func TestMessageSign(t *testing.T) {
|
||||||
req.Body.BearerToken = bv2.StableMarshal(nil)
|
req.Body.BearerToken = bv2.StableMarshal(nil)
|
||||||
|
|
||||||
require.NoError(t, SignMessage(req, &privs[1].PrivateKey))
|
require.NoError(t, SignMessage(req, &privs[1].PrivateKey))
|
||||||
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
|
require.Error(t, s.verifyClient(context.Background(), req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("impersonate", func(t *testing.T) {
|
t.Run("impersonate", func(t *testing.T) {
|
||||||
|
@ -205,8 +206,8 @@ func TestMessageSign(t *testing.T) {
|
||||||
req.Body.BearerToken = bt.Marshal()
|
req.Body.BearerToken = bt.Marshal()
|
||||||
|
|
||||||
require.NoError(t, SignMessage(req, &privs[0].PrivateKey))
|
require.NoError(t, SignMessage(req, &privs[0].PrivateKey))
|
||||||
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
|
require.Error(t, s.verifyClient(context.Background(), req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
|
||||||
require.NoError(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectGet))
|
require.NoError(t, s.verifyClient(context.Background(), req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectGet))
|
||||||
})
|
})
|
||||||
|
|
||||||
bt := testBearerToken(cid1, privs[1].PublicKey(), privs[2].PublicKey())
|
bt := testBearerToken(cid1, privs[1].PublicKey(), privs[2].PublicKey())
|
||||||
|
@ -216,18 +217,18 @@ func TestMessageSign(t *testing.T) {
|
||||||
|
|
||||||
t.Run("put and get", func(t *testing.T) {
|
t.Run("put and get", func(t *testing.T) {
|
||||||
require.NoError(t, SignMessage(req, &privs[1].PrivateKey))
|
require.NoError(t, SignMessage(req, &privs[1].PrivateKey))
|
||||||
require.NoError(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
|
require.NoError(t, s.verifyClient(context.Background(), req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
|
||||||
require.NoError(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectGet))
|
require.NoError(t, s.verifyClient(context.Background(), req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectGet))
|
||||||
})
|
})
|
||||||
t.Run("only get", func(t *testing.T) {
|
t.Run("only get", func(t *testing.T) {
|
||||||
require.NoError(t, SignMessage(req, &privs[2].PrivateKey))
|
require.NoError(t, SignMessage(req, &privs[2].PrivateKey))
|
||||||
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
|
require.Error(t, s.verifyClient(context.Background(), req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
|
||||||
require.NoError(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectGet))
|
require.NoError(t, s.verifyClient(context.Background(), req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectGet))
|
||||||
})
|
})
|
||||||
t.Run("none", func(t *testing.T) {
|
t.Run("none", func(t *testing.T) {
|
||||||
require.NoError(t, SignMessage(req, &privs[3].PrivateKey))
|
require.NoError(t, SignMessage(req, &privs[3].PrivateKey))
|
||||||
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
|
require.Error(t, s.verifyClient(context.Background(), req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectPut))
|
||||||
require.Error(t, s.verifyClient(req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectGet))
|
require.Error(t, s.verifyClient(context.Background(), req, cid1, req.GetBody().GetBearerToken(), acl.OpObjectGet))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue