[#193] pool: Return copy of session token in cache
To avoid side effects after token re-sign. Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
parent
f38a24e8b5
commit
2104945f9e
3 changed files with 67 additions and 1 deletions
|
@ -26,6 +26,9 @@ func newCache() (*sessionCache, error) {
|
|||
return &sessionCache{cache: cache}, nil
|
||||
}
|
||||
|
||||
// Get returns a copy of the session token from the cache without signature
|
||||
// and context related fields. Returns nil if token is missing in the cache.
|
||||
// It is safe to modify and re-sign returned session token.
|
||||
func (c *sessionCache) Get(key string) *session.Token {
|
||||
valueRaw, ok := c.cache.Get(key)
|
||||
if !ok {
|
||||
|
@ -35,7 +38,13 @@ func (c *sessionCache) Get(key string) *session.Token {
|
|||
value := valueRaw.(*cacheValue)
|
||||
value.atime = time.Now()
|
||||
|
||||
return value.token
|
||||
if value.token == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
res := copySessionTokenWithoutSignatureAndContext(*value.token)
|
||||
|
||||
return &res
|
||||
}
|
||||
|
||||
func (c *sessionCache) GetAccessTime(key string) (time.Time, bool) {
|
||||
|
|
27
pool/pool.go
27
pool/pool.go
|
@ -1582,3 +1582,30 @@ func newAddressFromCnrID(cnrID *cid.ID) *address.Address {
|
|||
addr.SetContainerID(cnrID)
|
||||
return addr
|
||||
}
|
||||
|
||||
func copySessionTokenWithoutSignatureAndContext(from session.Token) (to session.Token) {
|
||||
to.SetIat(from.Iat())
|
||||
to.SetExp(from.Exp())
|
||||
to.SetNbf(from.Nbf())
|
||||
|
||||
sessionTokenID := make([]byte, len(from.ID()))
|
||||
copy(sessionTokenID, from.ID())
|
||||
to.SetID(sessionTokenID)
|
||||
|
||||
sessionTokenKey := make([]byte, len(from.SessionKey()))
|
||||
copy(sessionTokenKey, from.SessionKey())
|
||||
to.SetSessionKey(sessionTokenKey)
|
||||
|
||||
var sessionTokenOwner owner.ID
|
||||
buf, err := from.OwnerID().Marshal()
|
||||
if err != nil {
|
||||
panic(err) // should never happen
|
||||
}
|
||||
err = sessionTokenOwner.Unmarshal(buf)
|
||||
if err != nil {
|
||||
panic(err) // should never happen
|
||||
}
|
||||
to.SetOwnerID(&sessionTokenOwner)
|
||||
|
||||
return to
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/owner"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/session"
|
||||
sessiontest "github.com/nspcc-dev/neofs-sdk-go/session/test"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
@ -639,3 +640,32 @@ func TestWaitPresence(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestCopySessionTokenWithoutSignatureAndContext(t *testing.T) {
|
||||
from := sessiontest.SignedToken()
|
||||
to := copySessionTokenWithoutSignatureAndContext(*from)
|
||||
|
||||
require.Equal(t, from.Nbf(), to.Nbf())
|
||||
require.Equal(t, from.Exp(), to.Exp())
|
||||
require.Equal(t, from.Iat(), to.Iat())
|
||||
require.Equal(t, from.ID(), to.ID())
|
||||
require.Equal(t, from.OwnerID().String(), to.OwnerID().String())
|
||||
require.Equal(t, from.SessionKey(), to.SessionKey())
|
||||
|
||||
require.Empty(t, to.Signature().Sign())
|
||||
require.Empty(t, to.Signature().Key())
|
||||
|
||||
t.Run("empty object context", func(t *testing.T) {
|
||||
octx := sessiontest.ObjectContext()
|
||||
from.SetContext(octx)
|
||||
to = copySessionTokenWithoutSignatureAndContext(*from)
|
||||
require.Nil(t, to.Context())
|
||||
})
|
||||
|
||||
t.Run("empty container context", func(t *testing.T) {
|
||||
cctx := sessiontest.ContainerContext()
|
||||
from.SetContext(cctx)
|
||||
to = copySessionTokenWithoutSignatureAndContext(*from)
|
||||
require.Nil(t, to.Context())
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue