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"
|
v2 "github.com/nspcc-dev/neofs-node/pkg/services/object/acl/v2"
|
||||||
bearerSDK "github.com/nspcc-dev/neofs-sdk-go/bearer"
|
bearerSDK "github.com/nspcc-dev/neofs-sdk-go/bearer"
|
||||||
eaclSDK "github.com/nspcc-dev/neofs-sdk-go/eacl"
|
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"
|
"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)
|
hdrSrcOpts := make([]eaclV2.Option, 0, 3)
|
||||||
|
|
||||||
addr := addressSDK.NewAddress()
|
|
||||||
addr.SetContainerID(cid)
|
|
||||||
addr.SetObjectID(*reqInfo.ObjectID())
|
|
||||||
|
|
||||||
hdrSrcOpts = append(hdrSrcOpts,
|
hdrSrcOpts = append(hdrSrcOpts,
|
||||||
eaclV2.WithLocalObjectStorage(c.localStorage),
|
eaclV2.WithLocalObjectStorage(c.localStorage),
|
||||||
eaclV2.WithAddress(addr),
|
eaclV2.WithCID(cid),
|
||||||
|
eaclV2.WithOID(reqInfo.ObjectID()),
|
||||||
)
|
)
|
||||||
|
|
||||||
if req, ok := msg.(eaclV2.Request); ok {
|
if req, ok := msg.(eaclV2.Request); ok {
|
||||||
|
|
|
@ -103,11 +103,15 @@ func TestHeadRequest(t *testing.T) {
|
||||||
obj: obj,
|
obj: obj,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cid, _ := addr.ContainerID()
|
||||||
|
oid, _ := addr.ObjectID()
|
||||||
|
|
||||||
newSource := func(t *testing.T) eaclSDK.TypedHeaderSource {
|
newSource := func(t *testing.T) eaclSDK.TypedHeaderSource {
|
||||||
hdrSrc, err := NewMessageHeaderSource(
|
hdrSrc, err := NewMessageHeaderSource(
|
||||||
WithObjectStorage(lStorage),
|
WithObjectStorage(lStorage),
|
||||||
WithServiceRequest(req),
|
WithServiceRequest(req),
|
||||||
WithAddress(addr))
|
WithCID(cid),
|
||||||
|
WithOID(&oid))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return hdrSrc
|
return hdrSrc
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,12 @@ import (
|
||||||
objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object"
|
objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object"
|
||||||
refsV2 "github.com/nspcc-dev/neofs-api-go/v2/refs"
|
refsV2 "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"
|
||||||
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"
|
eaclSDK "github.com/nspcc-dev/neofs-sdk-go/eacl"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
objectSDKAddress "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
objectSDKID "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
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"
|
"github.com/nspcc-dev/neofs-sdk-go/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -23,11 +24,12 @@ type cfg struct {
|
||||||
|
|
||||||
msg xHeaderSource
|
msg xHeaderSource
|
||||||
|
|
||||||
addr *objectSDKAddress.Address
|
cid cidSDK.ID
|
||||||
|
oid *oidSDK.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
type ObjectStorage interface {
|
type ObjectStorage interface {
|
||||||
Head(*objectSDKAddress.Address) (*object.Object, error)
|
Head(*addressSDK.Address) (*object.Object, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Request interface {
|
type Request interface {
|
||||||
|
@ -86,58 +88,42 @@ func requestHeaders(msg xHeaderSource) []eaclSDK.Header {
|
||||||
return msg.GetXHeaders()
|
return msg.GetXHeaders()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var errMissingOID = errors.New("object ID is missing")
|
||||||
|
|
||||||
func (h *cfg) objectHeaders() ([]eaclSDK.Header, error) {
|
func (h *cfg) objectHeaders() ([]eaclSDK.Header, error) {
|
||||||
switch m := h.msg.(type) {
|
switch m := h.msg.(type) {
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unexpected message type %T", h.msg))
|
panic(fmt.Sprintf("unexpected message type %T", h.msg))
|
||||||
case requestXHeaderSource:
|
case requestXHeaderSource:
|
||||||
switch req := m.req.(type) {
|
switch req := m.req.(type) {
|
||||||
case *objectV2.GetRequest:
|
case
|
||||||
return h.localObjectHeaders(h.addr)
|
*objectV2.GetRequest,
|
||||||
case *objectV2.HeadRequest:
|
*objectV2.HeadRequest:
|
||||||
return h.localObjectHeaders(h.addr)
|
if h.oid == nil {
|
||||||
|
return nil, errMissingOID
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.localObjectHeaders(h.cid, h.oid)
|
||||||
case
|
case
|
||||||
*objectV2.GetRangeRequest,
|
*objectV2.GetRangeRequest,
|
||||||
*objectV2.GetRangeHashRequest,
|
*objectV2.GetRangeHashRequest,
|
||||||
*objectV2.DeleteRequest:
|
*objectV2.DeleteRequest:
|
||||||
return addressHeaders(h.addr), nil
|
if h.oid == nil {
|
||||||
|
return nil, errMissingOID
|
||||||
|
}
|
||||||
|
|
||||||
|
return addressHeaders(h.cid, h.oid), nil
|
||||||
case *objectV2.PutRequest:
|
case *objectV2.PutRequest:
|
||||||
if v, ok := req.GetBody().GetObjectPart().(*objectV2.PutObjectPartInit); ok {
|
if v, ok := req.GetBody().GetObjectPart().(*objectV2.PutObjectPartInit); ok {
|
||||||
oV2 := new(objectV2.Object)
|
oV2 := new(objectV2.Object)
|
||||||
oV2.SetObjectID(v.GetObjectID())
|
oV2.SetObjectID(v.GetObjectID())
|
||||||
oV2.SetHeader(v.GetHeader())
|
oV2.SetHeader(v.GetHeader())
|
||||||
|
|
||||||
if h.addr == nil {
|
return headersFromObject(object.NewFromV2(oV2), h.cid, h.oid), 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
|
|
||||||
}
|
}
|
||||||
case *objectV2.SearchRequest:
|
case *objectV2.SearchRequest:
|
||||||
cnrV2 := req.GetBody().GetContainerID()
|
cnrV2 := req.GetBody().GetContainerID()
|
||||||
var cnr cid.ID
|
var cnr cidSDK.ID
|
||||||
|
|
||||||
if cnrV2 != nil {
|
if cnrV2 != nil {
|
||||||
if err := cnr.ReadFromV2(*cnrV2); err != nil {
|
if err := cnr.ReadFromV2(*cnrV2); err != nil {
|
||||||
|
@ -150,7 +136,7 @@ func (h *cfg) objectHeaders() ([]eaclSDK.Header, error) {
|
||||||
case responseXHeaderSource:
|
case responseXHeaderSource:
|
||||||
switch resp := m.resp.(type) {
|
switch resp := m.resp.(type) {
|
||||||
default:
|
default:
|
||||||
hs, _ := h.localObjectHeaders(h.addr)
|
hs, _ := h.localObjectHeaders(h.cid, h.oid)
|
||||||
return hs, nil
|
return hs, nil
|
||||||
case *objectV2.GetResponse:
|
case *objectV2.GetResponse:
|
||||||
if v, ok := resp.GetBody().GetObjectPart().(*objectV2.GetObjectPartInit); ok {
|
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.SetObjectID(v.GetObjectID())
|
||||||
oV2.SetHeader(v.GetHeader())
|
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:
|
case *objectV2.HeadResponse:
|
||||||
oV2 := new(objectV2.Object)
|
oV2 := new(objectV2.Object)
|
||||||
|
@ -169,10 +155,8 @@ func (h *cfg) objectHeaders() ([]eaclSDK.Header, error) {
|
||||||
case *objectV2.ShortHeader:
|
case *objectV2.ShortHeader:
|
||||||
hdr = new(objectV2.Header)
|
hdr = new(objectV2.Header)
|
||||||
|
|
||||||
id, _ := h.addr.ContainerID()
|
|
||||||
|
|
||||||
var idV2 refsV2.ContainerID
|
var idV2 refsV2.ContainerID
|
||||||
id.WriteToV2(&idV2)
|
h.cid.WriteToV2(&idV2)
|
||||||
|
|
||||||
hdr.SetContainerID(&idV2)
|
hdr.SetContainerID(&idV2)
|
||||||
hdr.SetVersion(v.GetVersion())
|
hdr.SetVersion(v.GetVersion())
|
||||||
|
@ -186,30 +170,40 @@ func (h *cfg) objectHeaders() ([]eaclSDK.Header, error) {
|
||||||
|
|
||||||
oV2.SetHeader(hdr)
|
oV2.SetHeader(hdr)
|
||||||
|
|
||||||
return headersFromObject(object.NewFromV2(oV2), h.addr), nil
|
return headersFromObject(object.NewFromV2(oV2), h.cid, h.oid), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *cfg) localObjectHeaders(addr *objectSDKAddress.Address) ([]eaclSDK.Header, error) {
|
func (h *cfg) localObjectHeaders(cid cidSDK.ID, oid *oidSDK.ID) ([]eaclSDK.Header, error) {
|
||||||
obj, err := h.storage.Head(addr)
|
var obj *objectSDK.Object
|
||||||
if err != nil {
|
var err error
|
||||||
// Still parse addressHeaders, because the errors is ignored in some places.
|
|
||||||
return addressHeaders(addr), err
|
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func cidHeader(idCnr cid.ID) sysObjHdr {
|
// Still parse addressHeaders, because the errors is ignored in some places.
|
||||||
|
return addressHeaders(cid, oid), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func cidHeader(idCnr cidSDK.ID) sysObjHdr {
|
||||||
return sysObjHdr{
|
return sysObjHdr{
|
||||||
k: acl.FilterObjectContainerID,
|
k: acl.FilterObjectContainerID,
|
||||||
v: idCnr.EncodeToString(),
|
v: idCnr.EncodeToString(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func oidHeader(oid objectSDKID.ID) sysObjHdr {
|
func oidHeader(oid oidSDK.ID) sysObjHdr {
|
||||||
return sysObjHdr{
|
return sysObjHdr{
|
||||||
k: acl.FilterObjectID,
|
k: acl.FilterObjectID,
|
||||||
v: oid.EncodeToString(),
|
v: oid.EncodeToString(),
|
||||||
|
@ -223,15 +217,13 @@ func ownerIDHeader(ownerID user.ID) sysObjHdr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func addressHeaders(addr *objectSDKAddress.Address) []eaclSDK.Header {
|
func addressHeaders(cid cidSDK.ID, oid *oidSDK.ID) []eaclSDK.Header {
|
||||||
cnr, _ := addr.ContainerID()
|
hh := make([]eaclSDK.Header, 0, 2)
|
||||||
|
hh = append(hh, cidHeader(cid))
|
||||||
|
|
||||||
res := make([]eaclSDK.Header, 1, 2)
|
if oid != nil {
|
||||||
res[0] = cidHeader(cnr)
|
hh = append(hh, oidHeader(*oid))
|
||||||
|
|
||||||
if oid, ok := addr.ObjectID(); ok {
|
|
||||||
res = append(res, oidHeader(oid))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return hh
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,10 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/acl"
|
"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"
|
eaclSDK "github.com/nspcc-dev/neofs-sdk-go/eacl"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"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 {
|
type sysObjHdr struct {
|
||||||
|
@ -25,7 +26,7 @@ func u64Value(v uint64) string {
|
||||||
return strconv.FormatUint(v, 10)
|
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
|
var count int
|
||||||
for obj := obj; obj != nil; obj = obj.Parent() {
|
for obj := obj; obj != nil; obj = obj.Parent() {
|
||||||
count += 9 + len(obj.Attributes())
|
count += 9 + len(obj.Attributes())
|
||||||
|
@ -33,11 +34,8 @@ func headersFromObject(obj *object.Object, addr *objectSDKAddress.Address) []eac
|
||||||
|
|
||||||
res := make([]eaclSDK.Header, 0, count)
|
res := make([]eaclSDK.Header, 0, count)
|
||||||
for ; obj != nil; obj = obj.Parent() {
|
for ; obj != nil; obj = obj.Parent() {
|
||||||
cnr, _ := addr.ContainerID()
|
|
||||||
id, _ := addr.ObjectID()
|
|
||||||
|
|
||||||
res = append(res,
|
res = append(res,
|
||||||
cidHeader(cnr),
|
cidHeader(cid),
|
||||||
// creation epoch
|
// creation epoch
|
||||||
sysObjHdr{
|
sysObjHdr{
|
||||||
k: acl.FilterObjectCreationEpoch,
|
k: acl.FilterObjectCreationEpoch,
|
||||||
|
@ -48,7 +46,6 @@ func headersFromObject(obj *object.Object, addr *objectSDKAddress.Address) []eac
|
||||||
k: acl.FilterObjectPayloadLength,
|
k: acl.FilterObjectPayloadLength,
|
||||||
v: u64Value(obj.PayloadSize()),
|
v: u64Value(obj.PayloadSize()),
|
||||||
},
|
},
|
||||||
oidHeader(id),
|
|
||||||
// object version
|
// object version
|
||||||
sysObjHdr{
|
sysObjHdr{
|
||||||
k: acl.FilterObjectVersion,
|
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 {
|
if idOwner := obj.OwnerID(); idOwner != nil {
|
||||||
res = append(res, ownerIDHeader(*idOwner))
|
res = append(res, ownerIDHeader(*idOwner))
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,8 @@ package v2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/engine"
|
"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 {
|
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) {
|
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
|
idCnr containerIDSDK.ID
|
||||||
|
|
||||||
|
// optional for some request
|
||||||
|
// e.g. Put, Search
|
||||||
oid *oidSDK.ID
|
oid *oidSDK.ID
|
||||||
|
|
||||||
senderKey []byte
|
senderKey []byte
|
||||||
|
|
Loading…
Reference in a new issue