Do not allow to create container without FrostFSID record, support/v0.42 #1281
4 changed files with 36 additions and 13 deletions
|
@ -3,7 +3,6 @@ package container
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -238,5 +237,5 @@ func (c *testMorphClient) NotarySignAndInvokeTX(mainTx *transaction.Transaction)
|
||||||
type testFrostFSIDClient struct{}
|
type testFrostFSIDClient struct{}
|
||||||
|
|
||||||
func (c *testFrostFSIDClient) GetSubject(addr util.Uint160) (*frostfsidclient.Subject, error) {
|
func (c *testFrostFSIDClient) GetSubject(addr util.Uint160) (*frostfsidclient.Subject, error) {
|
||||||
return nil, fmt.Errorf("subject not found")
|
return &frostfsidclient.Subject{}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,11 +180,6 @@ func (cp *Processor) checkNNS(ctx *putContainerContext, cnr containerSDK.Contain
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace, hasNamespace := strings.CutSuffix(ctx.d.Zone(), ".ns")
|
|
||||||
if !hasNamespace {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
addr, err := util.Uint160DecodeBytesBE(cnr.Owner().WalletBytes()[1 : 1+util.Uint160Size])
|
addr, err := util.Uint160DecodeBytesBE(cnr.Owner().WalletBytes()[1 : 1+util.Uint160Size])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not get container owner address: %w", err)
|
return fmt.Errorf("could not get container owner address: %w", err)
|
||||||
|
@ -195,6 +190,11 @@ func (cp *Processor) checkNNS(ctx *putContainerContext, cnr containerSDK.Contain
|
||||||
return fmt.Errorf("could not get subject from FrostfsID contract: %w", err)
|
return fmt.Errorf("could not get subject from FrostfsID contract: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace, hasNamespace := strings.CutSuffix(ctx.d.Zone(), ".ns")
|
||||||
|
if !hasNamespace {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if subject.Namespace != namespace {
|
if subject.Namespace != namespace {
|
||||||
return errContainerAndOwnerNamespaceDontMatch
|
return errContainerAndOwnerNamespaceDontMatch
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,7 +211,7 @@ func (ac *apeChecker) Put(ctx context.Context, req *container.PutRequest) (*cont
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace, err := ac.namespaceByOwner(req.GetBody().GetContainer().GetOwnerID())
|
namespace, err := ac.namespaceByKnownOwner(req.GetBody().GetContainer().GetOwnerID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("get namespace error: %w", err)
|
return nil, fmt.Errorf("get namespace error: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -608,6 +608,25 @@ func (ac *apeChecker) namespaceByOwner(owner *refs.OwnerID) (string, error) {
|
||||||
return namespace, nil
|
return namespace, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ac *apeChecker) namespaceByKnownOwner(owner *refs.OwnerID) (string, error) {
|
||||||
|
var ownerSDK user.ID
|
||||||
|
if owner == nil {
|
||||||
|
return "", errOwnerIDIsNotSet
|
||||||
|
}
|
||||||
|
if err := ownerSDK.ReadFromV2(*owner); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
addr, err := ownerSDK.ScriptHash()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
subject, err := ac.frostFSIDClient.GetSubject(addr)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("get subject error: %w", err)
|
||||||
|
}
|
||||||
|
return subject.Namespace, nil
|
||||||
|
}
|
||||||
|
|
||||||
// validateNamespace validates a namespace set in a container.
|
// validateNamespace validates a namespace set in a container.
|
||||||
// If frostfs-id contract stores a namespace N1 for an owner ID and a container within a request
|
// If frostfs-id contract stores a namespace N1 for an owner ID and a container within a request
|
||||||
// is set with namespace N2 (via Zone() property), then N2 is invalid and the request is denied.
|
// is set with namespace N2 (via Zone() property), then N2 is invalid and the request is denied.
|
||||||
|
|
|
@ -765,17 +765,22 @@ func testDenyPutContainerForOthersSessionToken(t *testing.T) {
|
||||||
keys: [][]byte{},
|
keys: [][]byte{},
|
||||||
}
|
}
|
||||||
nm := &netmapStub{}
|
nm := &netmapStub{}
|
||||||
frostfsIDSubjectReader := &frostfsidStub{
|
|
||||||
subjects: map[util.Uint160]*client.Subject{},
|
|
||||||
}
|
|
||||||
apeSrv := NewAPEServer(router, contRdr, ir, nm, frostfsIDSubjectReader, srv)
|
|
||||||
|
|
||||||
testContainer := containertest.Container()
|
testContainer := containertest.Container()
|
||||||
|
owner := testContainer.Owner()
|
||||||
|
ownerAddr, err := owner.ScriptHash()
|
||||||
|
require.NoError(t, err)
|
||||||
|
frostfsIDSubjectReader := &frostfsidStub{
|
||||||
|
subjects: map[util.Uint160]*client.Subject{
|
||||||
|
ownerAddr: {},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
apeSrv := NewAPEServer(router, contRdr, ir, nm, frostfsIDSubjectReader, srv)
|
||||||
|
|
||||||
nm.currentEpoch = 100
|
nm.currentEpoch = 100
|
||||||
nm.netmaps = map[uint64]*netmap.NetMap{}
|
nm.netmaps = map[uint64]*netmap.NetMap{}
|
||||||
|
|
||||||
_, _, err := router.MorphRuleChainStorage().AddMorphRuleChain(chain.Ingress, engine.NamespaceTarget(""), &chain.Chain{
|
_, _, err = router.MorphRuleChainStorage().AddMorphRuleChain(chain.Ingress, engine.NamespaceTarget(""), &chain.Chain{
|
||||||
Rules: []chain.Rule{
|
Rules: []chain.Rule{
|
||||||
{
|
{
|
||||||
Status: chain.AccessDenied,
|
Status: chain.AccessDenied,
|
||||||
|
|
Loading…
Reference in a new issue