forked from TrueCloudLab/frostfs-sdk-go
[#197] session: Refactor and document the package
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
497053c785
commit
552c7875bf
32 changed files with 1622 additions and 1358 deletions
|
@ -1,123 +1,296 @@
|
|||
package session_test
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
v2session "github.com/nspcc-dev/neofs-api-go/v2/session"
|
||||
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
|
||||
neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
||||
addresstest "github.com/nspcc-dev/neofs-sdk-go/object/address/test"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/session"
|
||||
sessiontest "github.com/nspcc-dev/neofs-sdk-go/session/test"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestObjectContextVerbs(t *testing.T) {
|
||||
c := session.NewObjectContext()
|
||||
|
||||
assert := func(setter func(), getter func() bool, verb v2session.ObjectSessionVerb) {
|
||||
setter()
|
||||
|
||||
require.True(t, getter())
|
||||
|
||||
require.Equal(t, verb, c.ToV2().GetVerb())
|
||||
func randSigner() ecdsa.PrivateKey {
|
||||
k, err := keys.NewPrivateKey()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("generate private key: %v", err))
|
||||
}
|
||||
|
||||
t.Run("PUT", func(t *testing.T) {
|
||||
assert(c.ForPut, c.IsForPut, v2session.ObjectVerbPut)
|
||||
return k.PrivateKey
|
||||
}
|
||||
|
||||
func randPublicKey() neofscrypto.PublicKey {
|
||||
k := randSigner().PublicKey
|
||||
return (*neofsecdsa.PublicKey)(&k)
|
||||
}
|
||||
|
||||
func TestObject_ReadFromV2(t *testing.T) {
|
||||
var x session.Object
|
||||
var m v2session.Token
|
||||
var b v2session.TokenBody
|
||||
var c v2session.ObjectSessionContext
|
||||
id := uuid.New()
|
||||
|
||||
t.Run("protocol violation", func(t *testing.T) {
|
||||
require.Error(t, x.ReadFromV2(m))
|
||||
|
||||
m.SetBody(&b)
|
||||
|
||||
require.Error(t, x.ReadFromV2(m))
|
||||
|
||||
b.SetID(id[:])
|
||||
|
||||
require.Error(t, x.ReadFromV2(m))
|
||||
|
||||
b.SetContext(&c)
|
||||
|
||||
require.NoError(t, x.ReadFromV2(m))
|
||||
})
|
||||
|
||||
t.Run("DELETE", func(t *testing.T) {
|
||||
assert(c.ForDelete, c.IsForDelete, v2session.ObjectVerbDelete)
|
||||
m.SetBody(&b)
|
||||
b.SetContext(&c)
|
||||
b.SetID(id[:])
|
||||
|
||||
t.Run("object", func(t *testing.T) {
|
||||
var obj address.Address
|
||||
|
||||
require.NoError(t, x.ReadFromV2(m))
|
||||
require.True(t, x.AppliedTo(obj))
|
||||
|
||||
obj = *addresstest.Address()
|
||||
|
||||
objv2 := *obj.ToV2()
|
||||
|
||||
c.SetAddress(&objv2)
|
||||
|
||||
require.NoError(t, x.ReadFromV2(m))
|
||||
require.True(t, x.AppliedTo(obj))
|
||||
})
|
||||
|
||||
t.Run("GET", func(t *testing.T) {
|
||||
assert(c.ForGet, c.IsForGet, v2session.ObjectVerbGet)
|
||||
t.Run("verb", func(t *testing.T) {
|
||||
require.NoError(t, x.ReadFromV2(m))
|
||||
require.True(t, x.AssertVerb(0))
|
||||
|
||||
verb := v2session.ObjectSessionVerb(rand.Uint32())
|
||||
|
||||
c.SetVerb(verb)
|
||||
|
||||
require.NoError(t, x.ReadFromV2(m))
|
||||
require.True(t, x.AssertVerb(session.ObjectVerb(verb)))
|
||||
})
|
||||
|
||||
t.Run("SEARCH", func(t *testing.T) {
|
||||
assert(c.ForSearch, c.IsForSearch, v2session.ObjectVerbSearch)
|
||||
t.Run("id", func(t *testing.T) {
|
||||
id := uuid.New()
|
||||
bID := id[:]
|
||||
|
||||
b.SetID(bID)
|
||||
|
||||
require.NoError(t, x.ReadFromV2(m))
|
||||
require.Equal(t, id, x.ID())
|
||||
})
|
||||
|
||||
t.Run("RANGE", func(t *testing.T) {
|
||||
assert(c.ForRange, c.IsForRange, v2session.ObjectVerbRange)
|
||||
t.Run("lifetime", func(t *testing.T) {
|
||||
const nbf, iat, exp = 11, 22, 33
|
||||
|
||||
var lt v2session.TokenLifetime
|
||||
lt.SetNbf(nbf)
|
||||
lt.SetIat(iat)
|
||||
lt.SetExp(exp)
|
||||
|
||||
b.SetLifetime(<)
|
||||
|
||||
require.NoError(t, x.ReadFromV2(m))
|
||||
require.False(t, x.ExpiredAt(exp-1))
|
||||
require.True(t, x.ExpiredAt(exp))
|
||||
require.True(t, x.ExpiredAt(exp+1))
|
||||
require.True(t, x.InvalidAt(nbf-1))
|
||||
require.True(t, x.InvalidAt(iat-1))
|
||||
require.False(t, x.InvalidAt(iat))
|
||||
require.False(t, x.InvalidAt(exp-1))
|
||||
require.True(t, x.InvalidAt(exp))
|
||||
require.True(t, x.InvalidAt(exp+1))
|
||||
})
|
||||
|
||||
t.Run("RANGEHASH", func(t *testing.T) {
|
||||
assert(c.ForRangeHash, c.IsForRangeHash, v2session.ObjectVerbRangeHash)
|
||||
})
|
||||
t.Run("session key", func(t *testing.T) {
|
||||
key := randPublicKey()
|
||||
|
||||
t.Run("HEAD", func(t *testing.T) {
|
||||
assert(c.ForHead, c.IsForHead, v2session.ObjectVerbHead)
|
||||
bKey := make([]byte, key.MaxEncodedSize())
|
||||
bKey = bKey[:key.Encode(bKey)]
|
||||
|
||||
b.SetSessionKey(bKey)
|
||||
|
||||
require.NoError(t, x.ReadFromV2(m))
|
||||
require.True(t, x.AssertAuthKey(key))
|
||||
})
|
||||
}
|
||||
|
||||
func TestObjectContext_ApplyTo(t *testing.T) {
|
||||
c := session.NewObjectContext()
|
||||
id := addresstest.Address()
|
||||
|
||||
t.Run("method", func(t *testing.T) {
|
||||
c.ApplyTo(id)
|
||||
|
||||
require.Equal(t, id, c.Address())
|
||||
|
||||
c.ApplyTo(nil)
|
||||
|
||||
require.Nil(t, c.Address())
|
||||
})
|
||||
}
|
||||
|
||||
func TestObjectFilter_ToV2(t *testing.T) {
|
||||
t.Run("nil", func(t *testing.T) {
|
||||
var x *session.ObjectContext
|
||||
|
||||
require.Nil(t, x.ToV2())
|
||||
})
|
||||
|
||||
t.Run("default values", func(t *testing.T) {
|
||||
c := session.NewObjectContext()
|
||||
|
||||
// check initial values
|
||||
require.Nil(t, c.Address())
|
||||
|
||||
for _, op := range []func() bool{
|
||||
c.IsForPut,
|
||||
c.IsForDelete,
|
||||
c.IsForGet,
|
||||
c.IsForHead,
|
||||
c.IsForRange,
|
||||
c.IsForRangeHash,
|
||||
c.IsForSearch,
|
||||
} {
|
||||
require.False(t, op())
|
||||
}
|
||||
|
||||
// convert to v2 message
|
||||
cV2 := c.ToV2()
|
||||
|
||||
require.Equal(t, v2session.ObjectVerbUnknown, cV2.GetVerb())
|
||||
require.Nil(t, cV2.GetAddress())
|
||||
})
|
||||
}
|
||||
|
||||
func TestObjectContextEncoding(t *testing.T) {
|
||||
c := sessiontest.ObjectContext()
|
||||
func TestEncodingObject(t *testing.T) {
|
||||
tok := *sessiontest.ObjectSigned()
|
||||
|
||||
t.Run("binary", func(t *testing.T) {
|
||||
data, err := c.Marshal()
|
||||
require.NoError(t, err)
|
||||
data := tok.Marshal()
|
||||
|
||||
c2 := session.NewObjectContext()
|
||||
require.NoError(t, c2.Unmarshal(data))
|
||||
var tok2 session.Object
|
||||
require.NoError(t, tok2.Unmarshal(data))
|
||||
|
||||
require.Equal(t, c, c2)
|
||||
require.Equal(t, tok, tok2)
|
||||
})
|
||||
|
||||
t.Run("json", func(t *testing.T) {
|
||||
data, err := c.MarshalJSON()
|
||||
data, err := tok.MarshalJSON()
|
||||
require.NoError(t, err)
|
||||
|
||||
c2 := session.NewObjectContext()
|
||||
require.NoError(t, c2.UnmarshalJSON(data))
|
||||
var tok2 session.Object
|
||||
require.NoError(t, tok2.UnmarshalJSON(data))
|
||||
|
||||
require.Equal(t, c, c2)
|
||||
require.Equal(t, tok, tok2)
|
||||
})
|
||||
}
|
||||
|
||||
func TestObjectAppliedTo(t *testing.T) {
|
||||
var x session.Object
|
||||
|
||||
a := *addresstest.Address()
|
||||
|
||||
require.False(t, x.AppliedTo(a))
|
||||
|
||||
x.ApplyTo(a)
|
||||
|
||||
require.True(t, x.AppliedTo(a))
|
||||
}
|
||||
|
||||
func TestObjectExp(t *testing.T) {
|
||||
var x session.Object
|
||||
|
||||
exp := rand.Uint64()
|
||||
|
||||
require.True(t, x.ExpiredAt(exp))
|
||||
|
||||
x.SetExp(exp)
|
||||
|
||||
require.False(t, x.ExpiredAt(exp-1))
|
||||
require.True(t, x.ExpiredAt(exp))
|
||||
require.True(t, x.ExpiredAt(exp+1))
|
||||
}
|
||||
|
||||
func TestObjectLifetime(t *testing.T) {
|
||||
var x session.Object
|
||||
|
||||
nbf := rand.Uint64()
|
||||
if nbf == math.MaxUint64 {
|
||||
nbf--
|
||||
}
|
||||
|
||||
iat := nbf
|
||||
exp := iat + 1
|
||||
|
||||
x.SetNbf(nbf)
|
||||
x.SetIat(iat)
|
||||
x.SetExp(exp)
|
||||
|
||||
require.True(t, x.InvalidAt(nbf-1))
|
||||
require.True(t, x.InvalidAt(iat-1))
|
||||
require.False(t, x.InvalidAt(iat))
|
||||
require.True(t, x.InvalidAt(exp))
|
||||
}
|
||||
|
||||
func TestObjectID(t *testing.T) {
|
||||
var x session.Object
|
||||
|
||||
require.Zero(t, x.ID())
|
||||
|
||||
id := uuid.New()
|
||||
|
||||
x.SetID(id)
|
||||
|
||||
require.Equal(t, id, x.ID())
|
||||
}
|
||||
|
||||
func TestObjectAuthKey(t *testing.T) {
|
||||
var x session.Object
|
||||
|
||||
key := randPublicKey()
|
||||
|
||||
require.False(t, x.AssertAuthKey(key))
|
||||
|
||||
x.SetAuthKey(key)
|
||||
|
||||
require.True(t, x.AssertAuthKey(key))
|
||||
}
|
||||
|
||||
func TestObjectVerb(t *testing.T) {
|
||||
var x session.Object
|
||||
|
||||
const v1, v2 = session.VerbObjectGet, session.VerbObjectPut
|
||||
|
||||
require.False(t, x.AssertVerb(v1, v2))
|
||||
|
||||
x.ForVerb(v1)
|
||||
require.True(t, x.AssertVerb(v1))
|
||||
require.False(t, x.AssertVerb(v2))
|
||||
require.True(t, x.AssertVerb(v1, v2))
|
||||
require.True(t, x.AssertVerb(v2, v1))
|
||||
}
|
||||
|
||||
func TestObjectSignature(t *testing.T) {
|
||||
var x session.Object
|
||||
|
||||
const nbf = 11
|
||||
const iat = 22
|
||||
const exp = 33
|
||||
id := uuid.New()
|
||||
key := randPublicKey()
|
||||
obj := *addresstest.Address()
|
||||
verb := session.VerbObjectDelete
|
||||
|
||||
signer := randSigner()
|
||||
|
||||
fs := []func(){
|
||||
func() { x.SetNbf(nbf) },
|
||||
func() { x.SetNbf(nbf + 1) },
|
||||
|
||||
func() { x.SetIat(iat) },
|
||||
func() { x.SetIat(iat + 1) },
|
||||
|
||||
func() { x.SetExp(exp) },
|
||||
func() { x.SetExp(exp + 1) },
|
||||
|
||||
func() { x.SetID(id) },
|
||||
func() {
|
||||
idcp := id
|
||||
idcp[0]++
|
||||
x.SetID(idcp)
|
||||
},
|
||||
|
||||
func() { x.SetAuthKey(key) },
|
||||
func() { x.SetAuthKey(randPublicKey()) },
|
||||
|
||||
func() { x.ApplyTo(obj) },
|
||||
func() { x.ApplyTo(*addresstest.Address()) },
|
||||
|
||||
func() { x.ForVerb(verb) },
|
||||
func() { x.ForVerb(verb + 1) },
|
||||
}
|
||||
|
||||
for i := 0; i < len(fs); i += 2 {
|
||||
fs[i]()
|
||||
|
||||
require.NoError(t, x.Sign(signer))
|
||||
require.True(t, x.VerifySignature())
|
||||
|
||||
fs[i+1]()
|
||||
require.False(t, x.VerifySignature())
|
||||
|
||||
fs[i]()
|
||||
require.True(t, x.VerifySignature())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue