[#529] objectcore: Use common sender classifier
All checks were successful
DCO action / DCO (pull_request) Successful in 2m19s
Vulncheck / Vulncheck (pull_request) Successful in 3m5s
Build / Build Components (1.21) (pull_request) Successful in 4m8s
Build / Build Components (1.20) (pull_request) Successful in 4m24s
Tests and linters / Tests (1.20) (pull_request) Successful in 4m57s
Tests and linters / Staticcheck (pull_request) Successful in 4m43s
Tests and linters / Tests (1.21) (pull_request) Successful in 5m2s
Tests and linters / Lint (pull_request) Successful in 5m21s
Tests and linters / Tests with -race (pull_request) Successful in 6m17s
All checks were successful
DCO action / DCO (pull_request) Successful in 2m19s
Vulncheck / Vulncheck (pull_request) Successful in 3m5s
Build / Build Components (1.21) (pull_request) Successful in 4m8s
Build / Build Components (1.20) (pull_request) Successful in 4m24s
Tests and linters / Tests (1.20) (pull_request) Successful in 4m57s
Tests and linters / Staticcheck (pull_request) Successful in 4m43s
Tests and linters / Tests (1.21) (pull_request) Successful in 5m2s
Tests and linters / Lint (pull_request) Successful in 5m21s
Tests and linters / Tests with -race (pull_request) Successful in 6m17s
Use common sender classifier for ACL service and format validator. Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
parent
ae81d6660a
commit
55b82e744b
5 changed files with 95 additions and 120 deletions
|
@ -1,10 +1,8 @@
|
|||
package object
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -14,18 +12,20 @@ import (
|
|||
"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/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"
|
||||
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"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
)
|
||||
|
||||
// FormatValidator represents an object format validator.
|
||||
type FormatValidator struct {
|
||||
*cfg
|
||||
|
||||
senderClassifier SenderClassifier
|
||||
}
|
||||
|
||||
// FormatValidatorOption represents a FormatValidator constructor option.
|
||||
|
@ -37,13 +37,10 @@ type cfg struct {
|
|||
ir InnerRing
|
||||
netmap netmap.Source
|
||||
containers container.Source
|
||||
log *logger.Logger
|
||||
verifyTokenIssuer bool
|
||||
}
|
||||
|
||||
type InnerRing interface {
|
||||
InnerRingKeys() ([][]byte, error)
|
||||
}
|
||||
|
||||
// DeleteHandler is an interface of delete queue processor.
|
||||
type DeleteHandler interface {
|
||||
// DeleteObjects places objects to a removal queue.
|
||||
|
@ -93,7 +90,8 @@ func NewFormatValidator(opts ...FormatValidatorOption) *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) {
|
||||
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()
|
||||
if !containerIDSet {
|
||||
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)
|
||||
}
|
||||
|
||||
lastNetmap, err := netmap.GetLatestNetworkMap(v.netmap)
|
||||
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)
|
||||
res, err := v.senderClassifier.IsInnerRingOrContainerNode(signerKey, cnrID, cnr.Value)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for i := range cnrVectors {
|
||||
for j := range cnrVectors[i] {
|
||||
if bytes.Equal(cnrVectors[i][j].PublicKey(), key) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
return res.Role == acl.RoleContainer || res.Role == acl.RoleInnerRing, nil
|
||||
}
|
||||
|
||||
func (v *FormatValidator) checkOwnerKey(id user.ID, key frostfsecdsa.PublicKey) error {
|
||||
|
@ -533,3 +460,10 @@ func WithVerifySessionTokenIssuer(verifySessionTokenIssuer bool) FormatValidator
|
|||
c.verifyTokenIssuer = verifySessionTokenIssuer
|
||||
}
|
||||
}
|
||||
|
||||
// WithLogger return option to set logger.
|
||||
func WithLogger(l *logger.Logger) FormatValidatorOption {
|
||||
return func(c *cfg) {
|
||||
c.log = l
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue