forked from TrueCloudLab/frostfs-sdk-go
[#336] session: Support group object sessions
Rename `LimitByObject` method of the `session.Object` type to `LimitByObjects` and make it to accept variadic parameter. Signed-off-by: Leonard Lyubich <ctulhurider@gmail.com>
This commit is contained in:
parent
c6576c8112
commit
1325b4f272
6 changed files with 99 additions and 79 deletions
2
go.mod
2
go.mod
|
@ -9,7 +9,7 @@ require (
|
|||
github.com/mr-tron/base58 v1.2.0
|
||||
github.com/nspcc-dev/hrw v1.0.9
|
||||
github.com/nspcc-dev/neo-go v0.99.2
|
||||
github.com/nspcc-dev/neofs-api-go/v2 v2.13.2-0.20220919124434-cf868188ef9c
|
||||
github.com/nspcc-dev/neofs-api-go/v2 v2.13.2-0.20221004142957-5fc2644c680d
|
||||
github.com/nspcc-dev/neofs-contract v0.15.3
|
||||
github.com/nspcc-dev/tzhash v1.6.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
|
|
4
go.sum
4
go.sum
|
@ -263,8 +263,8 @@ github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b h1:J7
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
github.com/nspcc-dev/neofs-api-go/v2 v2.11.0-pre.0.20211201134523-3604d96f3fe1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=
|
||||
github.com/nspcc-dev/neofs-api-go/v2 v2.11.1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=
|
||||
github.com/nspcc-dev/neofs-api-go/v2 v2.13.2-0.20220919124434-cf868188ef9c h1:YZwtBY9uypaShbe/NLhosDanIfxt8VhQlSLYUeFIWv8=
|
||||
github.com/nspcc-dev/neofs-api-go/v2 v2.13.2-0.20220919124434-cf868188ef9c/go.mod h1:DRIr0Ic1s+6QgdqmNFNLIqMqd7lNMJfYwkczlm1hDtM=
|
||||
github.com/nspcc-dev/neofs-api-go/v2 v2.13.2-0.20221004142957-5fc2644c680d h1:Oc15A8gDoP/TC5kdJi6TW9AnOp5dYiecZ0tJDRUV7vg=
|
||||
github.com/nspcc-dev/neofs-api-go/v2 v2.13.2-0.20221004142957-5fc2644c680d/go.mod h1:DRIr0Ic1s+6QgdqmNFNLIqMqd7lNMJfYwkczlm1hDtM=
|
||||
github.com/nspcc-dev/neofs-contract v0.15.3 h1:7+NwyTtxFAnIevz0hR/XxQf6R2Ej2scjVR2bnnJnhBM=
|
||||
github.com/nspcc-dev/neofs-contract v0.15.3/go.mod h1:BXVZUZUJxrmmDETglXHI8+5DSgn84B9y5DoSWqEjYCs=
|
||||
github.com/nspcc-dev/neofs-crypto v0.2.0/go.mod h1:F/96fUzPM3wR+UGsPi3faVNmFlA9KAEAUQR7dMxZmNA=
|
||||
|
|
|
@ -1737,7 +1737,7 @@ func (p *Pool) openDefaultSession(ctx *callContext) error {
|
|||
tok.BindContainer(ctx.sessionCnr)
|
||||
|
||||
if ctx.sessionObjSet {
|
||||
tok.LimitByObject(ctx.sessionObj)
|
||||
tok.LimitByObjects(ctx.sessionObj)
|
||||
}
|
||||
|
||||
// sign the token
|
||||
|
|
|
@ -29,8 +29,7 @@ type Object struct {
|
|||
cnrSet bool
|
||||
cnr cid.ID
|
||||
|
||||
objSet bool
|
||||
obj oid.ID
|
||||
objs []oid.ID
|
||||
}
|
||||
|
||||
func (x *Object) readContext(c session.TokenContext, checkFieldPresence bool) error {
|
||||
|
@ -39,30 +38,31 @@ func (x *Object) readContext(c session.TokenContext, checkFieldPresence bool) er
|
|||
return fmt.Errorf("invalid context %T", c)
|
||||
}
|
||||
|
||||
addr := cObj.GetAddress()
|
||||
if checkFieldPresence && addr == nil {
|
||||
return errors.New("missing object address")
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
cnr := addr.GetContainerID()
|
||||
cnr := cObj.GetContainer()
|
||||
if x.cnrSet = cnr != nil; x.cnrSet {
|
||||
err := x.cnr.ReadFromV2(*cnr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid container ID: %w", err)
|
||||
}
|
||||
} else if checkFieldPresence {
|
||||
return errors.New("missing container in object address")
|
||||
return errors.New("missing target container")
|
||||
}
|
||||
|
||||
obj := addr.GetObjectID()
|
||||
if x.objSet = obj != nil; x.objSet {
|
||||
err = x.obj.ReadFromV2(*obj)
|
||||
objs := cObj.GetObjects()
|
||||
if objs != nil {
|
||||
x.objs = make([]oid.ID, len(objs))
|
||||
|
||||
for i := range objs {
|
||||
err = x.objs[i].ReadFromV2(objs[i])
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid object ID: %w", err)
|
||||
return fmt.Errorf("invalid target object: %w", err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
x.objs = nil
|
||||
}
|
||||
|
||||
x.verb = ObjectVerb(cObj.GetVerb())
|
||||
|
||||
|
@ -85,24 +85,25 @@ func (x Object) writeContext() session.TokenContext {
|
|||
var c session.ObjectSessionContext
|
||||
c.SetVerb(session.ObjectSessionVerb(x.verb))
|
||||
|
||||
if x.cnrSet || x.objSet {
|
||||
var addr refs.Address
|
||||
if x.cnrSet || len(x.objs) > 0 {
|
||||
var cnr *refs.ContainerID
|
||||
|
||||
if x.cnrSet {
|
||||
var cnr refs.ContainerID
|
||||
x.cnr.WriteToV2(&cnr)
|
||||
|
||||
addr.SetContainerID(&cnr)
|
||||
cnr = new(refs.ContainerID)
|
||||
x.cnr.WriteToV2(cnr)
|
||||
}
|
||||
|
||||
if x.objSet {
|
||||
var obj refs.ObjectID
|
||||
x.obj.WriteToV2(&obj)
|
||||
var objs []refs.ObjectID
|
||||
|
||||
addr.SetObjectID(&obj)
|
||||
if x.objs != nil {
|
||||
objs = make([]refs.ObjectID, len(x.objs))
|
||||
|
||||
for i := range x.objs {
|
||||
x.objs[i].WriteToV2(&objs[i])
|
||||
}
|
||||
}
|
||||
|
||||
c.SetAddress(&addr)
|
||||
c.SetTarget(cnr, objs...)
|
||||
}
|
||||
|
||||
return &c
|
||||
|
@ -194,22 +195,33 @@ func (x Object) AssertContainer(cnr cid.ID) bool {
|
|||
return x.cnr.Equals(cnr)
|
||||
}
|
||||
|
||||
// LimitByObject limits session scope to a given object from the container
|
||||
// LimitByObjects limits session scope to the given objects from the container
|
||||
// to which Object session is bound.
|
||||
//
|
||||
// Argument MUST NOT be mutated, make a copy first.
|
||||
//
|
||||
// See also AssertObject.
|
||||
func (x *Object) LimitByObject(obj oid.ID) {
|
||||
x.obj = obj
|
||||
x.objSet = true
|
||||
func (x *Object) LimitByObjects(objs ...oid.ID) {
|
||||
x.objs = objs
|
||||
}
|
||||
|
||||
// AssertObject checks if Object session is applied to a given object.
|
||||
//
|
||||
// Zero Object is applied to all objects in the container.
|
||||
//
|
||||
// See also LimitByObject.
|
||||
// See also LimitByObjects.
|
||||
func (x Object) AssertObject(obj oid.ID) bool {
|
||||
return !x.objSet || x.obj.Equals(obj)
|
||||
if len(x.objs) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
for i := range x.objs {
|
||||
if x.objs[i].Equals(obj) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// ObjectVerb enumerates object operations.
|
||||
|
|
|
@ -15,7 +15,6 @@ import (
|
|||
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
|
||||
neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa"
|
||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/session"
|
||||
sessiontest "github.com/nspcc-dev/neofs-sdk-go/session/test"
|
||||
|
@ -84,15 +83,17 @@ func TestObjectProtocolV2(t *testing.T) {
|
|||
|
||||
// Context
|
||||
cnr := cidtest.ID()
|
||||
obj := oidtest.ID()
|
||||
var addr oid.Address
|
||||
addr.SetContainer(cnr)
|
||||
addr.SetObject(obj)
|
||||
var addrV2 refs.Address
|
||||
addr.WriteToV2(&addrV2)
|
||||
obj1 := oidtest.ID()
|
||||
obj2 := oidtest.ID()
|
||||
var cnrV2 refs.ContainerID
|
||||
cnr.WriteToV2(&cnrV2)
|
||||
var obj1V2 refs.ObjectID
|
||||
obj1.WriteToV2(&obj1V2)
|
||||
var obj2V2 refs.ObjectID
|
||||
obj2.WriteToV2(&obj2V2)
|
||||
var cObj v2session.ObjectSessionContext
|
||||
restoreCtx := func() {
|
||||
cObj.SetAddress(&addrV2)
|
||||
cObj.SetTarget(&cnrV2, obj1V2, obj2V2)
|
||||
body.SetContext(&cObj)
|
||||
}
|
||||
restoreCtx()
|
||||
|
@ -210,32 +211,29 @@ func TestObjectProtocolV2(t *testing.T) {
|
|||
body.SetContext(nil)
|
||||
},
|
||||
func() {
|
||||
cObj.SetAddress(new(refs.Address))
|
||||
cObj.SetTarget(nil)
|
||||
},
|
||||
func() {
|
||||
var brokenCnr refs.ContainerID
|
||||
brokenCnr.SetValue(append(addrV2.GetContainerID().GetValue(), 1))
|
||||
var addr refs.Address
|
||||
addr.SetContainerID(&brokenCnr)
|
||||
cObj.SetAddress(&addr)
|
||||
brokenCnr.SetValue(append(cnrV2.GetValue(), 1))
|
||||
cObj.SetTarget(&brokenCnr)
|
||||
},
|
||||
func() {
|
||||
var brokenObj refs.ObjectID
|
||||
brokenObj.SetValue(append(addrV2.GetContainerID().GetValue(), 1))
|
||||
var addr refs.Address
|
||||
addr.SetObjectID(&brokenObj)
|
||||
cObj.SetAddress(&addr)
|
||||
brokenObj.SetValue(append(obj1V2.GetValue(), 1))
|
||||
cObj.SetTarget(&cnrV2, brokenObj)
|
||||
},
|
||||
},
|
||||
restore: restoreCtx,
|
||||
assert: func(val session.Object) {
|
||||
require.True(t, val.AssertContainer(cnr))
|
||||
require.False(t, val.AssertContainer(cidtest.ID()))
|
||||
require.True(t, val.AssertObject(obj))
|
||||
require.True(t, val.AssertObject(obj1))
|
||||
require.True(t, val.AssertObject(obj2))
|
||||
require.False(t, val.AssertObject(oidtest.ID()))
|
||||
},
|
||||
breakSign: func(m *v2session.Token) {
|
||||
cnr := m.GetBody().GetContext().(*v2session.ObjectSessionContext).GetAddress().GetContainerID().GetValue()
|
||||
cnr := m.GetBody().GetContext().(*v2session.ObjectSessionContext).GetContainer().GetValue()
|
||||
cnr[len(cnr)-1]++
|
||||
},
|
||||
},
|
||||
|
@ -329,7 +327,8 @@ func TestObject_WriteToV2(t *testing.T) {
|
|||
assert(func(m v2session.Token) {
|
||||
cCnr, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
||||
require.True(t, ok)
|
||||
require.Zero(t, cCnr.GetAddress())
|
||||
require.Zero(t, cCnr.GetContainer())
|
||||
require.Zero(t, cCnr.GetObjects())
|
||||
})
|
||||
|
||||
cnr := cidtest.ID()
|
||||
|
@ -337,19 +336,22 @@ func TestObject_WriteToV2(t *testing.T) {
|
|||
var cnrV2 refs.ContainerID
|
||||
cnr.WriteToV2(&cnrV2)
|
||||
|
||||
obj := oidtest.ID()
|
||||
obj1 := oidtest.ID()
|
||||
obj2 := oidtest.ID()
|
||||
|
||||
var objV2 refs.ObjectID
|
||||
obj.WriteToV2(&objV2)
|
||||
var obj1V2 refs.ObjectID
|
||||
obj1.WriteToV2(&obj1V2)
|
||||
var obj2V2 refs.ObjectID
|
||||
obj2.WriteToV2(&obj2V2)
|
||||
|
||||
val.BindContainer(cnr)
|
||||
val.LimitByObject(obj)
|
||||
val.LimitByObjects(obj1, obj2)
|
||||
|
||||
assert(func(m v2session.Token) {
|
||||
cCnr, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, &cnrV2, cCnr.GetAddress().GetContainerID())
|
||||
require.Equal(t, &objV2, cCnr.GetAddress().GetObjectID())
|
||||
require.Equal(t, &cnrV2, cCnr.GetContainer())
|
||||
require.Equal(t, []refs.ObjectID{obj1V2, obj2V2}, cCnr.GetObjects())
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -361,7 +363,8 @@ func TestObject_BindContainer(t *testing.T) {
|
|||
assertDefaults := func() {
|
||||
cCnr, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
||||
require.True(t, ok)
|
||||
require.Zero(t, cCnr.GetAddress())
|
||||
require.Zero(t, cCnr.GetContainer())
|
||||
require.Zero(t, cCnr.GetObjects())
|
||||
}
|
||||
|
||||
assertBinary := func(baseAssert func()) {
|
||||
|
@ -401,7 +404,7 @@ func TestObject_BindContainer(t *testing.T) {
|
|||
assertCnr := func() {
|
||||
cObj, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, &cnrV2, cObj.GetAddress().GetContainerID())
|
||||
require.Equal(t, &cnrV2, cObj.GetContainer())
|
||||
}
|
||||
|
||||
assertCnr()
|
||||
|
@ -421,7 +424,7 @@ func TestObject_AssertContainer(t *testing.T) {
|
|||
require.True(t, x.AssertContainer(cnr))
|
||||
}
|
||||
|
||||
func TestObject_LimitByObject(t *testing.T) {
|
||||
func TestObject_LimitByObjects(t *testing.T) {
|
||||
var val session.Object
|
||||
var m v2session.Token
|
||||
filled := sessiontest.Object()
|
||||
|
@ -429,7 +432,8 @@ func TestObject_LimitByObject(t *testing.T) {
|
|||
assertDefaults := func() {
|
||||
cCnr, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
||||
require.True(t, ok)
|
||||
require.Zero(t, cCnr.GetAddress())
|
||||
require.Zero(t, cCnr.GetContainer())
|
||||
require.Zero(t, cCnr.GetObjects())
|
||||
}
|
||||
|
||||
assertBinary := func(baseAssert func()) {
|
||||
|
@ -457,19 +461,22 @@ func TestObject_LimitByObject(t *testing.T) {
|
|||
|
||||
// set value
|
||||
|
||||
obj := oidtest.ID()
|
||||
obj1 := oidtest.ID()
|
||||
obj2 := oidtest.ID()
|
||||
|
||||
var objV2 refs.ObjectID
|
||||
obj.WriteToV2(&objV2)
|
||||
var obj1V2 refs.ObjectID
|
||||
obj1.WriteToV2(&obj1V2)
|
||||
var obj2V2 refs.ObjectID
|
||||
obj2.WriteToV2(&obj2V2)
|
||||
|
||||
val.LimitByObject(obj)
|
||||
val.LimitByObjects(obj1, obj2)
|
||||
|
||||
val.WriteToV2(&m)
|
||||
|
||||
assertObj := func() {
|
||||
cObj, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, &objV2, cObj.GetAddress().GetObjectID())
|
||||
require.Equal(t, []refs.ObjectID{obj1V2, obj2V2}, cObj.GetObjects())
|
||||
}
|
||||
|
||||
assertObj()
|
||||
|
@ -480,16 +487,19 @@ func TestObject_LimitByObject(t *testing.T) {
|
|||
func TestObject_AssertObject(t *testing.T) {
|
||||
var x session.Object
|
||||
|
||||
obj := oidtest.ID()
|
||||
obj1 := oidtest.ID()
|
||||
obj2 := oidtest.ID()
|
||||
objOther := oidtest.ID()
|
||||
|
||||
require.True(t, x.AssertObject(obj))
|
||||
require.True(t, x.AssertObject(obj1))
|
||||
require.True(t, x.AssertObject(obj2))
|
||||
require.True(t, x.AssertObject(objOther))
|
||||
|
||||
x.LimitByObject(obj)
|
||||
x.LimitByObjects(obj1, obj2)
|
||||
|
||||
require.True(t, x.AssertObject(obj))
|
||||
require.False(t, x.AssertObject(obj2))
|
||||
require.True(t, x.AssertObject(obj1))
|
||||
require.True(t, x.AssertObject(obj2))
|
||||
require.False(t, x.AssertObject(objOther))
|
||||
}
|
||||
|
||||
func TestObject_InvalidAt(t *testing.T) {
|
||||
|
|
|
@ -71,11 +71,9 @@ func Object() *session.Object {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
addr := oidtest.Address()
|
||||
|
||||
tok.ForVerb(session.VerbObjectPut)
|
||||
tok.BindContainer(addr.Container())
|
||||
tok.LimitByObject(addr.Object())
|
||||
tok.BindContainer(cidtest.ID())
|
||||
tok.LimitByObjects(oidtest.ID(), oidtest.ID())
|
||||
tok.SetID(uuid.New())
|
||||
tok.SetAuthKey((*neofsecdsa.PublicKey)(&priv.PublicKey))
|
||||
tok.SetExp(11)
|
||||
|
|
Loading…
Reference in a new issue