Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ Changelog for NeoFS Node
### Changed
- SN returns unsigned responses to requests with API >= `v2.22` (#3785)
- Move lens `write-cache` `get`/`list` commands into `fstree` section in CLI (#3838)
- Session key storage access session keys by account only (#3817)

### Removed

### Updated
- `github.com/nspcc-dev/neofs-sdk-go` module to `v1.0.0-rc.17.0.20260211130529-740a11a64a87` (#3785)
- `github.com/nspcc-dev/neofs-sdk-go` module to `v1.0.0-rc.17.0.20260219114115-99622c87f029` (#3785, #3817)

### Updating from v0.51.1

Expand Down
3 changes: 3 additions & 0 deletions cmd/neofs-node/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,9 @@ func initCfg(appCfg *config.Config) *cfg {
fatalOnErr(err)
}

err = persistate.MigrateSessionTokensToAccounts()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it gonna migrate until we remove it? can be tight to node's version. but no-op migration should not be a problem though

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we'll remove it at some point, but I don't know how to determine when that point will be.

fatalOnErr(err)

basicSharedConfig := initBasics(c, key, persistate)
streamTimeout := appCfg.APIClient.StreamTimeout
minConnTimeout := appCfg.APIClient.MinConnectionTime
Expand Down
9 changes: 4 additions & 5 deletions cmd/neofs-node/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"sync/atomic"
"time"

"github.com/google/uuid"
lru "github.com/hashicorp/golang-lru/v2"
iec "github.com/nspcc-dev/neofs-node/internal/ec"
coreclient "github.com/nspcc-dev/neofs-node/pkg/core/client"
Expand Down Expand Up @@ -627,16 +626,16 @@ func (x storageForObjectService) VerifyAndStoreObjectLocally(obj object.Object)
return x.putSvc.ValidateAndStoreObjectLocally(obj)
}

func (x storageForObjectService) GetSessionPrivateKey(usr user.ID, uid uuid.UUID) (ecdsa.PrivateKey, error) {
k, err := x.keys.GetKey(&util.SessionInfo{ID: uid, Owner: usr})
func (x storageForObjectService) GetSessionPrivateKey(account user.ID) (ecdsa.PrivateKey, error) {
k, err := x.keys.GetKey(&account)
if err != nil {
return ecdsa.PrivateKey{}, err
}
return *k, nil
}

func (x storageForObjectService) GetSessionV2PrivateKey(issuer user.ID, subjects []sessionv2.Target) (ecdsa.PrivateKey, error) {
k, err := x.keys.GetKeyBySubjects(issuer, subjects)
func (x storageForObjectService) GetSessionV2PrivateKey(subjects []sessionv2.Target) (ecdsa.PrivateKey, error) {
k, err := x.keys.GetKeyBySubjects(subjects)
if err != nil {
return ecdsa.PrivateKey{}, err
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/neofs-node/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (

type sessionStorage interface {
sessionSvc.KeyStorage
GetToken(ownerID user.ID, tokenID []byte) *session.PrivateToken
FindTokenBySubjects(owner user.ID, subjects []sessionv2.Target) *session.PrivateToken
GetToken(account user.ID) *session.PrivateToken
FindTokenBySubjects(subjects []sessionv2.Target) *session.PrivateToken
RemoveOldTokens(epoch uint64)

Close() error
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ require (
github.com/nspcc-dev/neo-go v0.117.0
github.com/nspcc-dev/neofs-api-go/v2 v2.14.1-0.20240827150555-5ce597aa14ea
github.com/nspcc-dev/neofs-contract v0.26.1
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.17.0.20260211130529-740a11a64a87
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.17.0.20260219114115-99622c87f029
github.com/nspcc-dev/tzhash v1.8.3
github.com/panjf2000/ants/v2 v2.11.3
github.com/prometheus/client_golang v1.23.2
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,8 @@ github.com/nspcc-dev/neofs-api-go/v2 v2.14.1-0.20240827150555-5ce597aa14ea h1:mK
github.com/nspcc-dev/neofs-api-go/v2 v2.14.1-0.20240827150555-5ce597aa14ea/go.mod h1:YzhD4EZmC9Z/PNyd7ysC7WXgIgURc9uCG1UWDeV027Y=
github.com/nspcc-dev/neofs-contract v0.26.1 h1:7Ii7Q4L3au408LOsIWKiSgfnT1g8G9jo3W7381d41T8=
github.com/nspcc-dev/neofs-contract v0.26.1/go.mod h1:pevVF9OWdEN5bweKxOu6ryZv9muCEtS1ppzYM4RfBIo=
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.17.0.20260211130529-740a11a64a87 h1:RlOzZGS7925Dz5F6OckibMSLv/awqhla2D8PeO9nIHI=
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.17.0.20260211130529-740a11a64a87/go.mod h1:y2vNz9DVTqBkR7ctYb6taLnabWTtG7xtCHlGofEpKOM=
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.17.0.20260219114115-99622c87f029 h1:7EvHXn5LAzbZ25pwz+4qwLxG2f1H8jqjCOe0E1aR9gw=
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.17.0.20260219114115-99622c87f029/go.mod h1:y2vNz9DVTqBkR7ctYb6taLnabWTtG7xtCHlGofEpKOM=
github.com/nspcc-dev/rfc6979 v0.2.4 h1:NBgsdCjhLpEPJZqmC9rciMZDcSY297po2smeaRjw57k=
github.com/nspcc-dev/rfc6979 v0.2.4/go.mod h1:86ylDw6Kss+P6v4QAJqo1Sp3mC0/Zr9G97xSjQ9TuFg=
github.com/nspcc-dev/tzhash v1.8.3 h1:EWJMOL/ppdqNBvkKjHECljusopcsNu4i4kH8KctTv10=
Expand Down
13 changes: 7 additions & 6 deletions pkg/services/object/delete/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package deletesvc

import (
"context"
"fmt"

"github.com/nspcc-dev/neofs-node/pkg/services/object/util"
"github.com/nspcc-dev/neofs-sdk-go/user"
"go.uber.org/zap"
)
Expand All @@ -13,7 +13,7 @@ func (s *Service) Delete(ctx context.Context, prm Prm) error {
// If session token is not found we will fail during tombstone PUT.
// Here we fail immediately to ensure no unnecessary network communication is done.
if tokV2 := prm.common.SessionTokenV2(); tokV2 != nil {
if _, err := s.keyStorage.GetKeyBySubjects(tokV2.Issuer(), tokV2.Subjects()); err != nil {
if _, err := s.keyStorage.GetKeyBySubjects(tokV2.Subjects()); err != nil {
if s.nnsResolver == nil {
return err
}
Expand All @@ -31,10 +31,11 @@ func (s *Service) Delete(ctx context.Context, prm Prm) error {
}
}
} else if tok := prm.common.SessionToken(); tok != nil {
_, err := s.keyStorage.GetKey(&util.SessionInfo{
ID: tok.ID(),
Owner: tok.Issuer(),
})
authUser, err := tok.AuthUser()
if err != nil {
return fmt.Errorf("can't get auth user from token: %w", err)
}
_, err = s.keyStorage.GetKey(&authUser)
if err != nil {
return err
}
Expand Down
12 changes: 6 additions & 6 deletions pkg/services/object/get/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"io"

clientcore "github.com/nspcc-dev/neofs-node/pkg/core/client"
"github.com/nspcc-dev/neofs-node/pkg/services/object/util"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/netmap"
"github.com/nspcc-dev/neofs-sdk-go/object"
Expand Down Expand Up @@ -172,7 +171,7 @@ func (exec execCtx) key() (*ecdsa.PrivateKey, error) {
}
if tokV2 := exec.prm.common.SessionTokenV2(); tokV2 != nil {
// For V2 tokens, the key is stored as the subjects
if keyForSession, err := exec.svc.keyStore.GetKeyBySubjects(tokV2.Issuer(), tokV2.Subjects()); err == nil {
if keyForSession, err := exec.svc.keyStore.GetKeyBySubjects(tokV2.Subjects()); err == nil {
key = keyForSession
} else if exec.svc.nnsResolver != nil {
nodeUser := user.NewFromECDSAPublicKey(key.PublicKey)
Expand All @@ -188,10 +187,11 @@ func (exec execCtx) key() (*ecdsa.PrivateKey, error) {
return nil, fmt.Errorf("get key for session v2 token: %w", err)
}
} else if tok := exec.prm.common.SessionToken(); tok != nil {
key, err = exec.svc.keyStore.GetKey(&util.SessionInfo{
ID: tok.ID(),
Owner: tok.Issuer(),
})
authUser, err := tok.AuthUser()
if err != nil {
return nil, fmt.Errorf("could not get session auth user: %w", err)
}
key, err = exec.svc.keyStore.GetKey(&authUser)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/services/object/get/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ type cfg struct {
}

keyStore interface {
GetKey(*util.SessionInfo) (*ecdsa.PrivateKey, error)
GetKeyBySubjects(user.ID, []sessionv2.Target) (*ecdsa.PrivateKey, error)
GetKey(*user.ID) (*ecdsa.PrivateKey, error)
GetKeyBySubjects([]sessionv2.Target) (*ecdsa.PrivateKey, error)
}

nnsResolver sessionv2.NNSResolver
Expand Down
4 changes: 2 additions & 2 deletions pkg/services/object/get/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,11 @@ type mockKeyStorage struct {
privKey ecdsa.PrivateKey
}

func (x *mockKeyStorage) GetKey(*util.SessionInfo) (*ecdsa.PrivateKey, error) {
func (x *mockKeyStorage) GetKey(*user.ID) (*ecdsa.PrivateKey, error) {
return &x.privKey, nil
}

func (x *mockKeyStorage) GetKeyBySubjects(user.ID, []sessionv2.Target) (*ecdsa.PrivateKey, error) {
func (x *mockKeyStorage) GetKeyBySubjects([]sessionv2.Target) (*ecdsa.PrivateKey, error) {
return &x.privKey, nil
}

Expand Down
10 changes: 5 additions & 5 deletions pkg/services/object/put/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,16 @@ func putObjectToNode(ctx context.Context, nodeInfo clientcore.NodeInfo, obj *obj

if tokV2 := commonPrm.SessionTokenV2(); tokV2 != nil {
// For V2 tokens, the key is stored as the subjects
if keyForSession, err := keyStorage.GetKeyBySubjects(tokV2.Issuer(), tokV2.Subjects()); err == nil {
if keyForSession, err := keyStorage.GetKeyBySubjects(tokV2.Subjects()); err == nil {
key = keyForSession
}
opts.WithinSessionV2(*tokV2)
} else if tok := commonPrm.SessionToken(); tok != nil {
sessionInfo := &util.SessionInfo{
ID: tok.ID(),
Owner: tok.Issuer(),
authUser, err := tok.AuthUser()
if err != nil {
return fmt.Errorf("could not get session auth user: %w", err)
}
key, err = keyStorage.GetKey(sessionInfo)
key, err = keyStorage.GetKey(&authUser)
if err != nil {
return fmt.Errorf("could not receive private key: %w", err)
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/services/object/put/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -893,11 +893,11 @@ type mockNodeSession struct {
expiresAt uint64
}

func (x mockNodeSession) FindTokenBySubjects(user.ID, []sessionv2.Target) *storage.PrivateToken {
func (x mockNodeSession) FindTokenBySubjects([]sessionv2.Target) *storage.PrivateToken {
return storage.NewPrivateToken(&x.signer.ECDSAPrivateKey, x.expiresAt)
}

func (x mockNodeSession) GetToken(user.ID, []byte) *storage.PrivateToken {
func (x mockNodeSession) GetToken(user.ID) *storage.PrivateToken {
return storage.NewPrivateToken(&x.signer.ECDSAPrivateKey, x.expiresAt)
}

Expand Down
11 changes: 5 additions & 6 deletions pkg/services/object/put/streamer.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
iec "github.com/nspcc-dev/neofs-node/internal/ec"
"github.com/nspcc-dev/neofs-node/pkg/core/client"
"github.com/nspcc-dev/neofs-node/pkg/services/object/internal"
"github.com/nspcc-dev/neofs-node/pkg/services/object/util"
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
"github.com/nspcc-dev/neofs-sdk-go/container"
neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa"
Expand Down Expand Up @@ -104,7 +103,7 @@ func (p *Streamer) initTarget(prm *PutInitPrm) error {
}
if sTokenV2 != nil {
// For V2 tokens, the key is stored as the subjects
if keyForSession, err := p.keyStorage.GetKeyBySubjects(sTokenV2.Issuer(), sTokenV2.Subjects()); err == nil {
if keyForSession, err := p.keyStorage.GetKeyBySubjects(sTokenV2.Subjects()); err == nil {
sessionKey = keyForSession
} else if p.nnsResolver != nil {
nodeUser := user.NewFromECDSAPublicKey(sessionKey.PublicKey)
Expand All @@ -120,11 +119,11 @@ func (p *Streamer) initTarget(prm *PutInitPrm) error {
return fmt.Errorf("get key for session v2 token: %w", err)
}
} else if sToken != nil {
sessionInfo := &util.SessionInfo{
ID: sToken.ID(),
Owner: sToken.Issuer(),
authUser, err := sToken.AuthUser()
if err != nil {
return fmt.Errorf("could not get session auth user: %w", err)
}
sessionKey, err = p.keyStorage.GetKey(sessionInfo)
sessionKey, err = p.keyStorage.GetKey(&authUser)
if err != nil {
return fmt.Errorf("(%T) could not receive session key: %w", p, err)
}
Expand Down
12 changes: 6 additions & 6 deletions pkg/services/object/search/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (

"github.com/nspcc-dev/neofs-node/pkg/core/client"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/engine"
"github.com/nspcc-dev/neofs-node/pkg/services/object/util"
sdkclient "github.com/nspcc-dev/neofs-sdk-go/client"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
sessionv2 "github.com/nspcc-dev/neofs-sdk-go/session/v2"
Expand Down Expand Up @@ -83,7 +82,7 @@ func (c *clientWrapper) searchObjects(ctx context.Context, exec *execCtx) ([]oid
}
if tokV2 := exec.prm.common.SessionTokenV2(); tokV2 != nil {
// For V2 tokens, the key is stored as the subjects
if keyForSession, err := exec.svc.keyStore.GetKeyBySubjects(tokV2.Issuer(), tokV2.Subjects()); err == nil {
if keyForSession, err := exec.svc.keyStore.GetKeyBySubjects(tokV2.Subjects()); err == nil {
key = keyForSession
} else if exec.svc.nnsResolver != nil {
nodeUser := user.NewFromECDSAPublicKey(key.PublicKey)
Expand All @@ -99,10 +98,11 @@ func (c *clientWrapper) searchObjects(ctx context.Context, exec *execCtx) ([]oid
return nil, fmt.Errorf("get key for session v2 token: %w", err)
}
} else if tok := exec.prm.common.SessionToken(); tok != nil {
key, err = exec.svc.keyStore.GetKey(&util.SessionInfo{
ID: tok.ID(),
Owner: tok.Issuer(),
})
authUser, err := tok.AuthUser()
if err != nil {
return nil, fmt.Errorf("could not get session auth user: %w", err)
}
key, err = exec.svc.keyStore.GetKey(&authUser)
if err != nil {
return nil, err
}
Expand Down
17 changes: 10 additions & 7 deletions pkg/services/object/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"sync/atomic"
"time"

"github.com/google/uuid"
icrypto "github.com/nspcc-dev/neofs-node/internal/crypto"
"github.com/nspcc-dev/neofs-node/pkg/core/client"
"github.com/nspcc-dev/neofs-node/pkg/core/container"
Expand Down Expand Up @@ -122,15 +121,15 @@ type FSChain interface {
}

type sessions interface {
// GetSessionPrivateKey reads private session key by user and session IDs.
// GetSessionPrivateKey reads private session key by his account.
// Returns [apistatus.ErrSessionTokenNotFound] if there is no data for the
// referenced session.
GetSessionPrivateKey(usr user.ID, uid uuid.UUID) (ecdsa.PrivateKey, error)
GetSessionPrivateKey(account user.ID) (ecdsa.PrivateKey, error)

// GetSessionV2PrivateKey reads private session key by user ID and session
// GetSessionV2PrivateKey reads private session key by session
// subject. Returns [apistatus.ErrSessionTokenNotFound] if there is no data
// for the referenced session.
GetSessionV2PrivateKey(issuer user.ID, subject []sessionv2.Target) (ecdsa.PrivateKey, error)
GetSessionV2PrivateKey(subject []sessionv2.Target) (ecdsa.PrivateKey, error)
}

// Storage groups ops of the node's storage required to serve NeoFS API Object
Expand Down Expand Up @@ -895,7 +894,7 @@ func convertHashPrm(signer ecdsa.PrivateKey, ss sessions, req *protoobject.GetRa
}

if tokV2 := cp.SessionTokenV2(); tokV2 != nil {
signerKey, err := ss.GetSessionV2PrivateKey(tokV2.Issuer(), tokV2.Subjects())
signerKey, err := ss.GetSessionV2PrivateKey(tokV2.Subjects())
if err != nil {
if !errors.Is(err, apistatus.ErrSessionTokenNotFound) {
return getsvc.RangeHashPrm{}, fmt.Errorf("fetching session v2 key: %w", err)
Expand All @@ -905,7 +904,11 @@ func convertHashPrm(signer ecdsa.PrivateKey, ss sessions, req *protoobject.GetRa
}
p.WithCachedSignerKey(&signerKey)
} else if tok := cp.SessionToken(); tok != nil {
signerKey, err := ss.GetSessionPrivateKey(tok.Issuer(), tok.ID())
authUser, err := tok.AuthUser()
if err != nil {
return getsvc.RangeHashPrm{}, fmt.Errorf("getting auth user from token: %w", err)
}
signerKey, err := ss.GetSessionPrivateKey(authUser)
if err != nil {
if !errors.Is(err, apistatus.ErrSessionTokenNotFound) {
return getsvc.RangeHashPrm{}, fmt.Errorf("fetching session key: %w", err)
Expand Down
11 changes: 5 additions & 6 deletions pkg/services/object/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"testing"
"time"

"github.com/google/uuid"
"github.com/nspcc-dev/neo-go/pkg/core/block"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
Expand Down Expand Up @@ -112,11 +111,11 @@ func (noCallTestStorage) SearchObjects(cid.ID, []objectcore.SearchFilter, []stri
func (noCallTestStorage) VerifyAndStoreObjectLocally(object.Object) error {
panic("must not be called")
}
func (noCallTestStorage) GetSessionPrivateKey(user.ID, uuid.UUID) (ecdsa.PrivateKey, error) {
func (noCallTestStorage) GetSessionPrivateKey(user.ID) (ecdsa.PrivateKey, error) {
panic("implement me")
}

func (s noCallTestStorage) GetSessionV2PrivateKey(user.ID, []sessionv2.Target) (ecdsa.PrivateKey, error) {
func (s noCallTestStorage) GetSessionV2PrivateKey([]sessionv2.Target) (ecdsa.PrivateKey, error) {
panic("implement me")
}

Expand Down Expand Up @@ -284,7 +283,7 @@ func (x *testStorage) VerifyAndStoreObjectLocally(obj object.Object) error {
return x.storeErr
}

func (x *testStorage) GetSessionPrivateKey(user.ID, uuid.UUID) (ecdsa.PrivateKey, error) {
func (x *testStorage) GetSessionPrivateKey(user.ID) (ecdsa.PrivateKey, error) {
return ecdsa.PrivateKey{}, apistatus.ErrSessionTokenNotFound
}

Expand Down Expand Up @@ -634,10 +633,10 @@ func (nopFSChain) LocalNodeUnderMaintenance() bool { return false }
type nopStorage struct{}

func (nopStorage) VerifyAndStoreObjectLocally(object.Object) error { return nil }
func (nopStorage) GetSessionPrivateKey(user.ID, uuid.UUID) (ecdsa.PrivateKey, error) {
func (nopStorage) GetSessionPrivateKey(user.ID) (ecdsa.PrivateKey, error) {
return ecdsa.PrivateKey{}, apistatus.ErrSessionTokenNotFound
}
func (s nopStorage) GetSessionV2PrivateKey(user.ID, []sessionv2.Target) (ecdsa.PrivateKey, error) {
func (s nopStorage) GetSessionV2PrivateKey([]sessionv2.Target) (ecdsa.PrivateKey, error) {
return ecdsa.PrivateKey{}, apistatus.ErrSessionTokenNotFound
}
func (nopStorage) SearchObjects(cid.ID, []objectcore.SearchFilter, []string, *objectcore.SearchCursor, uint16) ([]client.SearchResultItem, []byte, error) {
Expand Down
Loading
Loading