[#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 97 additions and 77 deletions
2
go.mod
2
go.mod
|
@ -9,7 +9,7 @@ require (
|
||||||
github.com/mr-tron/base58 v1.2.0
|
github.com/mr-tron/base58 v1.2.0
|
||||||
github.com/nspcc-dev/hrw v1.0.9
|
github.com/nspcc-dev/hrw v1.0.9
|
||||||
github.com/nspcc-dev/neo-go v0.99.2
|
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/neofs-contract v0.15.3
|
||||||
github.com/nspcc-dev/tzhash v1.6.1
|
github.com/nspcc-dev/tzhash v1.6.1
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
|
|
BIN
go.sum
BIN
go.sum
Binary file not shown.
|
@ -1737,7 +1737,7 @@ func (p *Pool) openDefaultSession(ctx *callContext) error {
|
||||||
tok.BindContainer(ctx.sessionCnr)
|
tok.BindContainer(ctx.sessionCnr)
|
||||||
|
|
||||||
if ctx.sessionObjSet {
|
if ctx.sessionObjSet {
|
||||||
tok.LimitByObject(ctx.sessionObj)
|
tok.LimitByObjects(ctx.sessionObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sign the token
|
// sign the token
|
||||||
|
|
|
@ -29,8 +29,7 @@ type Object struct {
|
||||||
cnrSet bool
|
cnrSet bool
|
||||||
cnr cid.ID
|
cnr cid.ID
|
||||||
|
|
||||||
objSet bool
|
objs []oid.ID
|
||||||
obj oid.ID
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Object) readContext(c session.TokenContext, checkFieldPresence bool) error {
|
func (x *Object) readContext(c session.TokenContext, checkFieldPresence bool) error {
|
||||||
|
@ -39,29 +38,30 @@ func (x *Object) readContext(c session.TokenContext, checkFieldPresence bool) er
|
||||||
return fmt.Errorf("invalid context %T", c)
|
return fmt.Errorf("invalid context %T", c)
|
||||||
}
|
}
|
||||||
|
|
||||||
addr := cObj.GetAddress()
|
|
||||||
if checkFieldPresence && addr == nil {
|
|
||||||
return errors.New("missing object address")
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
cnr := addr.GetContainerID()
|
cnr := cObj.GetContainer()
|
||||||
if x.cnrSet = cnr != nil; x.cnrSet {
|
if x.cnrSet = cnr != nil; x.cnrSet {
|
||||||
err := x.cnr.ReadFromV2(*cnr)
|
err := x.cnr.ReadFromV2(*cnr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid container ID: %w", err)
|
return fmt.Errorf("invalid container ID: %w", err)
|
||||||
}
|
}
|
||||||
} else if checkFieldPresence {
|
} else if checkFieldPresence {
|
||||||
return errors.New("missing container in object address")
|
return errors.New("missing target container")
|
||||||
}
|
}
|
||||||
|
|
||||||
obj := addr.GetObjectID()
|
objs := cObj.GetObjects()
|
||||||
if x.objSet = obj != nil; x.objSet {
|
if objs != nil {
|
||||||
err = x.obj.ReadFromV2(*obj)
|
x.objs = make([]oid.ID, len(objs))
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("invalid object ID: %w", err)
|
for i := range objs {
|
||||||
|
err = x.objs[i].ReadFromV2(objs[i])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid target object: %w", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
x.objs = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
x.verb = ObjectVerb(cObj.GetVerb())
|
x.verb = ObjectVerb(cObj.GetVerb())
|
||||||
|
@ -85,24 +85,25 @@ func (x Object) writeContext() session.TokenContext {
|
||||||
var c session.ObjectSessionContext
|
var c session.ObjectSessionContext
|
||||||
c.SetVerb(session.ObjectSessionVerb(x.verb))
|
c.SetVerb(session.ObjectSessionVerb(x.verb))
|
||||||
|
|
||||||
if x.cnrSet || x.objSet {
|
if x.cnrSet || len(x.objs) > 0 {
|
||||||
var addr refs.Address
|
var cnr *refs.ContainerID
|
||||||
|
|
||||||
if x.cnrSet {
|
if x.cnrSet {
|
||||||
var cnr refs.ContainerID
|
cnr = new(refs.ContainerID)
|
||||||
x.cnr.WriteToV2(&cnr)
|
x.cnr.WriteToV2(cnr)
|
||||||
|
|
||||||
addr.SetContainerID(&cnr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if x.objSet {
|
var objs []refs.ObjectID
|
||||||
var obj refs.ObjectID
|
|
||||||
x.obj.WriteToV2(&obj)
|
|
||||||
|
|
||||||
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
|
return &c
|
||||||
|
@ -194,22 +195,33 @@ func (x Object) AssertContainer(cnr cid.ID) bool {
|
||||||
return x.cnr.Equals(cnr)
|
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.
|
// to which Object session is bound.
|
||||||
//
|
//
|
||||||
|
// Argument MUST NOT be mutated, make a copy first.
|
||||||
|
//
|
||||||
// See also AssertObject.
|
// See also AssertObject.
|
||||||
func (x *Object) LimitByObject(obj oid.ID) {
|
func (x *Object) LimitByObjects(objs ...oid.ID) {
|
||||||
x.obj = obj
|
x.objs = objs
|
||||||
x.objSet = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssertObject checks if Object session is applied to a given object.
|
// AssertObject checks if Object session is applied to a given object.
|
||||||
//
|
//
|
||||||
// Zero Object is applied to all objects in the container.
|
// Zero Object is applied to all objects in the container.
|
||||||
//
|
//
|
||||||
// See also LimitByObject.
|
// See also LimitByObjects.
|
||||||
func (x Object) AssertObject(obj oid.ID) bool {
|
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.
|
// ObjectVerb enumerates object operations.
|
||||||
|
|
|
@ -15,7 +15,6 @@ import (
|
||||||
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||||
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
|
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
|
||||||
neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa"
|
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"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/session"
|
"github.com/nspcc-dev/neofs-sdk-go/session"
|
||||||
sessiontest "github.com/nspcc-dev/neofs-sdk-go/session/test"
|
sessiontest "github.com/nspcc-dev/neofs-sdk-go/session/test"
|
||||||
|
@ -84,15 +83,17 @@ func TestObjectProtocolV2(t *testing.T) {
|
||||||
|
|
||||||
// Context
|
// Context
|
||||||
cnr := cidtest.ID()
|
cnr := cidtest.ID()
|
||||||
obj := oidtest.ID()
|
obj1 := oidtest.ID()
|
||||||
var addr oid.Address
|
obj2 := oidtest.ID()
|
||||||
addr.SetContainer(cnr)
|
var cnrV2 refs.ContainerID
|
||||||
addr.SetObject(obj)
|
cnr.WriteToV2(&cnrV2)
|
||||||
var addrV2 refs.Address
|
var obj1V2 refs.ObjectID
|
||||||
addr.WriteToV2(&addrV2)
|
obj1.WriteToV2(&obj1V2)
|
||||||
|
var obj2V2 refs.ObjectID
|
||||||
|
obj2.WriteToV2(&obj2V2)
|
||||||
var cObj v2session.ObjectSessionContext
|
var cObj v2session.ObjectSessionContext
|
||||||
restoreCtx := func() {
|
restoreCtx := func() {
|
||||||
cObj.SetAddress(&addrV2)
|
cObj.SetTarget(&cnrV2, obj1V2, obj2V2)
|
||||||
body.SetContext(&cObj)
|
body.SetContext(&cObj)
|
||||||
}
|
}
|
||||||
restoreCtx()
|
restoreCtx()
|
||||||
|
@ -210,32 +211,29 @@ func TestObjectProtocolV2(t *testing.T) {
|
||||||
body.SetContext(nil)
|
body.SetContext(nil)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
cObj.SetAddress(new(refs.Address))
|
cObj.SetTarget(nil)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
var brokenCnr refs.ContainerID
|
var brokenCnr refs.ContainerID
|
||||||
brokenCnr.SetValue(append(addrV2.GetContainerID().GetValue(), 1))
|
brokenCnr.SetValue(append(cnrV2.GetValue(), 1))
|
||||||
var addr refs.Address
|
cObj.SetTarget(&brokenCnr)
|
||||||
addr.SetContainerID(&brokenCnr)
|
|
||||||
cObj.SetAddress(&addr)
|
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
var brokenObj refs.ObjectID
|
var brokenObj refs.ObjectID
|
||||||
brokenObj.SetValue(append(addrV2.GetContainerID().GetValue(), 1))
|
brokenObj.SetValue(append(obj1V2.GetValue(), 1))
|
||||||
var addr refs.Address
|
cObj.SetTarget(&cnrV2, brokenObj)
|
||||||
addr.SetObjectID(&brokenObj)
|
|
||||||
cObj.SetAddress(&addr)
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
restore: restoreCtx,
|
restore: restoreCtx,
|
||||||
assert: func(val session.Object) {
|
assert: func(val session.Object) {
|
||||||
require.True(t, val.AssertContainer(cnr))
|
require.True(t, val.AssertContainer(cnr))
|
||||||
require.False(t, val.AssertContainer(cidtest.ID()))
|
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()))
|
require.False(t, val.AssertObject(oidtest.ID()))
|
||||||
},
|
},
|
||||||
breakSign: func(m *v2session.Token) {
|
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]++
|
cnr[len(cnr)-1]++
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -329,7 +327,8 @@ func TestObject_WriteToV2(t *testing.T) {
|
||||||
assert(func(m v2session.Token) {
|
assert(func(m v2session.Token) {
|
||||||
cCnr, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
cCnr, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
require.Zero(t, cCnr.GetAddress())
|
require.Zero(t, cCnr.GetContainer())
|
||||||
|
require.Zero(t, cCnr.GetObjects())
|
||||||
})
|
})
|
||||||
|
|
||||||
cnr := cidtest.ID()
|
cnr := cidtest.ID()
|
||||||
|
@ -337,19 +336,22 @@ func TestObject_WriteToV2(t *testing.T) {
|
||||||
var cnrV2 refs.ContainerID
|
var cnrV2 refs.ContainerID
|
||||||
cnr.WriteToV2(&cnrV2)
|
cnr.WriteToV2(&cnrV2)
|
||||||
|
|
||||||
obj := oidtest.ID()
|
obj1 := oidtest.ID()
|
||||||
|
obj2 := oidtest.ID()
|
||||||
|
|
||||||
var objV2 refs.ObjectID
|
var obj1V2 refs.ObjectID
|
||||||
obj.WriteToV2(&objV2)
|
obj1.WriteToV2(&obj1V2)
|
||||||
|
var obj2V2 refs.ObjectID
|
||||||
|
obj2.WriteToV2(&obj2V2)
|
||||||
|
|
||||||
val.BindContainer(cnr)
|
val.BindContainer(cnr)
|
||||||
val.LimitByObject(obj)
|
val.LimitByObjects(obj1, obj2)
|
||||||
|
|
||||||
assert(func(m v2session.Token) {
|
assert(func(m v2session.Token) {
|
||||||
cCnr, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
cCnr, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
require.Equal(t, &cnrV2, cCnr.GetAddress().GetContainerID())
|
require.Equal(t, &cnrV2, cCnr.GetContainer())
|
||||||
require.Equal(t, &objV2, cCnr.GetAddress().GetObjectID())
|
require.Equal(t, []refs.ObjectID{obj1V2, obj2V2}, cCnr.GetObjects())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,7 +363,8 @@ func TestObject_BindContainer(t *testing.T) {
|
||||||
assertDefaults := func() {
|
assertDefaults := func() {
|
||||||
cCnr, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
cCnr, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
require.Zero(t, cCnr.GetAddress())
|
require.Zero(t, cCnr.GetContainer())
|
||||||
|
require.Zero(t, cCnr.GetObjects())
|
||||||
}
|
}
|
||||||
|
|
||||||
assertBinary := func(baseAssert func()) {
|
assertBinary := func(baseAssert func()) {
|
||||||
|
@ -401,7 +404,7 @@ func TestObject_BindContainer(t *testing.T) {
|
||||||
assertCnr := func() {
|
assertCnr := func() {
|
||||||
cObj, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
cObj, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
require.Equal(t, &cnrV2, cObj.GetAddress().GetContainerID())
|
require.Equal(t, &cnrV2, cObj.GetContainer())
|
||||||
}
|
}
|
||||||
|
|
||||||
assertCnr()
|
assertCnr()
|
||||||
|
@ -421,7 +424,7 @@ func TestObject_AssertContainer(t *testing.T) {
|
||||||
require.True(t, x.AssertContainer(cnr))
|
require.True(t, x.AssertContainer(cnr))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestObject_LimitByObject(t *testing.T) {
|
func TestObject_LimitByObjects(t *testing.T) {
|
||||||
var val session.Object
|
var val session.Object
|
||||||
var m v2session.Token
|
var m v2session.Token
|
||||||
filled := sessiontest.Object()
|
filled := sessiontest.Object()
|
||||||
|
@ -429,7 +432,8 @@ func TestObject_LimitByObject(t *testing.T) {
|
||||||
assertDefaults := func() {
|
assertDefaults := func() {
|
||||||
cCnr, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
cCnr, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
require.Zero(t, cCnr.GetAddress())
|
require.Zero(t, cCnr.GetContainer())
|
||||||
|
require.Zero(t, cCnr.GetObjects())
|
||||||
}
|
}
|
||||||
|
|
||||||
assertBinary := func(baseAssert func()) {
|
assertBinary := func(baseAssert func()) {
|
||||||
|
@ -457,19 +461,22 @@ func TestObject_LimitByObject(t *testing.T) {
|
||||||
|
|
||||||
// set value
|
// set value
|
||||||
|
|
||||||
obj := oidtest.ID()
|
obj1 := oidtest.ID()
|
||||||
|
obj2 := oidtest.ID()
|
||||||
|
|
||||||
var objV2 refs.ObjectID
|
var obj1V2 refs.ObjectID
|
||||||
obj.WriteToV2(&objV2)
|
obj1.WriteToV2(&obj1V2)
|
||||||
|
var obj2V2 refs.ObjectID
|
||||||
|
obj2.WriteToV2(&obj2V2)
|
||||||
|
|
||||||
val.LimitByObject(obj)
|
val.LimitByObjects(obj1, obj2)
|
||||||
|
|
||||||
val.WriteToV2(&m)
|
val.WriteToV2(&m)
|
||||||
|
|
||||||
assertObj := func() {
|
assertObj := func() {
|
||||||
cObj, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
cObj, ok := m.GetBody().GetContext().(*v2session.ObjectSessionContext)
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
require.Equal(t, &objV2, cObj.GetAddress().GetObjectID())
|
require.Equal(t, []refs.ObjectID{obj1V2, obj2V2}, cObj.GetObjects())
|
||||||
}
|
}
|
||||||
|
|
||||||
assertObj()
|
assertObj()
|
||||||
|
@ -480,16 +487,19 @@ func TestObject_LimitByObject(t *testing.T) {
|
||||||
func TestObject_AssertObject(t *testing.T) {
|
func TestObject_AssertObject(t *testing.T) {
|
||||||
var x session.Object
|
var x session.Object
|
||||||
|
|
||||||
obj := oidtest.ID()
|
obj1 := oidtest.ID()
|
||||||
obj2 := 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(obj2))
|
||||||
|
require.True(t, x.AssertObject(objOther))
|
||||||
|
|
||||||
x.LimitByObject(obj)
|
x.LimitByObjects(obj1, obj2)
|
||||||
|
|
||||||
require.True(t, x.AssertObject(obj))
|
require.True(t, x.AssertObject(obj1))
|
||||||
require.False(t, x.AssertObject(obj2))
|
require.True(t, x.AssertObject(obj2))
|
||||||
|
require.False(t, x.AssertObject(objOther))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestObject_InvalidAt(t *testing.T) {
|
func TestObject_InvalidAt(t *testing.T) {
|
||||||
|
|
|
@ -71,11 +71,9 @@ func Object() *session.Object {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
addr := oidtest.Address()
|
|
||||||
|
|
||||||
tok.ForVerb(session.VerbObjectPut)
|
tok.ForVerb(session.VerbObjectPut)
|
||||||
tok.BindContainer(addr.Container())
|
tok.BindContainer(cidtest.ID())
|
||||||
tok.LimitByObject(addr.Object())
|
tok.LimitByObjects(oidtest.ID(), oidtest.ID())
|
||||||
tok.SetID(uuid.New())
|
tok.SetID(uuid.New())
|
||||||
tok.SetAuthKey((*neofsecdsa.PublicKey)(&priv.PublicKey))
|
tok.SetAuthKey((*neofsecdsa.PublicKey)(&priv.PublicKey))
|
||||||
tok.SetExp(11)
|
tok.SetExp(11)
|
||||||
|
|
Loading…
Reference in a new issue