[#32] Use less v2 specific structures in basic ACL checker

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2020-09-28 13:54:24 +03:00
parent c5a44e0a05
commit 4a8de3263d
2 changed files with 36 additions and 39 deletions

View file

@ -5,17 +5,17 @@ import (
"context" "context"
acl "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl" acl "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
containerSDK "github.com/nspcc-dev/neofs-api-go/pkg/container" "github.com/nspcc-dev/neofs-api-go/pkg/container"
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
"github.com/nspcc-dev/neofs-api-go/v2/object" "github.com/nspcc-dev/neofs-api-go/v2/object"
"github.com/nspcc-dev/neofs-api-go/v2/refs" core "github.com/nspcc-dev/neofs-node/pkg/core/container"
"github.com/nspcc-dev/neofs-node/pkg/core/container"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
type ( type (
// BasicChecker checks basic ACL rules. // BasicChecker checks basic ACL rules.
BasicChecker struct { BasicChecker struct {
containers container.Source containers core.Source
sender SenderClassifier sender SenderClassifier
next object.Service next object.Service
} }
@ -42,7 +42,7 @@ type (
basicACL uint32 basicACL uint32
requestRole acl.Role requestRole acl.Role
operation acl.Operation // put, get, head, etc. operation acl.Operation // put, get, head, etc.
owner *refs.OwnerID // container owner owner *owner.ID // container owner
} }
) )
@ -56,7 +56,7 @@ var (
// NewBasicChecker is a constructor for basic ACL checker of object requests. // NewBasicChecker is a constructor for basic ACL checker of object requests.
func NewBasicChecker( func NewBasicChecker(
c SenderClassifier, c SenderClassifier,
cnr container.Source, cnr core.Source,
next object.Service) BasicChecker { next object.Service) BasicChecker {
return BasicChecker{ return BasicChecker{
@ -126,7 +126,7 @@ func (b BasicChecker) Search(
ctx context.Context, ctx context.Context,
request *object.SearchRequest) (object.SearchObjectStreamer, error) { request *object.SearchRequest) (object.SearchObjectStreamer, error) {
var cid *refs.ContainerID var cid *container.ID
cid, err := getContainerIDFromRequest(request) cid, err := getContainerIDFromRequest(request)
if err != nil { if err != nil {
@ -258,12 +258,12 @@ func (g getStreamBasicChecker) Recv() (*object.GetResponse, error) {
part := body.GetObjectPart() part := body.GetObjectPart()
if _, ok := part.(*object.GetObjectPartInit); ok { if _, ok := part.(*object.GetObjectPartInit); ok {
owner, err := getObjectOwnerFromMessage(resp) ownerID, err := getObjectOwnerFromMessage(resp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !stickyBitCheck(g.info, owner) { if !stickyBitCheck(g.info, ownerID) {
return nil, ErrBasicAccessDenied return nil, ErrBasicAccessDenied
} }
} }
@ -273,15 +273,11 @@ func (g getStreamBasicChecker) Recv() (*object.GetResponse, error) {
func (b BasicChecker) findRequestInfo( func (b BasicChecker) findRequestInfo(
req RequestV2, req RequestV2,
cid *refs.ContainerID, cid *container.ID,
op acl.Operation) (info requestInfo, err error) { op acl.Operation) (info requestInfo, err error) {
// container.Source interface implemented with SDK's definitions,
// so we have to convert id there.
containerID := containerSDK.NewIDFromV2(cid)
// fetch actual container // fetch actual container
cnr, err := b.containers.Get(containerID) cnr, err := b.containers.Get(cid)
if err != nil || cnr.GetOwnerID() == nil { if err != nil || cnr.GetOwnerID() == nil {
return info, ErrUnknownContainer return info, ErrUnknownContainer
} }
@ -295,12 +291,12 @@ func (b BasicChecker) findRequestInfo(
info.basicACL = cnr.GetBasicACL() info.basicACL = cnr.GetBasicACL()
info.requestRole = role info.requestRole = role
info.operation = op info.operation = op
info.owner = cnr.GetOwnerID() info.owner = owner.NewIDFromV2(cnr.GetOwnerID())
return info, nil return info, nil
} }
func getContainerIDFromRequest(req interface{}) (id *refs.ContainerID, err error) { func getContainerIDFromRequest(req interface{}) (id *container.ID, err error) {
defer func() { defer func() {
// if there is a NPE on get body and get address // if there is a NPE on get body and get address
if r := recover(); r != nil { if r := recover(); r != nil {
@ -310,30 +306,30 @@ func getContainerIDFromRequest(req interface{}) (id *refs.ContainerID, err error
switch v := req.(type) { switch v := req.(type) {
case *object.GetRequest: case *object.GetRequest:
return v.GetBody().GetAddress().GetContainerID(), nil return container.NewIDFromV2(v.GetBody().GetAddress().GetContainerID()), nil
case *object.PutRequest: case *object.PutRequest:
objPart := v.GetBody().GetObjectPart() objPart := v.GetBody().GetObjectPart()
if part, ok := objPart.(*object.PutObjectPartInit); ok { if part, ok := objPart.(*object.PutObjectPartInit); ok {
return part.GetHeader().GetContainerID(), nil return container.NewIDFromV2(part.GetHeader().GetContainerID()), nil
} else { } else {
return nil, errors.New("can't get cid in chunk") return nil, errors.New("can't get cid in chunk")
} }
case *object.HeadRequest: case *object.HeadRequest:
return v.GetBody().GetAddress().GetContainerID(), nil return container.NewIDFromV2(v.GetBody().GetAddress().GetContainerID()), nil
case *object.SearchRequest: case *object.SearchRequest:
return v.GetBody().GetContainerID(), nil return container.NewIDFromV2(v.GetBody().GetContainerID()), nil
case *object.DeleteRequest: case *object.DeleteRequest:
return v.GetBody().GetAddress().GetContainerID(), nil return container.NewIDFromV2(v.GetBody().GetAddress().GetContainerID()), nil
case *object.GetRangeRequest: case *object.GetRangeRequest:
return v.GetBody().GetAddress().GetContainerID(), nil return container.NewIDFromV2(v.GetBody().GetAddress().GetContainerID()), nil
case *object.GetRangeHashRequest: case *object.GetRangeHashRequest:
return v.GetBody().GetAddress().GetContainerID(), nil return container.NewIDFromV2(v.GetBody().GetAddress().GetContainerID()), nil
default: default:
return nil, errors.New("unknown request type") return nil, errors.New("unknown request type")
} }
} }
func getObjectOwnerFromMessage(req interface{}) (id *refs.OwnerID, err error) { func getObjectOwnerFromMessage(req interface{}) (id *owner.ID, err error) {
defer func() { defer func() {
// if there is a NPE on get body and get address // if there is a NPE on get body and get address
if r := recover(); r != nil { if r := recover(); r != nil {
@ -345,14 +341,14 @@ func getObjectOwnerFromMessage(req interface{}) (id *refs.OwnerID, err error) {
case *object.PutRequest: case *object.PutRequest:
objPart := v.GetBody().GetObjectPart() objPart := v.GetBody().GetObjectPart()
if part, ok := objPart.(*object.PutObjectPartInit); ok { if part, ok := objPart.(*object.PutObjectPartInit); ok {
return part.GetHeader().GetOwnerID(), nil return owner.NewIDFromV2(part.GetHeader().GetOwnerID()), nil
} else { } else {
return nil, errors.New("can't get cid in chunk") return nil, errors.New("can't get cid in chunk")
} }
case *object.GetResponse: case *object.GetResponse:
objPart := v.GetBody().GetObjectPart() objPart := v.GetBody().GetObjectPart()
if part, ok := objPart.(*object.GetObjectPartInit); ok { if part, ok := objPart.(*object.GetObjectPartInit); ok {
return part.GetHeader().GetOwnerID(), nil return owner.NewIDFromV2(part.GetHeader().GetOwnerID()), nil
} else { } else {
return nil, errors.New("can't get cid in chunk") return nil, errors.New("can't get cid in chunk")
} }
@ -384,7 +380,7 @@ func basicACLCheck(info requestInfo) bool {
return checkFn(info.operation) return checkFn(info.operation)
} }
func stickyBitCheck(info requestInfo, owner *refs.OwnerID) bool { func stickyBitCheck(info requestInfo, owner *owner.ID) bool {
if owner == nil || info.owner == nil { if owner == nil || info.owner == nil {
return false return false
} }
@ -394,5 +390,5 @@ func stickyBitCheck(info requestInfo, owner *refs.OwnerID) bool {
return true return true
} }
return bytes.Equal(owner.GetValue(), info.owner.GetValue()) return bytes.Equal(owner.ToV2().GetValue(), info.owner.ToV2().GetValue())
} }

View file

@ -4,11 +4,11 @@ import (
"bytes" "bytes"
"crypto/ecdsa" "crypto/ecdsa"
"github.com/nspcc-dev/neofs-api-go/pkg"
acl "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl" acl "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
"github.com/nspcc-dev/neofs-api-go/pkg/container" "github.com/nspcc-dev/neofs-api-go/pkg/container"
"github.com/nspcc-dev/neofs-api-go/pkg/netmap" "github.com/nspcc-dev/neofs-api-go/pkg/netmap"
"github.com/nspcc-dev/neofs-api-go/pkg/owner" "github.com/nspcc-dev/neofs-api-go/pkg/owner"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-api-go/v2/session" "github.com/nspcc-dev/neofs-api-go/v2/session"
crypto "github.com/nspcc-dev/neofs-crypto" crypto "github.com/nspcc-dev/neofs-crypto"
core "github.com/nspcc-dev/neofs-node/pkg/core/netmap" core "github.com/nspcc-dev/neofs-node/pkg/core/netmap"
@ -31,6 +31,7 @@ type (
} }
) )
// fixme: update classifier constructor
func NewSenderClassifier(ir InnerRingFetcher, nm core.Source) SenderClassifier { func NewSenderClassifier(ir InnerRingFetcher, nm core.Source) SenderClassifier {
return SenderClassifier{ return SenderClassifier{
innerRing: ir, innerRing: ir,
@ -40,7 +41,7 @@ func NewSenderClassifier(ir InnerRingFetcher, nm core.Source) SenderClassifier {
func (c SenderClassifier) Classify( func (c SenderClassifier) Classify(
req RequestV2, req RequestV2,
cid *refs.ContainerID, cid *container.ID,
cnr *container.Container) acl.Role { cnr *container.Container) acl.Role {
if cid == nil || req == nil { if cid == nil || req == nil {
// log there // log there
@ -56,7 +57,7 @@ func (c SenderClassifier) Classify(
// todo: get owner from neofs.id if present // todo: get owner from neofs.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 bytes.Equal(cnr.GetOwnerID().GetValue(), ownerID.GetValue()) { if bytes.Equal(cnr.GetOwnerID().GetValue(), ownerID.ToV2().GetValue()) {
return acl.RoleUser return acl.RoleUser
} }
@ -70,7 +71,7 @@ func (c SenderClassifier) Classify(
return acl.RoleSystem return acl.RoleSystem
} }
isContainerNode, err := c.isContainerKey(ownerKeyInBytes, cid.GetValue(), cnr) isContainerNode, err := c.isContainerKey(ownerKeyInBytes, cid.ToV2().GetValue(), cnr)
if err != nil { if err != nil {
// log there // log there
return acl.RoleUnknown return acl.RoleUnknown
@ -82,7 +83,7 @@ func (c SenderClassifier) Classify(
return acl.RoleOthers return acl.RoleOthers
} }
func requestOwner(req RequestV2) (*refs.OwnerID, *ecdsa.PublicKey, error) { func requestOwner(req RequestV2) (*owner.ID, *ecdsa.PublicKey, error) {
var ( var (
meta = req.GetMetaHeader() meta = req.GetMetaHeader()
verify = req.GetVerificationHeader() verify = req.GetVerificationHeader()
@ -104,7 +105,7 @@ func requestOwner(req RequestV2) (*refs.OwnerID, *ecdsa.PublicKey, error) {
return nil, nil, errors.Wrap(ErrMalformedRequest, "nil at signature") return nil, nil, errors.Wrap(ErrMalformedRequest, "nil at signature")
} }
return body.GetOwnerID(), crypto.UnmarshalPublicKey(signature.GetKey()), nil return owner.NewIDFromV2(body.GetOwnerID()), crypto.UnmarshalPublicKey(signature.GetKey()), nil
} }
// otherwise get original body signature // otherwise get original body signature
@ -120,13 +121,13 @@ func requestOwner(req RequestV2) (*refs.OwnerID, *ecdsa.PublicKey, error) {
} }
// form user from public key // form user from public key
user := new(refs.OwnerID) user := new(owner.ID)
user.SetValue(neo3wallet.Bytes()) user.SetNeo3Wallet(neo3wallet)
return user, key, nil return user, key, nil
} }
func originalBodySignature(v *session.RequestVerificationHeader) *refs.Signature { func originalBodySignature(v *session.RequestVerificationHeader) *pkg.Signature {
if v == nil { if v == nil {
return nil return nil
} }
@ -135,7 +136,7 @@ func originalBodySignature(v *session.RequestVerificationHeader) *refs.Signature
v = v.GetOrigin() v = v.GetOrigin()
} }
return v.GetBodySignature() return pkg.NewSignatureFromV2(v.GetBodySignature())
} }
func (c SenderClassifier) isInnerRingKey(owner []byte) (bool, error) { func (c SenderClassifier) isInnerRingKey(owner []byte) (bool, error) {