Validate token issuer #528
5 changed files with 95 additions and 120 deletions
|
@ -1,10 +1,8 @@
|
||||||
package object
|
package object
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/elliptic"
|
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -14,18 +12,20 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/netmap"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/netmap"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
||||||
netmapSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
|
||||||
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"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// FormatValidator represents an object format validator.
|
// FormatValidator represents an object format validator.
|
||||||
type FormatValidator struct {
|
type FormatValidator struct {
|
||||||
*cfg
|
*cfg
|
||||||
|
|
||||||
|
senderClassifier SenderClassifier
|
||||||
}
|
}
|
||||||
|
|
||||||
// FormatValidatorOption represents a FormatValidator constructor option.
|
// FormatValidatorOption represents a FormatValidator constructor option.
|
||||||
|
@ -37,13 +37,10 @@ type cfg struct {
|
||||||
ir InnerRing
|
ir InnerRing
|
||||||
netmap netmap.Source
|
netmap netmap.Source
|
||||||
containers container.Source
|
containers container.Source
|
||||||
|
log *logger.Logger
|
||||||
verifyTokenIssuer bool
|
verifyTokenIssuer bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type InnerRing interface {
|
|
||||||
InnerRingKeys() ([][]byte, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteHandler is an interface of delete queue processor.
|
// DeleteHandler is an interface of delete queue processor.
|
||||||
type DeleteHandler interface {
|
type DeleteHandler interface {
|
||||||
// DeleteObjects places objects to a removal queue.
|
// DeleteObjects places objects to a removal queue.
|
||||||
|
@ -94,6 +91,7 @@ func NewFormatValidator(opts ...FormatValidatorOption) *FormatValidator {
|
||||||
|
|
||||||
return &FormatValidator{
|
return &FormatValidator{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
|
senderClassifier: NewSenderClassifier(cfg.ir, cfg.netmap, cfg.log),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,42 +191,6 @@ func (v *FormatValidator) validateSignatureKey(obj *objectSDK.Object) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *FormatValidator) isIROrContainerNode(obj *objectSDK.Object, signerKey []byte) (bool, error) {
|
func (v *FormatValidator) isIROrContainerNode(obj *objectSDK.Object, signerKey []byte) (bool, error) {
|
||||||
pKey, err := keys.NewPublicKeyFromBytes(signerKey, elliptic.P256())
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("(%T) failed to unmarshal signer public key: %w", v, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
isIR, err := v.isInnerRingKey(pKey.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("(%T) failed to check if signer is inner ring node: %w", v, err)
|
|
||||||
}
|
|
||||||
if isIR {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
isContainerNode, err := v.isContainerNode(pKey.Bytes(), obj)
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("(%T) failed to check if signer is container node: %w", v, err)
|
|
||||||
}
|
|
||||||
return isContainerNode, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *FormatValidator) isInnerRingKey(key []byte) (bool, error) {
|
|
||||||
innerRingKeys, err := v.ir.InnerRingKeys()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range innerRingKeys {
|
|
||||||
if bytes.Equal(innerRingKeys[i], key) {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *FormatValidator) isContainerNode(key []byte, obj *objectSDK.Object) (bool, error) {
|
|
||||||
cnrID, containerIDSet := obj.ContainerID()
|
cnrID, containerIDSet := obj.ContainerID()
|
||||||
if !containerIDSet {
|
if !containerIDSet {
|
||||||
fyrchik marked this conversation as resolved
Outdated
|
|||||||
return false, errNilCID
|
return false, errNilCID
|
||||||
|
@ -242,46 +204,11 @@ func (v *FormatValidator) isContainerNode(key []byte, obj *objectSDK.Object) (bo
|
||||||
return false, fmt.Errorf("failed to get container (id=%s): %w", cnrID.EncodeToString(), err)
|
return false, fmt.Errorf("failed to get container (id=%s): %w", cnrID.EncodeToString(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
lastNetmap, err := netmap.GetLatestNetworkMap(v.netmap)
|
res, err := v.senderClassifier.IsInnerRingOrContainerNode(signerKey, cnrID, cnr.Value)
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("failed to get latest netmap: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
isContainerNode, err := v.isContainerNodeKey(lastNetmap, cnr, cnrIDBin, key)
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("failed to check latest netmap for container nodes: %w", err)
|
|
||||||
}
|
|
||||||
if isContainerNode {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
previousNetmap, err := netmap.GetPreviousNetworkMap(v.netmap)
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("failed to get previous netmap: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
isContainerNode, err = v.isContainerNodeKey(previousNetmap, cnr, cnrIDBin, key)
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("failed to check previous netmap for container nodes: %w", err)
|
|
||||||
}
|
|
||||||
return isContainerNode, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *FormatValidator) isContainerNodeKey(nm *netmapSDK.NetMap, cnr *container.Container, cnrIDBin, key []byte) (bool, error) {
|
|
||||||
cnrVectors, err := nm.ContainerNodes(cnr.Value.PlacementPolicy(), cnrIDBin)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
return res.Role == acl.RoleContainer || res.Role == acl.RoleInnerRing, nil
|
||||||
for i := range cnrVectors {
|
|
||||||
for j := range cnrVectors[i] {
|
|
||||||
if bytes.Equal(cnrVectors[i][j].PublicKey(), key) {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *FormatValidator) checkOwnerKey(id user.ID, key frostfsecdsa.PublicKey) error {
|
func (v *FormatValidator) checkOwnerKey(id user.ID, key frostfsecdsa.PublicKey) error {
|
||||||
|
@ -533,3 +460,10 @@ func WithVerifySessionTokenIssuer(verifySessionTokenIssuer bool) FormatValidator
|
||||||
c.verifyTokenIssuer = verifySessionTokenIssuer
|
c.verifyTokenIssuer = verifySessionTokenIssuer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithLogger return option to set logger.
|
||||||
|
func WithLogger(l *logger.Logger) FormatValidatorOption {
|
||||||
|
return func(c *cfg) {
|
||||||
|
c.log = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
||||||
containerSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
containerSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||||
|
@ -22,6 +23,7 @@ import (
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"go.uber.org/zap/zaptest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func blankValidObject(key *ecdsa.PrivateKey) *objectSDK.Object {
|
func blankValidObject(key *ecdsa.PrivateKey) *objectSDK.Object {
|
||||||
|
@ -63,6 +65,7 @@ func TestFormatValidator_Validate(t *testing.T) {
|
||||||
epoch: curEpoch,
|
epoch: curEpoch,
|
||||||
}),
|
}),
|
||||||
WithLockSource(ls),
|
WithLockSource(ls),
|
||||||
|
WithLogger(&logger.Logger{Logger: zaptest.NewLogger(t)}),
|
||||||
)
|
)
|
||||||
|
|
||||||
ownerKey, err := keys.NewPrivateKey()
|
ownerKey, err := keys.NewPrivateKey()
|
||||||
|
@ -285,6 +288,7 @@ func TestFormatValidator_ValidateTokenIssuer(t *testing.T) {
|
||||||
}),
|
}),
|
||||||
WithLockSource(ls),
|
WithLockSource(ls),
|
||||||
WithVerifySessionTokenIssuer(false),
|
WithVerifySessionTokenIssuer(false),
|
||||||
|
WithLogger(&logger.Logger{Logger: zaptest.NewLogger(t)}),
|
||||||
)
|
)
|
||||||
|
|
||||||
tok := sessiontest.Object()
|
tok := sessiontest.Object()
|
||||||
|
@ -307,6 +311,14 @@ func TestFormatValidator_ValidateTokenIssuer(t *testing.T) {
|
||||||
|
|
||||||
t.Run("different issuer and owner, issuer is IR node, verify issuer enabled", func(t *testing.T) {
|
t.Run("different issuer and owner, issuer is IR node, verify issuer enabled", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
cnrID := cidtest.ID()
|
||||||
|
cont := containerSDK.Container{}
|
||||||
|
cont.Init()
|
||||||
|
pp := netmap.PlacementPolicy{}
|
||||||
|
require.NoError(t, pp.DecodeString("REP 1"))
|
||||||
|
cont.SetPlacementPolicy(pp)
|
||||||
|
|
||||||
v := NewFormatValidator(
|
v := NewFormatValidator(
|
||||||
WithNetState(testNetState{
|
WithNetState(testNetState{
|
||||||
epoch: curEpoch,
|
epoch: curEpoch,
|
||||||
|
@ -316,6 +328,16 @@ func TestFormatValidator_ValidateTokenIssuer(t *testing.T) {
|
||||||
WithInnerRing(&testIRSource{
|
WithInnerRing(&testIRSource{
|
||||||
irNodes: [][]byte{signer.PublicKey().Bytes()},
|
irNodes: [][]byte{signer.PublicKey().Bytes()},
|
||||||
}),
|
}),
|
||||||
|
WithContainersSource(
|
||||||
|
&testContainerSource{
|
||||||
|
containers: map[cid.ID]*container.Container{
|
||||||
|
cnrID: {
|
||||||
|
Value: cont,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
WithLogger(&logger.Logger{Logger: zaptest.NewLogger(t)}),
|
||||||
)
|
)
|
||||||
|
|
||||||
tok := sessiontest.Object()
|
tok := sessiontest.Object()
|
||||||
|
@ -328,7 +350,7 @@ func TestFormatValidator_ValidateTokenIssuer(t *testing.T) {
|
||||||
require.NoError(t, tok.Sign(signer.PrivateKey))
|
require.NoError(t, tok.Sign(signer.PrivateKey))
|
||||||
|
|
||||||
obj := objectSDK.New()
|
obj := objectSDK.New()
|
||||||
obj.SetContainerID(cidtest.ID())
|
obj.SetContainerID(cnrID)
|
||||||
obj.SetSessionToken(tok)
|
obj.SetSessionToken(tok)
|
||||||
obj.SetOwnerID(&owner)
|
obj.SetOwnerID(&owner)
|
||||||
require.NoError(t, objectSDK.SetIDWithSignature(signer.PrivateKey, obj))
|
require.NoError(t, objectSDK.SetIDWithSignature(signer.PrivateKey, obj))
|
||||||
|
@ -393,6 +415,7 @@ func TestFormatValidator_ValidateTokenIssuer(t *testing.T) {
|
||||||
currentEpoch: curEpoch,
|
currentEpoch: curEpoch,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
WithLogger(&logger.Logger{Logger: zaptest.NewLogger(t)}),
|
||||||
)
|
)
|
||||||
|
|
||||||
require.NoError(t, v.Validate(context.Background(), obj, false))
|
require.NoError(t, v.Validate(context.Background(), obj, false))
|
||||||
|
@ -466,6 +489,7 @@ func TestFormatValidator_ValidateTokenIssuer(t *testing.T) {
|
||||||
currentEpoch: curEpoch,
|
currentEpoch: curEpoch,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
WithLogger(&logger.Logger{Logger: zaptest.NewLogger(t)}),
|
||||||
)
|
)
|
||||||
|
|
||||||
require.NoError(t, v.Validate(context.Background(), obj, false))
|
require.NoError(t, v.Validate(context.Background(), obj, false))
|
||||||
|
@ -541,6 +565,7 @@ func TestFormatValidator_ValidateTokenIssuer(t *testing.T) {
|
||||||
currentEpoch: curEpoch,
|
currentEpoch: curEpoch,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
WithLogger(&logger.Logger{Logger: zaptest.NewLogger(t)}),
|
||||||
)
|
)
|
||||||
|
|
||||||
require.Error(t, v.Validate(context.Background(), obj, false))
|
require.Error(t, v.Validate(context.Background(), obj, false))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package v2
|
package object
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -11,50 +11,64 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type senderClassifier struct {
|
type InnerRing interface {
|
||||||
|
InnerRingKeys() ([][]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type SenderClassifier struct {
|
||||||
log *logger.Logger
|
log *logger.Logger
|
||||||
innerRing InnerRingFetcher
|
innerRing InnerRing
|
||||||
netmap core.Source
|
netmap core.Source
|
||||||
}
|
}
|
||||||
|
|
||||||
type classifyResult struct {
|
func NewSenderClassifier(innerRing InnerRing, netmap core.Source, log *logger.Logger) SenderClassifier {
|
||||||
role acl.Role
|
return SenderClassifier{
|
||||||
key []byte
|
log: log,
|
||||||
|
innerRing: innerRing,
|
||||||
|
netmap: netmap,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c senderClassifier) classify(
|
type ClassifyResult struct {
|
||||||
req MetaWithToken,
|
Role acl.Role
|
||||||
idCnr cid.ID,
|
Key []byte
|
||||||
cnr container.Container) (res *classifyResult, err error) {
|
}
|
||||||
ownerID, ownerKey, err := req.RequestOwner()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
|
func (c SenderClassifier) Classify(
|
||||||
|
ownerID *user.ID,
|
||||||
|
ownerKey *keys.PublicKey,
|
||||||
|
idCnr cid.ID,
|
||||||
|
cnr container.Container) (res *ClassifyResult, err error) {
|
||||||
ownerKeyInBytes := ownerKey.Bytes()
|
ownerKeyInBytes := ownerKey.Bytes()
|
||||||
|
|
||||||
// TODO: #767 get owner from frostfs.id if present
|
// TODO: #767 get owner from frostfs.id if present
|
||||||
|
|
||||||
// if request owner is the same as container owner, return RoleUser
|
// if request owner is the same as container owner, return RoleUser
|
||||||
if ownerID.Equals(cnr.Owner()) {
|
if ownerID.Equals(cnr.Owner()) {
|
||||||
return &classifyResult{
|
return &ClassifyResult{
|
||||||
role: acl.RoleOwner,
|
Role: acl.RoleOwner,
|
||||||
key: ownerKeyInBytes,
|
Key: ownerKeyInBytes,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return c.IsInnerRingOrContainerNode(ownerKeyInBytes, idCnr, cnr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c SenderClassifier) IsInnerRingOrContainerNode(ownerKeyInBytes []byte, idCnr cid.ID, cnr container.Container) (*ClassifyResult, error) {
|
||||||
isInnerRingNode, err := c.isInnerRingKey(ownerKeyInBytes)
|
isInnerRingNode, err := c.isInnerRingKey(ownerKeyInBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// do not throw error, try best case matching
|
// do not throw error, try best case matching
|
||||||
c.log.Debug(logs.V2CantCheckIfRequestFromInnerRing,
|
c.log.Debug(logs.V2CantCheckIfRequestFromInnerRing,
|
||||||
zap.String("error", err.Error()))
|
zap.String("error", err.Error()))
|
||||||
} else if isInnerRingNode {
|
} else if isInnerRingNode {
|
||||||
return &classifyResult{
|
return &ClassifyResult{
|
||||||
role: acl.RoleInnerRing,
|
Role: acl.RoleInnerRing,
|
||||||
key: ownerKeyInBytes,
|
Key: ownerKeyInBytes,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,20 +83,20 @@ func (c senderClassifier) classify(
|
||||||
c.log.Debug(logs.V2CantCheckIfRequestFromContainerNode,
|
c.log.Debug(logs.V2CantCheckIfRequestFromContainerNode,
|
||||||
zap.String("error", err.Error()))
|
zap.String("error", err.Error()))
|
||||||
} else if isContainerNode {
|
} else if isContainerNode {
|
||||||
return &classifyResult{
|
return &ClassifyResult{
|
||||||
role: acl.RoleContainer,
|
Role: acl.RoleContainer,
|
||||||
key: ownerKeyInBytes,
|
Key: ownerKeyInBytes,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// if none of above, return RoleOthers
|
// if none of above, return RoleOthers
|
||||||
return &classifyResult{
|
return &ClassifyResult{
|
||||||
role: acl.RoleOthers,
|
Role: acl.RoleOthers,
|
||||||
key: ownerKeyInBytes,
|
Key: ownerKeyInBytes,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c senderClassifier) isInnerRingKey(owner []byte) (bool, error) {
|
func (c SenderClassifier) isInnerRingKey(owner []byte) (bool, error) {
|
||||||
innerRingKeys, err := c.innerRing.InnerRingKeys()
|
innerRingKeys, err := c.innerRing.InnerRingKeys()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
@ -98,7 +112,7 @@ func (c senderClassifier) isInnerRingKey(owner []byte) (bool, error) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c senderClassifier) isContainerKey(
|
func (c SenderClassifier) isContainerKey(
|
||||||
owner, idCnr []byte,
|
owner, idCnr []byte,
|
||||||
cnr container.Container) (bool, error) {
|
cnr container.Container) (bool, error) {
|
||||||
nm, err := core.GetLatestNetworkMap(c.netmap) // first check current netmap
|
nm, err := core.GetLatestNetworkMap(c.netmap) // first check current netmap
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/netmap"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/netmap"
|
||||||
|
objectCore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/object"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/object"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
||||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||||
|
@ -24,7 +25,7 @@ import (
|
||||||
type Service struct {
|
type Service struct {
|
||||||
*cfg
|
*cfg
|
||||||
|
|
||||||
c senderClassifier
|
c objectCore.SenderClassifier
|
||||||
}
|
}
|
||||||
|
|
||||||
type putStreamBasicChecker struct {
|
type putStreamBasicChecker struct {
|
||||||
|
@ -95,11 +96,7 @@ func New(next object.ServiceServer,
|
||||||
|
|
||||||
return Service{
|
return Service{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
c: senderClassifier{
|
c: objectCore.NewSenderClassifier(cfg.irFetcher, cfg.nm, cfg.log),
|
||||||
log: cfg.log,
|
|
||||||
innerRing: cfg.irFetcher,
|
|
||||||
netmap: cfg.nm,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,20 +649,24 @@ func (b Service) findRequestInfo(req MetaWithToken, idCnr cid.ID, op acl.Op) (in
|
||||||
}
|
}
|
||||||
|
|
||||||
// find request role and key
|
// find request role and key
|
||||||
res, err := b.c.classify(req, idCnr, cnr.Value)
|
ownerID, ownerKey, err := req.RequestOwner()
|
||||||
|
if err != nil {
|
||||||
|
return info, err
|
||||||
|
}
|
||||||
|
res, err := b.c.Classify(ownerID, ownerKey, idCnr, cnr.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return info, err
|
return info, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info.basicACL = cnr.Value.BasicACL()
|
info.basicACL = cnr.Value.BasicACL()
|
||||||
info.requestRole = res.role
|
info.requestRole = res.Role
|
||||||
info.operation = op
|
info.operation = op
|
||||||
info.cnrOwner = cnr.Value.Owner()
|
info.cnrOwner = cnr.Value.Owner()
|
||||||
info.idCnr = idCnr
|
info.idCnr = idCnr
|
||||||
|
|
||||||
// it is assumed that at the moment the key will be valid,
|
// it is assumed that at the moment the key will be valid,
|
||||||
// otherwise the request would not pass validation
|
// otherwise the request would not pass validation
|
||||||
info.senderKey = res.key
|
info.senderKey = res.Key
|
||||||
|
|
||||||
// add bearer token if it is present in request
|
// add bearer token if it is present in request
|
||||||
info.bearer = req.bearer
|
info.bearer = req.bearer
|
||||||
|
|
|
@ -98,6 +98,7 @@ func NewService(ks *objutil.KeyStorage,
|
||||||
object.WithNetmapSource(ns),
|
object.WithNetmapSource(ns),
|
||||||
object.WithContainersSource(cs),
|
object.WithContainersSource(cs),
|
||||||
object.WithVerifySessionTokenIssuer(c.verifySessionTokenIssuer),
|
object.WithVerifySessionTokenIssuer(c.verifySessionTokenIssuer),
|
||||||
|
object.WithLogger(c.log),
|
||||||
)
|
)
|
||||||
|
|
||||||
return &Service{
|
return &Service{
|
||||||
|
|
Loading…
Reference in a new issue
We already have role calculation in the acl service: https://git.frostfs.info/TrueCloudLab/frostfs-node/src/branch/master/pkg/services/object/acl/v2/classifier.go#L27
Can we reuse it somehow?
Done:
sender_classifier
moved toobject/core
package, ACL service and format validator now using it.