Merge pull request #76 from nspcc-dev/private-token-key-owner
session: add OwnerID to a private token storage key
This commit is contained in:
commit
87d0efaad2
5 changed files with 69 additions and 18 deletions
|
@ -43,3 +43,13 @@ func (t *pToken) PublicKey() []byte {
|
||||||
func (t *pToken) Expired(epoch uint64) bool {
|
func (t *pToken) Expired(epoch uint64) bool {
|
||||||
return t.validUntil < epoch
|
return t.validUntil < epoch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetOwnerID is an owner ID field setter.
|
||||||
|
func (s *PrivateTokenKey) SetOwnerID(id OwnerID) {
|
||||||
|
s.owner = id
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTokenID is a token ID field setter.
|
||||||
|
func (s *PrivateTokenKey) SetTokenID(id TokenID) {
|
||||||
|
s.token = id
|
||||||
|
}
|
||||||
|
|
|
@ -48,3 +48,23 @@ func TestPToken_Expired(t *testing.T) {
|
||||||
// must be expired in the epoch after last
|
// must be expired in the epoch after last
|
||||||
require.True(t, token.Expired(e+1))
|
require.True(t, token.Expired(e+1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPrivateTokenKey_SetOwnerID(t *testing.T) {
|
||||||
|
ownerID := OwnerID{1, 2, 3}
|
||||||
|
|
||||||
|
s := new(PrivateTokenKey)
|
||||||
|
|
||||||
|
s.SetOwnerID(ownerID)
|
||||||
|
|
||||||
|
require.Equal(t, ownerID, s.owner)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateTokenKey_SetTokenID(t *testing.T) {
|
||||||
|
tokenID := TokenID{1, 2, 3}
|
||||||
|
|
||||||
|
s := new(PrivateTokenKey)
|
||||||
|
|
||||||
|
s.SetTokenID(tokenID)
|
||||||
|
|
||||||
|
require.Equal(t, tokenID, s.token)
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
type mapTokenStore struct {
|
type mapTokenStore struct {
|
||||||
*sync.RWMutex
|
*sync.RWMutex
|
||||||
|
|
||||||
tokens map[TokenID]PrivateToken
|
tokens map[PrivateTokenKey]PrivateToken
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMapTokenStore creates new PrivateTokenStore instance.
|
// NewMapTokenStore creates new PrivateTokenStore instance.
|
||||||
|
@ -16,16 +16,16 @@ type mapTokenStore struct {
|
||||||
func NewMapTokenStore() PrivateTokenStore {
|
func NewMapTokenStore() PrivateTokenStore {
|
||||||
return &mapTokenStore{
|
return &mapTokenStore{
|
||||||
RWMutex: new(sync.RWMutex),
|
RWMutex: new(sync.RWMutex),
|
||||||
tokens: make(map[TokenID]PrivateToken),
|
tokens: make(map[PrivateTokenKey]PrivateToken),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store adds passed token to the map.
|
// Store adds passed token to the map.
|
||||||
//
|
//
|
||||||
// Resulting error is always nil.
|
// Resulting error is always nil.
|
||||||
func (s *mapTokenStore) Store(id TokenID, token PrivateToken) error {
|
func (s *mapTokenStore) Store(key PrivateTokenKey, token PrivateToken) error {
|
||||||
s.Lock()
|
s.Lock()
|
||||||
s.tokens[id] = token
|
s.tokens[key] = token
|
||||||
s.Unlock()
|
s.Unlock()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -34,11 +34,11 @@ func (s *mapTokenStore) Store(id TokenID, token PrivateToken) error {
|
||||||
// Fetch returns the map element corresponding to the given key.
|
// Fetch returns the map element corresponding to the given key.
|
||||||
//
|
//
|
||||||
// Returns ErrPrivateTokenNotFound is there is no element in map.
|
// Returns ErrPrivateTokenNotFound is there is no element in map.
|
||||||
func (s *mapTokenStore) Fetch(id TokenID) (PrivateToken, error) {
|
func (s *mapTokenStore) Fetch(key PrivateTokenKey) (PrivateToken, error) {
|
||||||
s.RLock()
|
s.RLock()
|
||||||
defer s.RUnlock()
|
defer s.RUnlock()
|
||||||
|
|
||||||
t, ok := s.tokens[id]
|
t, ok := s.tokens[key]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ErrPrivateTokenNotFound
|
return nil, ErrPrivateTokenNotFound
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,19 +15,26 @@ func TestMapTokenStore(t *testing.T) {
|
||||||
// create map token store
|
// create map token store
|
||||||
s := NewMapTokenStore()
|
s := NewMapTokenStore()
|
||||||
|
|
||||||
// create new storage key
|
// create test TokenID
|
||||||
id, err := refs.NewUUID()
|
tid, err := refs.NewUUID()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// create test OwnerID
|
||||||
|
ownerID := OwnerID{1, 2, 3}
|
||||||
|
|
||||||
|
key := PrivateTokenKey{}
|
||||||
|
key.SetOwnerID(ownerID)
|
||||||
|
key.SetTokenID(tid)
|
||||||
|
|
||||||
// ascertain that there is no record for the key
|
// ascertain that there is no record for the key
|
||||||
_, err = s.Fetch(id)
|
_, err = s.Fetch(key)
|
||||||
require.EqualError(t, err, ErrPrivateTokenNotFound.Error())
|
require.EqualError(t, err, ErrPrivateTokenNotFound.Error())
|
||||||
|
|
||||||
// save private token record
|
// save private token record
|
||||||
require.NoError(t, s.Store(id, pToken))
|
require.NoError(t, s.Store(key, pToken))
|
||||||
|
|
||||||
// fetch private token by the key
|
// fetch private token by the key
|
||||||
res, err := s.Fetch(id)
|
res, err := s.Fetch(key)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// ascertain that returned token equals to initial
|
// ascertain that returned token equals to initial
|
||||||
|
@ -52,7 +59,11 @@ func TestMapTokenStore_RemoveExpired(t *testing.T) {
|
||||||
// create token store instance
|
// create token store instance
|
||||||
s := NewMapTokenStore()
|
s := NewMapTokenStore()
|
||||||
|
|
||||||
// create storage keys for tokens
|
// create test PrivateTokenKey
|
||||||
|
key := PrivateTokenKey{}
|
||||||
|
key.SetOwnerID(OwnerID{1, 2, 3})
|
||||||
|
|
||||||
|
// create IDs for tokens
|
||||||
id1, err := refs.NewUUID()
|
id1, err := refs.NewUUID()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
id2, err := refs.NewUUID()
|
id2, err := refs.NewUUID()
|
||||||
|
@ -60,21 +71,25 @@ func TestMapTokenStore_RemoveExpired(t *testing.T) {
|
||||||
|
|
||||||
assertPresence := func(ids ...TokenID) {
|
assertPresence := func(ids ...TokenID) {
|
||||||
for i := range ids {
|
for i := range ids {
|
||||||
_, err = s.Fetch(ids[i])
|
key.SetTokenID(ids[i])
|
||||||
|
_, err = s.Fetch(key)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assertAbsence := func(ids ...TokenID) {
|
assertAbsence := func(ids ...TokenID) {
|
||||||
for i := range ids {
|
for i := range ids {
|
||||||
_, err = s.Fetch(ids[i])
|
key.SetTokenID(ids[i])
|
||||||
|
_, err = s.Fetch(key)
|
||||||
require.EqualError(t, err, ErrPrivateTokenNotFound.Error())
|
require.EqualError(t, err, ErrPrivateTokenNotFound.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// store both tokens
|
// store both tokens
|
||||||
require.NoError(t, s.Store(id1, tok1))
|
key.SetTokenID(id1)
|
||||||
require.NoError(t, s.Store(id2, tok2))
|
require.NoError(t, s.Store(key, tok1))
|
||||||
|
key.SetTokenID(id2)
|
||||||
|
require.NoError(t, s.Store(key, tok2))
|
||||||
|
|
||||||
// ascertain that both tokens are available
|
// ascertain that both tokens are available
|
||||||
assertPresence(id1, id2)
|
assertPresence(id1, id2)
|
||||||
|
|
|
@ -23,12 +23,18 @@ type PrivateToken interface {
|
||||||
Expired(uint64) bool
|
Expired(uint64) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PrivateTokenKey is a structure of private token storage key.
|
||||||
|
type PrivateTokenKey struct {
|
||||||
|
owner OwnerID
|
||||||
|
token TokenID
|
||||||
|
}
|
||||||
|
|
||||||
// PrivateTokenSource is an interface of private token storage with read access.
|
// PrivateTokenSource is an interface of private token storage with read access.
|
||||||
type PrivateTokenSource interface {
|
type PrivateTokenSource interface {
|
||||||
// Fetch must return the storage record corresponding to the passed key.
|
// Fetch must return the storage record corresponding to the passed key.
|
||||||
//
|
//
|
||||||
// Resulting error must be ErrPrivateTokenNotFound if there is no corresponding record.
|
// Resulting error must be ErrPrivateTokenNotFound if there is no corresponding record.
|
||||||
Fetch(TokenID) (PrivateToken, error)
|
Fetch(PrivateTokenKey) (PrivateToken, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EpochLifetimeStore is an interface of the storage of elements that lifetime is limited by NeoFS epoch.
|
// EpochLifetimeStore is an interface of the storage of elements that lifetime is limited by NeoFS epoch.
|
||||||
|
@ -45,7 +51,7 @@ type PrivateTokenStore interface {
|
||||||
// Store must save passed private token in the storage under the given key.
|
// Store must save passed private token in the storage under the given key.
|
||||||
//
|
//
|
||||||
// Resulting error must be nil if private token was stored successfully.
|
// Resulting error must be nil if private token was stored successfully.
|
||||||
Store(TokenID, PrivateToken) error
|
Store(PrivateTokenKey, PrivateToken) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeyStore is an interface of the storage of public keys addressable by OwnerID,
|
// KeyStore is an interface of the storage of public keys addressable by OwnerID,
|
||||||
|
|
Loading…
Reference in a new issue