forked from TrueCloudLab/frostfs-node
[#1428] node/acl: Make OID optional
Not all the NeoFS requests must contain OID in their bodies (or must NOT contain them at all). Do not pass object address in helper functions, pass CID and OID separately instead. Also, fixed NPE in the ACL service: updated SDK library brought errors when working with `Put` and `Search` requests without OID fields. Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
parent
d69eb2aaf3
commit
57c5fccc8c
6 changed files with 79 additions and 77 deletions
|
@ -15,7 +15,6 @@ import (
|
|||
v2 "github.com/nspcc-dev/neofs-node/pkg/services/object/acl/v2"
|
||||
bearerSDK "github.com/nspcc-dev/neofs-sdk-go/bearer"
|
||||
eaclSDK "github.com/nspcc-dev/neofs-sdk-go/eacl"
|
||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/user"
|
||||
)
|
||||
|
||||
|
@ -168,13 +167,10 @@ func (c *Checker) CheckEACL(msg interface{}, reqInfo v2.RequestInfo) error {
|
|||
|
||||
hdrSrcOpts := make([]eaclV2.Option, 0, 3)
|
||||
|
||||
addr := addressSDK.NewAddress()
|
||||
addr.SetContainerID(cid)
|
||||
addr.SetObjectID(*reqInfo.ObjectID())
|
||||
|
||||
hdrSrcOpts = append(hdrSrcOpts,
|
||||
eaclV2.WithLocalObjectStorage(c.localStorage),
|
||||
eaclV2.WithAddress(addr),
|
||||
eaclV2.WithCID(cid),
|
||||
eaclV2.WithOID(reqInfo.ObjectID()),
|
||||
)
|
||||
|
||||
if req, ok := msg.(eaclV2.Request); ok {
|
||||
|
|
|
@ -103,11 +103,15 @@ func TestHeadRequest(t *testing.T) {
|
|||
obj: obj,
|
||||
}
|
||||
|
||||
cid, _ := addr.ContainerID()
|
||||
oid, _ := addr.ObjectID()
|
||||
|
||||
newSource := func(t *testing.T) eaclSDK.TypedHeaderSource {
|
||||
hdrSrc, err := NewMessageHeaderSource(
|
||||
WithObjectStorage(lStorage),
|
||||
WithServiceRequest(req),
|
||||
WithAddress(addr))
|
||||
WithCID(cid),
|
||||
WithOID(&oid))
|
||||
require.NoError(t, err)
|
||||
return hdrSrc
|
||||
}
|
||||
|
|
|
@ -8,11 +8,12 @@ import (
|
|||
objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object"
|
||||
refsV2 "github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/session"
|
||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||
cidSDK "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||
eaclSDK "github.com/nspcc-dev/neofs-sdk-go/eacl"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||
objectSDKAddress "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
||||
objectSDKID "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
||||
oidSDK "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/user"
|
||||
)
|
||||
|
||||
|
@ -23,11 +24,12 @@ type cfg struct {
|
|||
|
||||
msg xHeaderSource
|
||||
|
||||
addr *objectSDKAddress.Address
|
||||
cid cidSDK.ID
|
||||
oid *oidSDK.ID
|
||||
}
|
||||
|
||||
type ObjectStorage interface {
|
||||
Head(*objectSDKAddress.Address) (*object.Object, error)
|
||||
Head(*addressSDK.Address) (*object.Object, error)
|
||||
}
|
||||
|
||||
type Request interface {
|
||||
|
@ -86,58 +88,42 @@ func requestHeaders(msg xHeaderSource) []eaclSDK.Header {
|
|||
return msg.GetXHeaders()
|
||||
}
|
||||
|
||||
var errMissingOID = errors.New("object ID is missing")
|
||||
|
||||
func (h *cfg) objectHeaders() ([]eaclSDK.Header, error) {
|
||||
switch m := h.msg.(type) {
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected message type %T", h.msg))
|
||||
case requestXHeaderSource:
|
||||
switch req := m.req.(type) {
|
||||
case *objectV2.GetRequest:
|
||||
return h.localObjectHeaders(h.addr)
|
||||
case *objectV2.HeadRequest:
|
||||
return h.localObjectHeaders(h.addr)
|
||||
case
|
||||
*objectV2.GetRequest,
|
||||
*objectV2.HeadRequest:
|
||||
if h.oid == nil {
|
||||
return nil, errMissingOID
|
||||
}
|
||||
|
||||
return h.localObjectHeaders(h.cid, h.oid)
|
||||
case
|
||||
*objectV2.GetRangeRequest,
|
||||
*objectV2.GetRangeHashRequest,
|
||||
*objectV2.DeleteRequest:
|
||||
return addressHeaders(h.addr), nil
|
||||
if h.oid == nil {
|
||||
return nil, errMissingOID
|
||||
}
|
||||
|
||||
return addressHeaders(h.cid, h.oid), nil
|
||||
case *objectV2.PutRequest:
|
||||
if v, ok := req.GetBody().GetObjectPart().(*objectV2.PutObjectPartInit); ok {
|
||||
oV2 := new(objectV2.Object)
|
||||
oV2.SetObjectID(v.GetObjectID())
|
||||
oV2.SetHeader(v.GetHeader())
|
||||
|
||||
if h.addr == nil {
|
||||
idV2 := v.GetObjectID()
|
||||
var id objectSDKID.ID
|
||||
|
||||
if idV2 != nil {
|
||||
if err := id.ReadFromV2(*idV2); err != nil {
|
||||
return nil, fmt.Errorf("can't parse object ID: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
cnrV2 := v.GetHeader().GetContainerID()
|
||||
var cnr cid.ID
|
||||
|
||||
if cnrV2 != nil {
|
||||
if err := cnr.ReadFromV2(*cnrV2); err != nil {
|
||||
return nil, fmt.Errorf("can't parse container ID: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
h.addr = new(objectSDKAddress.Address)
|
||||
h.addr.SetContainerID(cnr)
|
||||
h.addr.SetObjectID(id)
|
||||
}
|
||||
|
||||
hs := headersFromObject(object.NewFromV2(oV2), h.addr)
|
||||
|
||||
return hs, nil
|
||||
return headersFromObject(object.NewFromV2(oV2), h.cid, h.oid), nil
|
||||
}
|
||||
case *objectV2.SearchRequest:
|
||||
cnrV2 := req.GetBody().GetContainerID()
|
||||
var cnr cid.ID
|
||||
var cnr cidSDK.ID
|
||||
|
||||
if cnrV2 != nil {
|
||||
if err := cnr.ReadFromV2(*cnrV2); err != nil {
|
||||
|
@ -150,7 +136,7 @@ func (h *cfg) objectHeaders() ([]eaclSDK.Header, error) {
|
|||
case responseXHeaderSource:
|
||||
switch resp := m.resp.(type) {
|
||||
default:
|
||||
hs, _ := h.localObjectHeaders(h.addr)
|
||||
hs, _ := h.localObjectHeaders(h.cid, h.oid)
|
||||
return hs, nil
|
||||
case *objectV2.GetResponse:
|
||||
if v, ok := resp.GetBody().GetObjectPart().(*objectV2.GetObjectPartInit); ok {
|
||||
|
@ -158,7 +144,7 @@ func (h *cfg) objectHeaders() ([]eaclSDK.Header, error) {
|
|||
oV2.SetObjectID(v.GetObjectID())
|
||||
oV2.SetHeader(v.GetHeader())
|
||||
|
||||
return headersFromObject(object.NewFromV2(oV2), h.addr), nil
|
||||
return headersFromObject(object.NewFromV2(oV2), h.cid, h.oid), nil
|
||||
}
|
||||
case *objectV2.HeadResponse:
|
||||
oV2 := new(objectV2.Object)
|
||||
|
@ -169,10 +155,8 @@ func (h *cfg) objectHeaders() ([]eaclSDK.Header, error) {
|
|||
case *objectV2.ShortHeader:
|
||||
hdr = new(objectV2.Header)
|
||||
|
||||
id, _ := h.addr.ContainerID()
|
||||
|
||||
var idV2 refsV2.ContainerID
|
||||
id.WriteToV2(&idV2)
|
||||
h.cid.WriteToV2(&idV2)
|
||||
|
||||
hdr.SetContainerID(&idV2)
|
||||
hdr.SetVersion(v.GetVersion())
|
||||
|
@ -186,30 +170,40 @@ func (h *cfg) objectHeaders() ([]eaclSDK.Header, error) {
|
|||
|
||||
oV2.SetHeader(hdr)
|
||||
|
||||
return headersFromObject(object.NewFromV2(oV2), h.addr), nil
|
||||
return headersFromObject(object.NewFromV2(oV2), h.cid, h.oid), nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (h *cfg) localObjectHeaders(addr *objectSDKAddress.Address) ([]eaclSDK.Header, error) {
|
||||
obj, err := h.storage.Head(addr)
|
||||
if err != nil {
|
||||
// Still parse addressHeaders, because the errors is ignored in some places.
|
||||
return addressHeaders(addr), err
|
||||
func (h *cfg) localObjectHeaders(cid cidSDK.ID, oid *oidSDK.ID) ([]eaclSDK.Header, error) {
|
||||
var obj *objectSDK.Object
|
||||
var err error
|
||||
|
||||
if oid != nil {
|
||||
var addr addressSDK.Address
|
||||
addr.SetContainerID(cid)
|
||||
addr.SetObjectID(*oid)
|
||||
|
||||
obj, err = h.storage.Head(&addr)
|
||||
if err == nil {
|
||||
return headersFromObject(obj, cid, oid), nil
|
||||
}
|
||||
return headersFromObject(obj, addr), nil
|
||||
}
|
||||
|
||||
// Still parse addressHeaders, because the errors is ignored in some places.
|
||||
return addressHeaders(cid, oid), err
|
||||
}
|
||||
|
||||
func cidHeader(idCnr cid.ID) sysObjHdr {
|
||||
func cidHeader(idCnr cidSDK.ID) sysObjHdr {
|
||||
return sysObjHdr{
|
||||
k: acl.FilterObjectContainerID,
|
||||
v: idCnr.EncodeToString(),
|
||||
}
|
||||
}
|
||||
|
||||
func oidHeader(oid objectSDKID.ID) sysObjHdr {
|
||||
func oidHeader(oid oidSDK.ID) sysObjHdr {
|
||||
return sysObjHdr{
|
||||
k: acl.FilterObjectID,
|
||||
v: oid.EncodeToString(),
|
||||
|
@ -223,15 +217,13 @@ func ownerIDHeader(ownerID user.ID) sysObjHdr {
|
|||
}
|
||||
}
|
||||
|
||||
func addressHeaders(addr *objectSDKAddress.Address) []eaclSDK.Header {
|
||||
cnr, _ := addr.ContainerID()
|
||||
func addressHeaders(cid cidSDK.ID, oid *oidSDK.ID) []eaclSDK.Header {
|
||||
hh := make([]eaclSDK.Header, 0, 2)
|
||||
hh = append(hh, cidHeader(cid))
|
||||
|
||||
res := make([]eaclSDK.Header, 1, 2)
|
||||
res[0] = cidHeader(cnr)
|
||||
|
||||
if oid, ok := addr.ObjectID(); ok {
|
||||
res = append(res, oidHeader(oid))
|
||||
if oid != nil {
|
||||
hh = append(hh, oidHeader(*oid))
|
||||
}
|
||||
|
||||
return res
|
||||
return hh
|
||||
}
|
||||
|
|
|
@ -4,9 +4,10 @@ import (
|
|||
"strconv"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/acl"
|
||||
cidSDK "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||
eaclSDK "github.com/nspcc-dev/neofs-sdk-go/eacl"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||
objectSDKAddress "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
||||
oidSDK "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||
)
|
||||
|
||||
type sysObjHdr struct {
|
||||
|
@ -25,7 +26,7 @@ func u64Value(v uint64) string {
|
|||
return strconv.FormatUint(v, 10)
|
||||
}
|
||||
|
||||
func headersFromObject(obj *object.Object, addr *objectSDKAddress.Address) []eaclSDK.Header {
|
||||
func headersFromObject(obj *object.Object, cid cidSDK.ID, oid *oidSDK.ID) []eaclSDK.Header {
|
||||
var count int
|
||||
for obj := obj; obj != nil; obj = obj.Parent() {
|
||||
count += 9 + len(obj.Attributes())
|
||||
|
@ -33,11 +34,8 @@ func headersFromObject(obj *object.Object, addr *objectSDKAddress.Address) []eac
|
|||
|
||||
res := make([]eaclSDK.Header, 0, count)
|
||||
for ; obj != nil; obj = obj.Parent() {
|
||||
cnr, _ := addr.ContainerID()
|
||||
id, _ := addr.ObjectID()
|
||||
|
||||
res = append(res,
|
||||
cidHeader(cnr),
|
||||
cidHeader(cid),
|
||||
// creation epoch
|
||||
sysObjHdr{
|
||||
k: acl.FilterObjectCreationEpoch,
|
||||
|
@ -48,7 +46,6 @@ func headersFromObject(obj *object.Object, addr *objectSDKAddress.Address) []eac
|
|||
k: acl.FilterObjectPayloadLength,
|
||||
v: u64Value(obj.PayloadSize()),
|
||||
},
|
||||
oidHeader(id),
|
||||
// object version
|
||||
sysObjHdr{
|
||||
k: acl.FilterObjectVersion,
|
||||
|
@ -61,6 +58,10 @@ func headersFromObject(obj *object.Object, addr *objectSDKAddress.Address) []eac
|
|||
},
|
||||
)
|
||||
|
||||
if oid != nil {
|
||||
res = append(res, oidHeader(*oid))
|
||||
}
|
||||
|
||||
if idOwner := obj.OwnerID(); idOwner != nil {
|
||||
res = append(res, ownerIDHeader(*idOwner))
|
||||
}
|
||||
|
|
|
@ -2,7 +2,8 @@ package v2
|
|||
|
||||
import (
|
||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/engine"
|
||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
||||
cidSDK "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||
oidSDK "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||
)
|
||||
|
||||
func WithObjectStorage(v ObjectStorage) Option {
|
||||
|
@ -36,8 +37,14 @@ func WithServiceResponse(resp Response, req Request) Option {
|
|||
}
|
||||
}
|
||||
|
||||
func WithAddress(v *addressSDK.Address) Option {
|
||||
func WithCID(v cidSDK.ID) Option {
|
||||
return func(c *cfg) {
|
||||
c.addr = v
|
||||
c.cid = v
|
||||
}
|
||||
}
|
||||
|
||||
func WithOID(v *oidSDK.ID) Option {
|
||||
return func(c *cfg) {
|
||||
c.oid = v
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ type RequestInfo struct {
|
|||
|
||||
idCnr containerIDSDK.ID
|
||||
|
||||
// optional for some request
|
||||
// e.g. Put, Search
|
||||
oid *oidSDK.ID
|
||||
|
||||
senderKey []byte
|
||||
|
|
Loading…
Reference in a new issue