[#283] pkg/token: Replace SessionToken into a session package

There is a need to add session token to `eacl.Table` structure. To do this,
we need to replace `token.SessionToken` type to another package since `eacl`
package imports `token` one (potential cross-import).

Create `pkg/session` package and replace session token implementation to it.
Related API in `container` package is deprecated from now.

Additionally implement test generator of random session tokens.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2021-05-24 20:34:56 +03:00 committed by Alex Vanin
parent fcbe0bbd2e
commit 37b415347d
5 changed files with 246 additions and 118 deletions

View file

@ -7,14 +7,14 @@ import (
"github.com/nspcc-dev/neofs-api-go/pkg" "github.com/nspcc-dev/neofs-api-go/pkg"
"github.com/nspcc-dev/neofs-api-go/pkg/netmap" "github.com/nspcc-dev/neofs-api-go/pkg/netmap"
"github.com/nspcc-dev/neofs-api-go/pkg/owner" "github.com/nspcc-dev/neofs-api-go/pkg/owner"
"github.com/nspcc-dev/neofs-api-go/pkg/token" "github.com/nspcc-dev/neofs-api-go/pkg/session"
"github.com/nspcc-dev/neofs-api-go/v2/container" "github.com/nspcc-dev/neofs-api-go/v2/container"
) )
type Container struct { type Container struct {
v2 container.Container v2 container.Container
token *token.SessionToken token *session.Token
sig *pkg.Signature sig *pkg.Signature
} }
@ -159,13 +159,13 @@ func (c *Container) SetPlacementPolicy(v *netmap.PlacementPolicy) {
// SessionToken returns token of the session within // SessionToken returns token of the session within
// which container was created. // which container was created.
func (c Container) SessionToken() *token.SessionToken { func (c Container) SessionToken() *session.Token {
return c.token return c.token
} }
// SetSessionToken sets token of the session within // SetSessionToken sets token of the session within
// which container was created. // which container was created.
func (c *Container) SetSessionToken(t *token.SessionToken) { func (c *Container) SetSessionToken(t *session.Token) {
c.token = t c.token = t
} }

125
pkg/session/session.go Normal file
View file

@ -0,0 +1,125 @@
package session
import (
"github.com/nspcc-dev/neofs-api-go/pkg"
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
"github.com/nspcc-dev/neofs-api-go/v2/session"
)
// Token represents NeoFS API v2-compatible
// session token.
type Token session.SessionToken
// NewTokenFromV2 wraps session.SessionToken message structure
// into Token.
func NewTokenFromV2(tV2 *session.SessionToken) *Token {
return (*Token)(tV2)
}
// NewToken creates and returns blank Token.
func NewToken() *Token {
return NewTokenFromV2(new(session.SessionToken))
}
// ToV2 converts Token to session.SessionToken message structure.
func (t *Token) ToV2() *session.SessionToken {
return (*session.SessionToken)(t)
}
func (t *Token) setBodyField(setter func(*session.SessionTokenBody)) {
token := (*session.SessionToken)(t)
body := token.GetBody()
if body == nil {
body = new(session.SessionTokenBody)
token.SetBody(body)
}
setter(body)
}
// ID returns Token identifier.
func (t *Token) ID() []byte {
return (*session.SessionToken)(t).
GetBody().
GetID()
}
// SetID sets Token identifier.
func (t *Token) SetID(v []byte) {
t.setBodyField(func(body *session.SessionTokenBody) {
body.SetID(v)
})
}
// OwnerID returns Token's owner identifier.
func (t *Token) OwnerID() *owner.ID {
return owner.NewIDFromV2(
(*session.SessionToken)(t).
GetBody().
GetOwnerID(),
)
}
// SetOwnerID sets Token's owner identifier.
func (t *Token) SetOwnerID(v *owner.ID) {
t.setBodyField(func(body *session.SessionTokenBody) {
body.SetOwnerID(v.ToV2())
})
}
// SessionKey returns public key of the session
// in a binary format.
func (t *Token) SessionKey() []byte {
return (*session.SessionToken)(t).
GetBody().
GetSessionKey()
}
// SetSessionKey sets public key of the session
// // in a binary format.
func (t *Token) SetSessionKey(v []byte) {
t.setBodyField(func(body *session.SessionTokenBody) {
body.SetSessionKey(v)
})
}
// Signature returns Token signature.
func (t *Token) Signature() *pkg.Signature {
return pkg.NewSignatureFromV2(
(*session.SessionToken)(t).
GetSignature(),
)
}
// Marshal marshals Token into a protobuf binary form.
//
// Buffer is allocated when the argument is empty.
// Otherwise, the first buffer is used.
func (t *Token) Marshal(bs ...[]byte) ([]byte, error) {
var buf []byte
if len(bs) > 0 {
buf = bs[0]
}
return (*session.SessionToken)(t).
StableMarshal(buf)
}
// Unmarshal unmarshals protobuf binary representation of Token.
func (t *Token) Unmarshal(data []byte) error {
return (*session.SessionToken)(t).
Unmarshal(data)
}
// MarshalJSON encodes Token to protobuf JSON format.
func (t *Token) MarshalJSON() ([]byte, error) {
return (*session.SessionToken)(t).
MarshalJSON()
}
// UnmarshalJSON decodes Token from protobuf JSON format.
func (t *Token) UnmarshalJSON(data []byte) error {
return (*session.SessionToken)(t).
UnmarshalJSON(data)
}

View file

@ -0,0 +1,68 @@
package session_test
import (
"crypto/rand"
"testing"
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
"github.com/nspcc-dev/neofs-api-go/pkg/session"
sessiontest "github.com/nspcc-dev/neofs-api-go/pkg/session/test"
"github.com/stretchr/testify/require"
)
func TestSessionToken_SetID(t *testing.T) {
token := session.NewToken()
id := []byte{1, 2, 3}
token.SetID(id)
require.Equal(t, id, token.ID())
}
func TestSessionToken_SetOwnerID(t *testing.T) {
token := session.NewToken()
w := new(owner.NEO3Wallet)
_, err := rand.Read(w.Bytes())
require.NoError(t, err)
ownerID := owner.NewID()
ownerID.SetNeo3Wallet(w)
token.SetOwnerID(ownerID)
require.Equal(t, ownerID, token.OwnerID())
}
func TestSessionToken_SetSessionKey(t *testing.T) {
token := session.NewToken()
key := []byte{1, 2, 3}
token.SetSessionKey(key)
require.Equal(t, key, token.SessionKey())
}
func TestSessionTokenEncoding(t *testing.T) {
tok := sessiontest.Generate()
t.Run("binary", func(t *testing.T) {
data, err := tok.Marshal()
require.NoError(t, err)
tok2 := session.NewToken()
require.NoError(t, tok2.Unmarshal(data))
require.Equal(t, tok, tok2)
})
t.Run("json", func(t *testing.T) {
data, err := tok.MarshalJSON()
require.NoError(t, err)
tok2 := session.NewToken()
require.NoError(t, tok2.UnmarshalJSON(data))
require.Equal(t, tok, tok2)
})
}

35
pkg/session/test/token.go Normal file
View file

@ -0,0 +1,35 @@
package sessiontest
import (
"math/rand"
"github.com/google/uuid"
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
"github.com/nspcc-dev/neofs-api-go/pkg/session"
crypto "github.com/nspcc-dev/neofs-crypto"
"github.com/nspcc-dev/neofs-crypto/test"
)
// Generate returns random session.Token.
func Generate() *session.Token {
tok := session.NewToken()
uid, err := uuid.New().MarshalBinary()
if err != nil {
panic(err)
}
w := new(owner.NEO3Wallet)
rand.Read(w.Bytes())
ownerID := owner.NewID()
ownerID.SetNeo3Wallet(w)
keyBin := crypto.MarshalPublicKey(&test.DecodeKey(0).PublicKey)
tok.SetID(uid)
tok.SetOwnerID(ownerID)
tok.SetSessionKey(keyBin)
return tok
}

View file

@ -1,122 +1,22 @@
package token package token
import ( import (
"github.com/nspcc-dev/neofs-api-go/pkg" "github.com/nspcc-dev/neofs-api-go/pkg/session"
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
"github.com/nspcc-dev/neofs-api-go/v2/session"
) )
type SessionToken session.SessionToken // SessionToken represents NeoFS API v2-compatible
// session token.
func NewSessionTokenFromV2(tV2 *session.SessionToken) *SessionToken {
return (*SessionToken)(tV2)
}
func NewSessionToken() *SessionToken {
return NewSessionTokenFromV2(new(session.SessionToken))
}
func (t *SessionToken) ToV2() *session.SessionToken {
return (*session.SessionToken)(t)
}
func (t *SessionToken) setBodyField(setter func(*session.SessionTokenBody)) {
token := (*session.SessionToken)(t)
body := token.GetBody()
if body == nil {
body = new(session.SessionTokenBody)
token.SetBody(body)
}
setter(body)
}
func (t *SessionToken) ID() []byte {
return (*session.SessionToken)(t).
GetBody().
GetID()
}
func (t *SessionToken) SetID(v []byte) {
t.setBodyField(func(body *session.SessionTokenBody) {
body.SetID(v)
})
}
func (t *SessionToken) OwnerID() *owner.ID {
return owner.NewIDFromV2(
(*session.SessionToken)(t).
GetBody().
GetOwnerID(),
)
}
func (t *SessionToken) SetOwnerID(v *owner.ID) {
t.setBodyField(func(body *session.SessionTokenBody) {
body.SetOwnerID(v.ToV2())
})
}
func (t *SessionToken) SessionKey() []byte {
return (*session.SessionToken)(t).
GetBody().
GetSessionKey()
}
func (t *SessionToken) SetSessionKey(v []byte) {
t.setBodyField(func(body *session.SessionTokenBody) {
body.SetSessionKey(v)
})
}
func (t *SessionToken) Signature() *pkg.Signature {
return pkg.NewSignatureFromV2(
(*session.SessionToken)(t).
GetSignature(),
)
}
// Marshal marshals SessionToken into a protobuf binary form.
// //
// Buffer is allocated when the argument is empty. // Deprecated: use session.Token instead
// Otherwise, the first buffer is used. type SessionToken = session.Token
func (t *SessionToken) Marshal(bs ...[]byte) ([]byte, error) {
var buf []byte
if len(bs) > 0 {
buf = bs[0]
}
return (*session.SessionToken)(t). // NewSessionTokenFromV2 wraps session.SessionToken message structure
StableMarshal(buf) // into Token.
} //
// Deprecated: use session.NewTokenFromV2 instead.
var NewSessionTokenFromV2 = session.NewTokenFromV2
// Unmarshal unmarshals protobuf binary representation of SessionToken. // NewSessionToken creates and returns blank session token.
func (t *SessionToken) Unmarshal(data []byte) error { //
tV2 := new(session.SessionToken) // Deprecated: use session.NewToken instead.
if err := tV2.Unmarshal(data); err != nil { var NewSessionToken = session.NewToken
return err
}
*t = *NewSessionTokenFromV2(tV2)
return nil
}
// MarshalJSON encodes SessionToken to protobuf JSON format.
func (t *SessionToken) MarshalJSON() ([]byte, error) {
return (*session.SessionToken)(t).
MarshalJSON()
}
// UnmarshalJSON decodes SessionToken from protobuf JSON format.
func (t *SessionToken) UnmarshalJSON(data []byte) error {
tV2 := new(session.SessionToken)
if err := tV2.UnmarshalJSON(data); err != nil {
return err
}
*t = *NewSessionTokenFromV2(tV2)
return nil
}