[#247] object/eacl: Use address from session token in request validation

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2020-12-15 12:06:04 +03:00 committed by Leonard Lyubich
parent dba88c79b4
commit 49131f1bc7
5 changed files with 44 additions and 37 deletions

View file

@ -606,19 +606,21 @@ func eACLCheck(msg interface{}, reqInfo requestInfo, cfg *eACLCfg) bool {
return false return false
} }
hdrSrcOpts := make([]eaclV2.Option, 0, 2) hdrSrcOpts := make([]eaclV2.Option, 0, 3)
hdrSrcOpts = append(hdrSrcOpts, eaclV2.WithLocalObjectStorage(cfg.localStorage))
if req, ok := msg.(eaclV2.Request); ok {
hdrSrcOpts = append(hdrSrcOpts, eaclV2.WithServiceRequest(req))
} else {
addr := objectSDK.NewAddress() addr := objectSDK.NewAddress()
addr.SetContainerID(reqInfo.cid) addr.SetContainerID(reqInfo.cid)
addr.SetObjectID(reqInfo.oid) addr.SetObjectID(reqInfo.oid)
// TODO: Add 'WithAddress' option to config and use address from reqInfo hdrSrcOpts = append(hdrSrcOpts,
hdrSrcOpts = append(hdrSrcOpts, eaclV2.WithServiceResponse(msg.(eaclV2.Response), addr.ToV2())) eaclV2.WithLocalObjectStorage(cfg.localStorage),
eaclV2.WithAddress(addr.ToV2()),
)
if req, ok := msg.(eaclV2.Request); ok {
hdrSrcOpts = append(hdrSrcOpts, eaclV2.WithServiceRequest(req))
} else {
hdrSrcOpts = append(hdrSrcOpts, eaclV2.WithServiceResponse(msg.(eaclV2.Response)))
} }
action := cfg.eACL.CalculateAction(new(eacl.ValidationUnit). action := cfg.eACL.CalculateAction(new(eacl.ValidationUnit).

View file

@ -21,6 +21,8 @@ type cfg struct {
storage ObjectStorage storage ObjectStorage
msg xHeaderSource msg xHeaderSource
addr *refs.Address
} }
type ObjectStorage interface { type ObjectStorage interface {
@ -81,22 +83,27 @@ func requestHeaders(msg xHeaderSource) []eacl.Header {
} }
func (h *headerSource) objectHeaders() ([]eacl.Header, bool) { func (h *headerSource) objectHeaders() ([]eacl.Header, bool) {
var addr *objectSDK.Address
if h.addr != nil {
addr = objectSDK.NewAddressFromV2(h.addr)
}
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 *objectV2.GetRequest:
return h.localObjectHeaders(req.GetBody().GetAddress()) return h.localObjectHeaders(h.addr)
case *objectV2.DeleteRequest: case *objectV2.DeleteRequest:
hs, _ := h.localObjectHeaders(req.GetBody().GetAddress()) hs, _ := h.localObjectHeaders(h.addr)
return hs, true return hs, true
case *objectV2.HeadRequest: case *objectV2.HeadRequest:
return h.localObjectHeaders(req.GetBody().GetAddress()) return h.localObjectHeaders(h.addr)
case *objectV2.GetRangeRequest: case *objectV2.GetRangeRequest:
return addressHeaders(objectSDK.NewAddressFromV2(req.GetBody().GetAddress())), true return addressHeaders(objectSDK.NewAddressFromV2(h.addr)), true
case *objectV2.GetRangeHashRequest: case *objectV2.GetRangeHashRequest:
hs, _ := h.localObjectHeaders(req.GetBody().GetAddress()) hs, _ := h.localObjectHeaders(h.addr)
return hs, true return hs, true
case *objectV2.PutRequest: case *objectV2.PutRequest:
if v, ok := req.GetBody().GetObjectPart().(*objectV2.PutObjectPartInit); ok { if v, ok := req.GetBody().GetObjectPart().(*objectV2.PutObjectPartInit); ok {
@ -104,14 +111,14 @@ func (h *headerSource) objectHeaders() ([]eacl.Header, bool) {
oV2.SetObjectID(v.GetObjectID()) oV2.SetObjectID(v.GetObjectID())
oV2.SetHeader(v.GetHeader()) oV2.SetHeader(v.GetHeader())
hs := headersFromObject(object.NewFromV2(oV2)) if addr == nil {
if tok := oV2.GetHeader().GetSessionToken(); tok != nil { addr = objectSDK.NewAddress()
objCtx, ok := tok.GetBody().GetContext().(*session.ObjectSessionContext) addr.SetContainerID(container.NewIDFromV2(v.GetHeader().GetContainerID()))
if ok { addr.SetObjectID(objectSDK.NewIDFromV2(v.GetObjectID()))
hs = append(hs, addressHeaders(objectSDK.NewAddressFromV2(objCtx.GetAddress()))...)
}
} }
hs := headersFromObject(object.NewFromV2(oV2), addr)
return hs, true return hs, true
} }
case *objectV2.SearchRequest: case *objectV2.SearchRequest:
@ -123,7 +130,7 @@ func (h *headerSource) objectHeaders() ([]eacl.Header, bool) {
case *responseXHeaderSource: case *responseXHeaderSource:
switch resp := m.resp.(type) { switch resp := m.resp.(type) {
default: default:
hs, _ := h.localObjectHeaders(m.addr) hs, _ := h.localObjectHeaders(h.addr)
return hs, true return hs, true
case *objectV2.GetResponse: case *objectV2.GetResponse:
if v, ok := resp.GetBody().GetObjectPart().(*objectV2.GetObjectPartInit); ok { if v, ok := resp.GetBody().GetObjectPart().(*objectV2.GetObjectPartInit); ok {
@ -131,7 +138,7 @@ func (h *headerSource) objectHeaders() ([]eacl.Header, bool) {
oV2.SetObjectID(v.GetObjectID()) oV2.SetObjectID(v.GetObjectID())
oV2.SetHeader(v.GetHeader()) oV2.SetHeader(v.GetHeader())
return headersFromObject(object.NewFromV2(oV2)), true return headersFromObject(object.NewFromV2(oV2), addr), true
} }
case *objectV2.HeadResponse: case *objectV2.HeadResponse:
oV2 := new(objectV2.Object) oV2 := new(objectV2.Object)
@ -142,7 +149,7 @@ func (h *headerSource) objectHeaders() ([]eacl.Header, bool) {
case *objectV2.ShortHeader: case *objectV2.ShortHeader:
hdr = new(objectV2.Header) hdr = new(objectV2.Header)
hdr.SetContainerID(m.addr.GetContainerID()) hdr.SetContainerID(h.addr.GetContainerID())
hdr.SetVersion(v.GetVersion()) hdr.SetVersion(v.GetVersion())
hdr.SetCreationEpoch(v.GetCreationEpoch()) hdr.SetCreationEpoch(v.GetCreationEpoch())
hdr.SetOwnerID(v.GetOwnerID()) hdr.SetOwnerID(v.GetOwnerID())
@ -154,10 +161,7 @@ func (h *headerSource) objectHeaders() ([]eacl.Header, bool) {
oV2.SetHeader(hdr) oV2.SetHeader(hdr)
return append( return headersFromObject(object.NewFromV2(oV2), addr), true
headersFromObject(object.NewFromV2(oV2)),
oidHeader(objectSDK.NewIDFromV2(m.addr.GetObjectID())),
), true
} }
} }
@ -169,7 +173,7 @@ func (h *headerSource) localObjectHeaders(addrV2 *refs.Address) ([]eacl.Header,
obj, err := h.storage.Head(addr) obj, err := h.storage.Head(addr)
if err == nil { if err == nil {
return append(headersFromObject(obj), addressHeaders(addr)...), true return headersFromObject(obj, addr), true
} }
return addressHeaders(addr), false return addressHeaders(addr), false

View file

@ -39,14 +39,13 @@ func u64Value(v uint64) string {
return strconv.FormatUint(v, 10) return strconv.FormatUint(v, 10)
} }
func headersFromObject(obj *object.Object) []eacl.Header { func headersFromObject(obj *object.Object, addr *objectSDK.Address) []eacl.Header {
// TODO: optimize allocs // TODO: optimize allocs
res := make([]eacl.Header, 0) res := make([]eacl.Header, 0)
for ; obj != nil; obj = obj.GetParent() { for ; obj != nil; obj = obj.GetParent() {
res = append(res, res = append(res,
// container ID cidHeader(addr.ContainerID()),
cidHeader(obj.ContainerID()),
// owner ID // owner ID
&sysObjHdr{ &sysObjHdr{
k: acl.FilterObjectOwnerID, k: acl.FilterObjectOwnerID,
@ -62,7 +61,7 @@ func headersFromObject(obj *object.Object) []eacl.Header {
k: acl.FilterObjectPayloadLength, k: acl.FilterObjectPayloadLength,
v: u64Value(obj.PayloadSize()), v: u64Value(obj.PayloadSize()),
}, },
oidHeader(obj.ID()), oidHeader(addr.ObjectID()),
// TODO: add others fields after neofs-api#84 // TODO: add others fields after neofs-api#84
) )

View file

@ -1,8 +1,8 @@
package v2 package v2
import ( import (
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/engine"
"github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/engine"
) )
func WithObjectStorage(v ObjectStorage) Option { func WithObjectStorage(v ObjectStorage) Option {
@ -27,11 +27,16 @@ func WithServiceRequest(v Request) Option {
} }
} }
func WithServiceResponse(v Response, addr *refs.Address) Option { func WithServiceResponse(v Response) Option {
return func(c *cfg) { return func(c *cfg) {
c.msg = &responseXHeaderSource{ c.msg = &responseXHeaderSource{
resp: v, resp: v,
addr: addr,
} }
} }
} }
func WithAddress(v *refs.Address) Option {
return func(c *cfg) {
c.addr = v
}
}

View file

@ -1,7 +1,6 @@
package v2 package v2
import ( import (
"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"
) )
@ -15,8 +14,6 @@ type requestXHeaderSource struct {
type responseXHeaderSource struct { type responseXHeaderSource struct {
resp Response resp Response
addr *refs.Address
} }
func (s *requestXHeaderSource) GetXHeaders() []*session.XHeader { func (s *requestXHeaderSource) GetXHeaders() []*session.XHeader {