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:
Leonard Lyubich 2020-05-08 13:39:37 +03:00 committed by GitHub
commit 87d0efaad2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 69 additions and 18 deletions

View file

@ -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
}

View file

@ -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)
}

View file

@ -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
} }

View file

@ -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)

View file

@ -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,