[#57] services/object: Sign requests with session key

Use key storage in object services in order to sign requests with private
session key within user session.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2020-09-29 19:44:59 +03:00 committed by Alex Vanin
parent 68178b8d74
commit 88459963fb
15 changed files with 89 additions and 65 deletions

View file

@ -115,8 +115,8 @@ loop:
} }
} else { } else {
header = &remoteHeader{ header = &remoteHeader{
key: h.key, keyStorage: h.keyStorage,
node: addr, node: addr,
} }
} }

View file

@ -2,24 +2,29 @@ package headsvc
import ( import (
"context" "context"
"crypto/ecdsa"
"github.com/nspcc-dev/neofs-api-go/pkg/client" "github.com/nspcc-dev/neofs-api-go/pkg/client"
"github.com/nspcc-dev/neofs-node/pkg/core/object" "github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/nspcc-dev/neofs-node/pkg/network" "github.com/nspcc-dev/neofs-node/pkg/network"
"github.com/nspcc-dev/neofs-node/pkg/services/object/util"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
type remoteHeader struct { type remoteHeader struct {
key *ecdsa.PrivateKey keyStorage *util.KeyStorage
node *network.Address node *network.Address
} }
func (h *remoteHeader) head(ctx context.Context, prm *Prm, handler func(*object.Object)) error { func (h *remoteHeader) head(ctx context.Context, prm *Prm, handler func(*object.Object)) error {
key, err := h.keyStorage.GetKey(prm.common.SessionToken())
if err != nil {
return errors.Wrapf(err, "(%T) could not receive private key", h)
}
addr := h.node.NetAddr() addr := h.node.NetAddr()
c, err := client.New(h.key, c, err := client.New(key,
client.WithAddress(addr), client.WithAddress(addr),
) )
if err != nil { if err != nil {
@ -35,6 +40,7 @@ func (h *remoteHeader) head(ctx context.Context, prm *Prm, handler func(*object.
hdr, err := c.GetObjectHeader(ctx, p, hdr, err := c.GetObjectHeader(ctx, p,
client.WithTTL(1), // FIXME: use constant client.WithTTL(1), // FIXME: use constant
client.WithSession(prm.common.SessionToken()),
) )
if err != nil { if err != nil {
return errors.Wrapf(err, "(%T) could not head object in %s", h, addr) return errors.Wrapf(err, "(%T) could not head object in %s", h, addr)

View file

@ -2,7 +2,6 @@ package headsvc
import ( import (
"context" "context"
"crypto/ecdsa"
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object" objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
"github.com/nspcc-dev/neofs-node/pkg/core/container" "github.com/nspcc-dev/neofs-node/pkg/core/container"
@ -10,6 +9,7 @@ import (
"github.com/nspcc-dev/neofs-node/pkg/core/object" "github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/localstore" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/localstore"
"github.com/nspcc-dev/neofs-node/pkg/network" "github.com/nspcc-dev/neofs-node/pkg/network"
objutil "github.com/nspcc-dev/neofs-node/pkg/services/object/util"
"github.com/nspcc-dev/neofs-node/pkg/util" "github.com/nspcc-dev/neofs-node/pkg/util"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -25,7 +25,7 @@ type Service struct {
type Option func(*cfg) type Option func(*cfg)
type cfg struct { type cfg struct {
key *ecdsa.PrivateKey keyStorage *objutil.KeyStorage
localStore *localstore.Storage localStore *localstore.Storage
@ -92,9 +92,9 @@ func (s *Service) Head(ctx context.Context, prm *Prm) (*Response, error) {
}, nil }, nil
} }
func WithKey(v *ecdsa.PrivateKey) Option { func WithKeyStorage(v *objutil.KeyStorage) Option {
return func(c *cfg) { return func(c *cfg) {
c.key = v c.keyStorage = v
} }
} }

View file

@ -2,11 +2,12 @@ package putsvc
import ( import (
"context" "context"
"crypto/ecdsa"
"github.com/nspcc-dev/neofs-api-go/pkg/client" "github.com/nspcc-dev/neofs-api-go/pkg/client"
"github.com/nspcc-dev/neofs-api-go/pkg/token"
"github.com/nspcc-dev/neofs-node/pkg/core/object" "github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/nspcc-dev/neofs-node/pkg/network" "github.com/nspcc-dev/neofs-node/pkg/network"
"github.com/nspcc-dev/neofs-node/pkg/services/object/util"
"github.com/nspcc-dev/neofs-node/pkg/services/object_manager/transformer" "github.com/nspcc-dev/neofs-node/pkg/services/object_manager/transformer"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -16,7 +17,9 @@ type remoteTarget struct {
ctx context.Context ctx context.Context
key *ecdsa.PrivateKey keyStorage *util.KeyStorage
token *token.SessionToken
addr *network.Address addr *network.Address
@ -30,9 +33,14 @@ func (t *remoteTarget) WriteHeader(obj *object.RawObject) error {
} }
func (t *remoteTarget) Close() (*transformer.AccessIdentifiers, error) { func (t *remoteTarget) Close() (*transformer.AccessIdentifiers, error) {
key, err := t.keyStorage.GetKey(t.token)
if err != nil {
return nil, errors.Wrapf(err, "(%T) could not receive private key", t)
}
addr := t.addr.NetAddr() addr := t.addr.NetAddr()
c, err := client.New(t.key, c, err := client.New(key,
client.WithAddress(addr), client.WithAddress(addr),
) )
if err != nil { if err != nil {

View file

@ -2,14 +2,13 @@ package putsvc
import ( import (
"context" "context"
"crypto/ecdsa"
"github.com/nspcc-dev/neofs-node/pkg/core/container" "github.com/nspcc-dev/neofs-node/pkg/core/container"
"github.com/nspcc-dev/neofs-node/pkg/core/netmap" "github.com/nspcc-dev/neofs-node/pkg/core/netmap"
"github.com/nspcc-dev/neofs-node/pkg/core/object" "github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/localstore" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/localstore"
"github.com/nspcc-dev/neofs-node/pkg/network" "github.com/nspcc-dev/neofs-node/pkg/network"
"github.com/nspcc-dev/neofs-node/pkg/services/session/storage" objutil "github.com/nspcc-dev/neofs-node/pkg/services/object/util"
"github.com/nspcc-dev/neofs-node/pkg/util" "github.com/nspcc-dev/neofs-node/pkg/util"
) )
@ -24,12 +23,10 @@ type Service struct {
type Option func(*cfg) type Option func(*cfg)
type cfg struct { type cfg struct {
key *ecdsa.PrivateKey keyStorage *objutil.KeyStorage
maxSizeSrc MaxSizeSource maxSizeSrc MaxSizeSource
tokenStore *storage.TokenStore
localStore *localstore.Storage localStore *localstore.Storage
cnrSrc container.Source cnrSrc container.Source
@ -69,9 +66,9 @@ func (p *Service) Put(ctx context.Context) (*Streamer, error) {
}, nil }, nil
} }
func WithKey(v *ecdsa.PrivateKey) Option { func WithKeyStorage(v *objutil.KeyStorage) Option {
return func(c *cfg) { return func(c *cfg) {
c.key = v c.keyStorage = v
} }
} }
@ -81,12 +78,6 @@ func WithMaxSizeSource(v MaxSizeSource) Option {
} }
} }
func WithTokenStorage(v *storage.TokenStore) Option {
return func(c *cfg) {
c.tokenStore = v
}
}
func WithLocalStorage(v *localstore.Storage) Option { func WithLocalStorage(v *localstore.Storage) Option {
return func(c *cfg) { return func(c *cfg) {
c.localStore = v c.localStore = v

View file

@ -23,8 +23,6 @@ var errNotInit = errors.New("stream not initialized")
var errInitRecall = errors.New("init recall") var errInitRecall = errors.New("init recall")
var errPrivateTokenNotFound = errors.New("private token not found")
func (p *Streamer) Init(prm *PutInitPrm) error { func (p *Streamer) Init(prm *PutInitPrm) error {
// initialize destination target // initialize destination target
if err := p.initTarget(prm); err != nil { if err := p.initTarget(prm); err != nil {
@ -63,15 +61,15 @@ func (p *Streamer) initTarget(prm *PutInitPrm) error {
// prepare trusted-Put object target // prepare trusted-Put object target
// get private token from local storage // get private token from local storage
pToken := p.tokenStore.Get(sToken.OwnerID(), sToken.ID()) sessionKey, err := p.keyStorage.GetKey(sToken)
if pToken == nil { if err != nil {
return errPrivateTokenNotFound return errors.Wrapf(err, "(%T) could not receive session key", p)
} }
p.target = transformer.NewPayloadSizeLimiter( p.target = transformer.NewPayloadSizeLimiter(
p.maxSizeSrc.MaxObjectSize(), p.maxSizeSrc.MaxObjectSize(),
func() transformer.ObjectTarget { func() transformer.ObjectTarget {
return transformer.NewFormatTarget(pToken.SessionKey(), p.newCommonTarget(prm), sToken) return transformer.NewFormatTarget(sessionKey, p.newCommonTarget(prm), sToken)
}, },
) )
@ -133,9 +131,10 @@ func (p *Streamer) newCommonTarget(prm *PutInitPrm) transformer.ObjectTarget {
} }
} else { } else {
return &remoteTarget{ return &remoteTarget{
ctx: p.ctx, ctx: p.ctx,
key: p.key, keyStorage: p.keyStorage,
addr: addr, token: prm.common.SessionToken(),
addr: addr,
} }
} }
}, },

View file

@ -2,31 +2,39 @@ package rangesvc
import ( import (
"context" "context"
"crypto/ecdsa"
"io" "io"
"github.com/nspcc-dev/neofs-api-go/pkg/client" "github.com/nspcc-dev/neofs-api-go/pkg/client"
"github.com/nspcc-dev/neofs-api-go/pkg/object" "github.com/nspcc-dev/neofs-api-go/pkg/object"
"github.com/nspcc-dev/neofs-api-go/pkg/token"
"github.com/nspcc-dev/neofs-node/pkg/network" "github.com/nspcc-dev/neofs-node/pkg/network"
"github.com/nspcc-dev/neofs-node/pkg/services/object/util"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
type remoteRangeWriter struct { type remoteRangeWriter struct {
ctx context.Context ctx context.Context
key *ecdsa.PrivateKey keyStorage *util.KeyStorage
node *network.Address node *network.Address
token *token.SessionToken
addr *object.Address addr *object.Address
rng *object.Range rng *object.Range
} }
func (r *remoteRangeWriter) WriteTo(w io.Writer) (int64, error) { func (r *remoteRangeWriter) WriteTo(w io.Writer) (int64, error) {
key, err := r.keyStorage.GetKey(r.token)
if err != nil {
return 0, errors.Wrapf(err, "(%T) could not receive private key", r)
}
addr := r.node.NetAddr() addr := r.node.NetAddr()
c, err := client.New(r.key, c, err := client.New(key,
client.WithAddress(addr), client.WithAddress(addr),
) )
if err != nil { if err != nil {
@ -38,6 +46,7 @@ func (r *remoteRangeWriter) WriteTo(w io.Writer) (int64, error) {
WithRange(r.rng). WithRange(r.rng).
WithAddress(r.addr), WithAddress(r.addr),
client.WithTTL(1), // FIXME: use constant client.WithTTL(1), // FIXME: use constant
client.WithSession(r.token),
) )
if err != nil { if err != nil {
return 0, errors.Wrapf(err, "(%T) could not read object payload range from %s", r, addr) return 0, errors.Wrapf(err, "(%T) could not read object payload range from %s", r, addr)

View file

@ -2,7 +2,6 @@ package rangesvc
import ( import (
"context" "context"
"crypto/ecdsa"
"sync" "sync"
"github.com/nspcc-dev/neofs-api-go/pkg/object" "github.com/nspcc-dev/neofs-api-go/pkg/object"
@ -23,7 +22,7 @@ type Service struct {
type Option func(*cfg) type Option func(*cfg)
type cfg struct { type cfg struct {
key *ecdsa.PrivateKey keyStorage *objutil.KeyStorage
localStore *localstore.Storage localStore *localstore.Storage
@ -124,9 +123,9 @@ func (s *Service) fillTraverser(ctx context.Context, prm *Prm, traverser *objuti
} }
} }
func WithKey(v *ecdsa.PrivateKey) Option { func WithKeyStorage(v *objutil.KeyStorage) Option {
return func(c *cfg) { return func(c *cfg) {
c.key = v c.keyStorage = v
} }
} }

View file

@ -178,11 +178,12 @@ loop:
} }
} else { } else {
rngWriter = &remoteRangeWriter{ rngWriter = &remoteRangeWriter{
ctx: p.ctx, ctx: p.ctx,
key: p.key, keyStorage: p.keyStorage,
node: addr, node: addr,
addr: objAddr, token: p.prm.common.SessionToken(),
rng: nextRange, addr: objAddr,
rng: nextRange,
} }
} }

View file

@ -112,8 +112,8 @@ loop:
} }
} else { } else {
hasher = &remoteHasher{ hasher = &remoteHasher{
key: h.key, keyStorage: h.keyStorage,
node: addr, node: addr,
} }
} }

View file

@ -2,25 +2,30 @@ package rangehashsvc
import ( import (
"context" "context"
"crypto/ecdsa"
"fmt" "fmt"
"github.com/nspcc-dev/neofs-api-go/pkg" "github.com/nspcc-dev/neofs-api-go/pkg"
"github.com/nspcc-dev/neofs-api-go/pkg/client" "github.com/nspcc-dev/neofs-api-go/pkg/client"
"github.com/nspcc-dev/neofs-node/pkg/network" "github.com/nspcc-dev/neofs-node/pkg/network"
"github.com/nspcc-dev/neofs-node/pkg/services/object/util"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
type remoteHasher struct { type remoteHasher struct {
key *ecdsa.PrivateKey keyStorage *util.KeyStorage
node *network.Address node *network.Address
} }
func (h *remoteHasher) hashRange(ctx context.Context, prm *Prm, handler func([][]byte)) error { func (h *remoteHasher) hashRange(ctx context.Context, prm *Prm, handler func([][]byte)) error {
key, err := h.keyStorage.GetKey(prm.common.SessionToken())
if err != nil {
return errors.Wrapf(err, "(%T) could not receive private key", h)
}
addr := h.node.NetAddr() addr := h.node.NetAddr()
c, err := client.New(h.key, c, err := client.New(key,
client.WithAddress(addr), client.WithAddress(addr),
) )
if err != nil { if err != nil {
@ -36,6 +41,7 @@ func (h *remoteHasher) hashRange(ctx context.Context, prm *Prm, handler func([][
opts := []client.CallOption{ opts := []client.CallOption{
client.WithTTL(1), // FIXME: use constant client.WithTTL(1), // FIXME: use constant
client.WithSession(prm.common.SessionToken()),
} }
switch prm.typ { switch prm.typ {

View file

@ -2,7 +2,6 @@ package rangehashsvc
import ( import (
"context" "context"
"crypto/ecdsa"
"crypto/sha256" "crypto/sha256"
"fmt" "fmt"
"io" "io"
@ -27,7 +26,7 @@ type Service struct {
type Option func(*cfg) type Option func(*cfg)
type cfg struct { type cfg struct {
key *ecdsa.PrivateKey keyStorage *objutil.KeyStorage
localStore *localstore.Storage localStore *localstore.Storage
@ -218,9 +217,9 @@ func (s *Service) getHashes(ctx context.Context, prm *Prm, traverser *objutil.Ra
return resp, nil return resp, nil
} }
func WithKey(v *ecdsa.PrivateKey) Option { func WithKeyStorage(v *objutil.KeyStorage) Option {
return func(c *cfg) { return func(c *cfg) {
c.key = v c.keyStorage = v
} }
} }

View file

@ -2,26 +2,31 @@ package searchsvc
import ( import (
"context" "context"
"crypto/ecdsa"
"github.com/nspcc-dev/neofs-api-go/pkg/client" "github.com/nspcc-dev/neofs-api-go/pkg/client"
"github.com/nspcc-dev/neofs-api-go/pkg/object" "github.com/nspcc-dev/neofs-api-go/pkg/object"
"github.com/nspcc-dev/neofs-node/pkg/network" "github.com/nspcc-dev/neofs-node/pkg/network"
"github.com/nspcc-dev/neofs-node/pkg/services/object/util"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
type remoteStream struct { type remoteStream struct {
prm *Prm prm *Prm
key *ecdsa.PrivateKey keyStorage *util.KeyStorage
addr *network.Address addr *network.Address
} }
func (s *remoteStream) stream(ctx context.Context, ch chan<- []*object.ID) error { func (s *remoteStream) stream(ctx context.Context, ch chan<- []*object.ID) error {
key, err := s.keyStorage.GetKey(s.prm.common.SessionToken())
if err != nil {
return errors.Wrapf(err, "(%T) could not receive private key", s)
}
addr := s.addr.NetAddr() addr := s.addr.NetAddr()
c, err := client.New(s.key, c, err := client.New(key,
client.WithAddress(addr), client.WithAddress(addr),
) )
if err != nil { if err != nil {
@ -33,6 +38,7 @@ func (s *remoteStream) stream(ctx context.Context, ch chan<- []*object.ID) error
WithContainerID(s.prm.cid). WithContainerID(s.prm.cid).
WithSearchFilters(s.prm.query.ToSearchFilters()), WithSearchFilters(s.prm.query.ToSearchFilters()),
client.WithTTL(1), // FIXME: use constant client.WithTTL(1), // FIXME: use constant
client.WithSession(s.prm.common.SessionToken()),
) )
if err != nil { if err != nil {
return errors.Wrapf(err, "(%T) could not search objects in %s", s, addr) return errors.Wrapf(err, "(%T) could not search objects in %s", s, addr)

View file

@ -2,7 +2,6 @@ package searchsvc
import ( import (
"context" "context"
"crypto/ecdsa"
"io" "io"
"sync" "sync"
@ -12,6 +11,7 @@ import (
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/localstore" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/localstore"
"github.com/nspcc-dev/neofs-node/pkg/network" "github.com/nspcc-dev/neofs-node/pkg/network"
"github.com/nspcc-dev/neofs-node/pkg/services/object/search/query/v1" "github.com/nspcc-dev/neofs-node/pkg/services/object/search/query/v1"
objutil "github.com/nspcc-dev/neofs-node/pkg/services/object/util"
"github.com/nspcc-dev/neofs-node/pkg/util" "github.com/nspcc-dev/neofs-node/pkg/util"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -23,7 +23,7 @@ type Service struct {
type Option func(*cfg) type Option func(*cfg)
type cfg struct { type cfg struct {
key *ecdsa.PrivateKey keyStorage *objutil.KeyStorage
localStore *localstore.Storage localStore *localstore.Storage
@ -104,9 +104,9 @@ func readFullStream(s *Streamer, cap int) ([]*object.ID, error) {
return res, nil return res, nil
} }
func WithKey(v *ecdsa.PrivateKey) Option { func WithKeyStorage(v *objutil.KeyStorage) Option {
return func(c *cfg) { return func(c *cfg) {
c.key = v c.keyStorage = v
} }
} }

View file

@ -160,9 +160,9 @@ loop:
} }
} else { } else {
streamer = &remoteStream{ streamer = &remoteStream{
prm: prm, prm: prm,
key: p.key, keyStorage: p.keyStorage,
addr: addr, addr: addr,
} }
} }