forked from TrueCloudLab/frostfs-node
[#1052] object: Remove acl/eacl
package
Signed-off-by: Airat Arifullin <a.arifullin@yadro.com>
This commit is contained in:
parent
737788b35f
commit
291d1bf17e
5 changed files with 0 additions and 584 deletions
|
@ -1,166 +0,0 @@
|
|||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/object"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/refs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/session"
|
||||
eaclSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type testLocalStorage struct {
|
||||
t *testing.T
|
||||
|
||||
expAddr oid.Address
|
||||
|
||||
obj *objectSDK.Object
|
||||
|
||||
err error
|
||||
}
|
||||
|
||||
func (s *testLocalStorage) Head(ctx context.Context, addr oid.Address) (*objectSDK.Object, error) {
|
||||
require.True(s.t, addr.Container().Equals(s.expAddr.Container()))
|
||||
require.True(s.t, addr.Object().Equals(s.expAddr.Object()))
|
||||
|
||||
return s.obj, s.err
|
||||
}
|
||||
|
||||
func testXHeaders(strs ...string) []session.XHeader {
|
||||
res := make([]session.XHeader, len(strs)/2)
|
||||
|
||||
for i := 0; i < len(strs); i += 2 {
|
||||
res[i/2].SetKey(strs[i])
|
||||
res[i/2].SetValue(strs[i+1])
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func TestHeadRequest(t *testing.T) {
|
||||
req := new(objectV2.HeadRequest)
|
||||
|
||||
meta := new(session.RequestMetaHeader)
|
||||
req.SetMetaHeader(meta)
|
||||
|
||||
body := new(objectV2.HeadRequestBody)
|
||||
req.SetBody(body)
|
||||
|
||||
addr := oidtest.Address()
|
||||
|
||||
var addrV2 refs.Address
|
||||
addr.WriteToV2(&addrV2)
|
||||
|
||||
body.SetAddress(&addrV2)
|
||||
|
||||
xKey := "x-key"
|
||||
xVal := "x-val"
|
||||
xHdrs := testXHeaders(
|
||||
xKey, xVal,
|
||||
)
|
||||
|
||||
meta.SetXHeaders(xHdrs)
|
||||
|
||||
obj := objectSDK.New()
|
||||
|
||||
attrKey := "attr_key"
|
||||
attrVal := "attr_val"
|
||||
var attr objectSDK.Attribute
|
||||
attr.SetKey(attrKey)
|
||||
attr.SetValue(attrVal)
|
||||
obj.SetAttributes(attr)
|
||||
|
||||
table := new(eaclSDK.Table)
|
||||
|
||||
priv, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
senderKey := priv.PublicKey()
|
||||
|
||||
r := eaclSDK.NewRecord()
|
||||
r.SetOperation(eaclSDK.OperationHead)
|
||||
r.SetAction(eaclSDK.ActionDeny)
|
||||
r.AddFilter(eaclSDK.HeaderFromObject, eaclSDK.MatchStringEqual, attrKey, attrVal)
|
||||
r.AddFilter(eaclSDK.HeaderFromRequest, eaclSDK.MatchStringEqual, xKey, xVal)
|
||||
eaclSDK.AddFormedTarget(r, eaclSDK.RoleUnknown, (ecdsa.PublicKey)(*senderKey))
|
||||
|
||||
table.AddRecord(r)
|
||||
|
||||
lStorage := &testLocalStorage{
|
||||
t: t,
|
||||
expAddr: addr,
|
||||
obj: obj,
|
||||
}
|
||||
|
||||
id := addr.Object()
|
||||
|
||||
newSource := func(t *testing.T) eaclSDK.TypedHeaderSource {
|
||||
hdrSrc, err := NewMessageHeaderSource(
|
||||
lStorage,
|
||||
NewRequestXHeaderSource(req),
|
||||
addr.Container(),
|
||||
WithOID(&id))
|
||||
require.NoError(t, err)
|
||||
return hdrSrc
|
||||
}
|
||||
|
||||
cnr := addr.Container()
|
||||
|
||||
unit := new(eaclSDK.ValidationUnit).
|
||||
WithContainerID(&cnr).
|
||||
WithOperation(eaclSDK.OperationHead).
|
||||
WithSenderKey(senderKey.Bytes()).
|
||||
WithEACLTable(table)
|
||||
|
||||
validator := eaclSDK.NewValidator()
|
||||
|
||||
checkAction(t, eaclSDK.ActionDeny, validator, unit.WithHeaderSource(newSource(t)))
|
||||
|
||||
meta.SetXHeaders(nil)
|
||||
|
||||
checkDefaultAction(t, validator, unit.WithHeaderSource(newSource(t)))
|
||||
|
||||
meta.SetXHeaders(xHdrs)
|
||||
|
||||
obj.SetAttributes()
|
||||
|
||||
checkDefaultAction(t, validator, unit.WithHeaderSource(newSource(t)))
|
||||
|
||||
lStorage.err = errors.New("any error")
|
||||
|
||||
checkDefaultAction(t, validator, unit.WithHeaderSource(newSource(t)))
|
||||
|
||||
r.SetAction(eaclSDK.ActionAllow)
|
||||
|
||||
rID := eaclSDK.NewRecord()
|
||||
rID.SetOperation(eaclSDK.OperationHead)
|
||||
rID.SetAction(eaclSDK.ActionDeny)
|
||||
rID.AddObjectIDFilter(eaclSDK.MatchStringEqual, addr.Object())
|
||||
eaclSDK.AddFormedTarget(rID, eaclSDK.RoleUnknown, (ecdsa.PublicKey)(*senderKey))
|
||||
|
||||
table = eaclSDK.NewTable()
|
||||
table.AddRecord(r)
|
||||
table.AddRecord(rID)
|
||||
|
||||
unit.WithEACLTable(table)
|
||||
checkDefaultAction(t, validator, unit.WithHeaderSource(newSource(t)))
|
||||
}
|
||||
|
||||
func checkAction(t *testing.T, expected eaclSDK.Action, v *eaclSDK.Validator, u *eaclSDK.ValidationUnit) {
|
||||
actual, fromRule := v.CalculateAction(u)
|
||||
require.True(t, fromRule)
|
||||
require.Equal(t, expected, actual)
|
||||
}
|
||||
|
||||
func checkDefaultAction(t *testing.T, v *eaclSDK.Validator, u *eaclSDK.ValidationUnit) {
|
||||
actual, fromRule := v.CalculateAction(u)
|
||||
require.False(t, fromRule)
|
||||
require.Equal(t, eaclSDK.ActionAllow, actual)
|
||||
}
|
|
@ -1,246 +0,0 @@
|
|||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/acl"
|
||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/object"
|
||||
refsV2 "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/refs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/session"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
eaclSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
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"
|
||||
)
|
||||
|
||||
type Option func(*cfg)
|
||||
|
||||
type cfg struct {
|
||||
storage ObjectStorage
|
||||
|
||||
msg XHeaderSource
|
||||
|
||||
cnr cid.ID
|
||||
obj *oid.ID
|
||||
}
|
||||
|
||||
type ObjectStorage interface {
|
||||
Head(context.Context, oid.Address) (*objectSDK.Object, error)
|
||||
}
|
||||
|
||||
type Request interface {
|
||||
GetMetaHeader() *session.RequestMetaHeader
|
||||
}
|
||||
|
||||
type Response interface {
|
||||
GetMetaHeader() *session.ResponseMetaHeader
|
||||
}
|
||||
|
||||
type headerSource struct {
|
||||
requestHeaders []eaclSDK.Header
|
||||
objectHeaders []eaclSDK.Header
|
||||
|
||||
incompleteObjectHeaders bool
|
||||
}
|
||||
|
||||
func NewMessageHeaderSource(os ObjectStorage, xhs XHeaderSource, cnrID cid.ID, opts ...Option) (eaclSDK.TypedHeaderSource, error) {
|
||||
cfg := &cfg{
|
||||
storage: os,
|
||||
cnr: cnrID,
|
||||
msg: xhs,
|
||||
}
|
||||
|
||||
for i := range opts {
|
||||
opts[i](cfg)
|
||||
}
|
||||
|
||||
if cfg.msg == nil {
|
||||
return nil, errors.New("message is not provided")
|
||||
}
|
||||
|
||||
var res headerSource
|
||||
|
||||
err := cfg.readObjectHeaders(&res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res.requestHeaders = cfg.msg.GetXHeaders()
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (h headerSource) HeadersOfType(typ eaclSDK.FilterHeaderType) ([]eaclSDK.Header, bool) {
|
||||
switch typ {
|
||||
default:
|
||||
return nil, true
|
||||
case eaclSDK.HeaderFromRequest:
|
||||
return h.requestHeaders, true
|
||||
case eaclSDK.HeaderFromObject:
|
||||
return h.objectHeaders, !h.incompleteObjectHeaders
|
||||
}
|
||||
}
|
||||
|
||||
type xHeader session.XHeader
|
||||
|
||||
func (x xHeader) Key() string {
|
||||
return (*session.XHeader)(&x).GetKey()
|
||||
}
|
||||
|
||||
func (x xHeader) Value() string {
|
||||
return (*session.XHeader)(&x).GetValue()
|
||||
}
|
||||
|
||||
var errMissingOID = errors.New("object ID is missing")
|
||||
|
||||
func (h *cfg) readObjectHeaders(dst *headerSource) error {
|
||||
switch m := h.msg.(type) {
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected message type %T", h.msg))
|
||||
case requestXHeaderSource:
|
||||
return h.readObjectHeadersFromRequestXHeaderSource(m, dst)
|
||||
case responseXHeaderSource:
|
||||
return h.readObjectHeadersResponseXHeaderSource(m, dst)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *cfg) readObjectHeadersFromRequestXHeaderSource(m requestXHeaderSource, dst *headerSource) error {
|
||||
switch req := m.req.(type) {
|
||||
case
|
||||
*objectV2.GetRequest,
|
||||
*objectV2.HeadRequest:
|
||||
if h.obj == nil {
|
||||
return errMissingOID
|
||||
}
|
||||
|
||||
objHeaders, completed := h.localObjectHeaders(h.cnr, h.obj)
|
||||
|
||||
dst.objectHeaders = objHeaders
|
||||
dst.incompleteObjectHeaders = !completed
|
||||
case
|
||||
*objectV2.GetRangeRequest,
|
||||
*objectV2.GetRangeHashRequest,
|
||||
*objectV2.DeleteRequest:
|
||||
if h.obj == nil {
|
||||
return errMissingOID
|
||||
}
|
||||
|
||||
dst.objectHeaders = addressHeaders(h.cnr, h.obj)
|
||||
case *objectV2.PutRequest:
|
||||
if v, ok := req.GetBody().GetObjectPart().(*objectV2.PutObjectPartInit); ok {
|
||||
oV2 := new(objectV2.Object)
|
||||
oV2.SetObjectID(v.GetObjectID())
|
||||
oV2.SetHeader(v.GetHeader())
|
||||
|
||||
dst.objectHeaders = headersFromObject(objectSDK.NewFromV2(oV2), h.cnr, h.obj)
|
||||
}
|
||||
case *objectV2.PutSingleRequest:
|
||||
dst.objectHeaders = headersFromObject(objectSDK.NewFromV2(req.GetBody().GetObject()), h.cnr, h.obj)
|
||||
case *objectV2.SearchRequest:
|
||||
cnrV2 := req.GetBody().GetContainerID()
|
||||
var cnr cid.ID
|
||||
|
||||
if cnrV2 != nil {
|
||||
if err := cnr.ReadFromV2(*cnrV2); err != nil {
|
||||
return fmt.Errorf("can't parse container ID: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
dst.objectHeaders = []eaclSDK.Header{cidHeader(cnr)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *cfg) readObjectHeadersResponseXHeaderSource(m responseXHeaderSource, dst *headerSource) error {
|
||||
switch resp := m.resp.(type) {
|
||||
default:
|
||||
objectHeaders, completed := h.localObjectHeaders(h.cnr, h.obj)
|
||||
|
||||
dst.objectHeaders = objectHeaders
|
||||
dst.incompleteObjectHeaders = !completed
|
||||
case *objectV2.GetResponse:
|
||||
if v, ok := resp.GetBody().GetObjectPart().(*objectV2.GetObjectPartInit); ok {
|
||||
oV2 := new(objectV2.Object)
|
||||
oV2.SetObjectID(v.GetObjectID())
|
||||
oV2.SetHeader(v.GetHeader())
|
||||
|
||||
dst.objectHeaders = headersFromObject(objectSDK.NewFromV2(oV2), h.cnr, h.obj)
|
||||
}
|
||||
case *objectV2.HeadResponse:
|
||||
oV2 := new(objectV2.Object)
|
||||
|
||||
var hdr *objectV2.Header
|
||||
|
||||
switch v := resp.GetBody().GetHeaderPart().(type) {
|
||||
case *objectV2.ShortHeader:
|
||||
hdr = new(objectV2.Header)
|
||||
|
||||
var idV2 refsV2.ContainerID
|
||||
h.cnr.WriteToV2(&idV2)
|
||||
|
||||
hdr.SetContainerID(&idV2)
|
||||
hdr.SetVersion(v.GetVersion())
|
||||
hdr.SetCreationEpoch(v.GetCreationEpoch())
|
||||
hdr.SetOwnerID(v.GetOwnerID())
|
||||
hdr.SetObjectType(v.GetObjectType())
|
||||
hdr.SetPayloadLength(v.GetPayloadLength())
|
||||
case *objectV2.HeaderWithSignature:
|
||||
hdr = v.GetHeader()
|
||||
}
|
||||
|
||||
oV2.SetHeader(hdr)
|
||||
|
||||
dst.objectHeaders = headersFromObject(objectSDK.NewFromV2(oV2), h.cnr, h.obj)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *cfg) localObjectHeaders(cnr cid.ID, idObj *oid.ID) ([]eaclSDK.Header, bool) {
|
||||
if idObj != nil {
|
||||
var addr oid.Address
|
||||
addr.SetContainer(cnr)
|
||||
addr.SetObject(*idObj)
|
||||
|
||||
obj, err := h.storage.Head(context.TODO(), addr)
|
||||
if err == nil {
|
||||
return headersFromObject(obj, cnr, idObj), true
|
||||
}
|
||||
}
|
||||
|
||||
return addressHeaders(cnr, idObj), false
|
||||
}
|
||||
|
||||
func cidHeader(idCnr cid.ID) sysObjHdr {
|
||||
return sysObjHdr{
|
||||
k: acl.FilterObjectContainerID,
|
||||
v: idCnr.EncodeToString(),
|
||||
}
|
||||
}
|
||||
|
||||
func oidHeader(obj oid.ID) sysObjHdr {
|
||||
return sysObjHdr{
|
||||
k: acl.FilterObjectID,
|
||||
v: obj.EncodeToString(),
|
||||
}
|
||||
}
|
||||
|
||||
func ownerIDHeader(ownerID user.ID) sysObjHdr {
|
||||
return sysObjHdr{
|
||||
k: acl.FilterObjectOwnerID,
|
||||
v: ownerID.EncodeToString(),
|
||||
}
|
||||
}
|
||||
|
||||
func addressHeaders(cnr cid.ID, oid *oid.ID) []eaclSDK.Header {
|
||||
hh := make([]eaclSDK.Header, 0, 2)
|
||||
hh = append(hh, cidHeader(cnr))
|
||||
|
||||
if oid != nil {
|
||||
hh = append(hh, oidHeader(*oid))
|
||||
}
|
||||
|
||||
return hh
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
package v2
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/acl"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
eaclSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
)
|
||||
|
||||
type sysObjHdr struct {
|
||||
k, v string
|
||||
}
|
||||
|
||||
func (s sysObjHdr) Key() string {
|
||||
return s.k
|
||||
}
|
||||
|
||||
func (s sysObjHdr) Value() string {
|
||||
return s.v
|
||||
}
|
||||
|
||||
func u64Value(v uint64) string {
|
||||
return strconv.FormatUint(v, 10)
|
||||
}
|
||||
|
||||
func headersFromObject(obj *objectSDK.Object, cnr cid.ID, oid *oid.ID) []eaclSDK.Header {
|
||||
var count int
|
||||
for obj := obj; obj != nil; obj = obj.Parent() {
|
||||
count += 9 + len(obj.Attributes())
|
||||
}
|
||||
|
||||
res := make([]eaclSDK.Header, 0, count)
|
||||
for ; obj != nil; obj = obj.Parent() {
|
||||
res = append(res,
|
||||
cidHeader(cnr),
|
||||
// creation epoch
|
||||
sysObjHdr{
|
||||
k: acl.FilterObjectCreationEpoch,
|
||||
v: u64Value(obj.CreationEpoch()),
|
||||
},
|
||||
// payload size
|
||||
sysObjHdr{
|
||||
k: acl.FilterObjectPayloadLength,
|
||||
v: u64Value(obj.PayloadSize()),
|
||||
},
|
||||
// object version
|
||||
sysObjHdr{
|
||||
k: acl.FilterObjectVersion,
|
||||
v: obj.Version().String(),
|
||||
},
|
||||
// object type
|
||||
sysObjHdr{
|
||||
k: acl.FilterObjectType,
|
||||
v: obj.Type().String(),
|
||||
},
|
||||
)
|
||||
|
||||
if oid != nil {
|
||||
res = append(res, oidHeader(*oid))
|
||||
}
|
||||
|
||||
if idOwner := obj.OwnerID(); !idOwner.IsEmpty() {
|
||||
res = append(res, ownerIDHeader(idOwner))
|
||||
}
|
||||
|
||||
cs, ok := obj.PayloadChecksum()
|
||||
if ok {
|
||||
res = append(res, sysObjHdr{
|
||||
k: acl.FilterObjectPayloadHash,
|
||||
v: cs.String(),
|
||||
})
|
||||
}
|
||||
|
||||
cs, ok = obj.PayloadHomomorphicHash()
|
||||
if ok {
|
||||
res = append(res, sysObjHdr{
|
||||
k: acl.FilterObjectHomomorphicHash,
|
||||
v: cs.String(),
|
||||
})
|
||||
}
|
||||
|
||||
attrs := obj.Attributes()
|
||||
for i := range attrs {
|
||||
res = append(res, &attrs[i]) // only pointer attrs can implement eaclSDK.Header interface
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
package v2
|
||||
|
||||
import (
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
)
|
||||
|
||||
func WithOID(v *oid.ID) Option {
|
||||
return func(c *cfg) {
|
||||
c.obj = v
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
package v2
|
||||
|
||||
import (
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/session"
|
||||
eaclSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
)
|
||||
|
||||
type XHeaderSource interface {
|
||||
GetXHeaders() []eaclSDK.Header
|
||||
}
|
||||
|
||||
type requestXHeaderSource struct {
|
||||
req Request
|
||||
}
|
||||
|
||||
func NewRequestXHeaderSource(req Request) XHeaderSource {
|
||||
return requestXHeaderSource{req: req}
|
||||
}
|
||||
|
||||
type responseXHeaderSource struct {
|
||||
resp Response
|
||||
|
||||
req Request
|
||||
}
|
||||
|
||||
func NewResponseXHeaderSource(resp Response, req Request) XHeaderSource {
|
||||
return responseXHeaderSource{resp: resp, req: req}
|
||||
}
|
||||
|
||||
func (s requestXHeaderSource) GetXHeaders() []eaclSDK.Header {
|
||||
ln := 0
|
||||
|
||||
for meta := s.req.GetMetaHeader(); meta != nil; meta = meta.GetOrigin() {
|
||||
ln += len(meta.GetXHeaders())
|
||||
}
|
||||
|
||||
res := make([]eaclSDK.Header, 0, ln)
|
||||
for meta := s.req.GetMetaHeader(); meta != nil; meta = meta.GetOrigin() {
|
||||
x := meta.GetXHeaders()
|
||||
for i := range x {
|
||||
res = append(res, (xHeader)(x[i]))
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (s responseXHeaderSource) GetXHeaders() []eaclSDK.Header {
|
||||
ln := 0
|
||||
xHdrs := make([][]session.XHeader, 0)
|
||||
|
||||
for meta := s.req.GetMetaHeader(); meta != nil; meta = meta.GetOrigin() {
|
||||
x := meta.GetXHeaders()
|
||||
|
||||
ln += len(x)
|
||||
|
||||
xHdrs = append(xHdrs, x)
|
||||
}
|
||||
|
||||
res := make([]eaclSDK.Header, 0, ln)
|
||||
|
||||
for i := range xHdrs {
|
||||
for j := range xHdrs[i] {
|
||||
res = append(res, xHeader(xHdrs[i][j]))
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
Loading…
Add table
Reference in a new issue