[#943] service/object: Refactor private key fetching during execution

`CommonPrm` structure has private key for remote operations.
It obtained in the beginning of request processing. However,
not every operation triggers remote calls. Therefore, key
might not be used. It is important to avoid early key fetching
because `TokenStore` now returns error if session token does not
exist. This is valid case when container nodes receive request with
session token (for ACL pass) and they should process request locally.

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2021-10-26 15:07:28 +03:00 committed by Alex Vanin
parent 2fbdcbdee1
commit c30aa20b04
7 changed files with 57 additions and 58 deletions

View file

@ -2,7 +2,6 @@ package deletesvc
import ( import (
"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/session"
objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object" objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object"
deletesvc "github.com/nspcc-dev/neofs-node/pkg/services/object/delete" deletesvc "github.com/nspcc-dev/neofs-node/pkg/services/object/delete"
"github.com/nspcc-dev/neofs-node/pkg/services/object/util" "github.com/nspcc-dev/neofs-node/pkg/services/object/util"
@ -13,13 +12,6 @@ type tombstoneBodyWriter struct {
} }
func (s *Service) toPrm(req *objectV2.DeleteRequest, respBody *objectV2.DeleteResponseBody) (*deletesvc.Prm, error) { func (s *Service) toPrm(req *objectV2.DeleteRequest, respBody *objectV2.DeleteResponseBody) (*deletesvc.Prm, error) {
meta := req.GetMetaHeader()
key, err := s.keyStorage.GetKey(session.NewTokenFromV2(meta.GetSessionToken()))
if err != nil {
return nil, err
}
commonPrm, err := util.CommonPrmFromV2(req) commonPrm, err := util.CommonPrmFromV2(req)
if err != nil { if err != nil {
return nil, err return nil, err
@ -27,7 +19,7 @@ func (s *Service) toPrm(req *objectV2.DeleteRequest, respBody *objectV2.DeleteRe
p := new(deletesvc.Prm) p := new(deletesvc.Prm)
p.SetCommonParameters(commonPrm. p.SetCommonParameters(commonPrm.
WithPrivateKey(key), WithKeyStorage(s.keyStorage),
) )
body := req.GetBody() body := req.GetBody()

View file

@ -104,14 +104,19 @@ func (exec execCtx) isChild(obj *object.Object) bool {
return par != nil && equalAddresses(exec.address(), par.Address()) return par != nil && equalAddresses(exec.address(), par.Address())
} }
func (exec execCtx) key() *ecdsa.PrivateKey { func (exec execCtx) key() (*ecdsa.PrivateKey, error) {
return exec.prm.common.PrivateKey() return exec.prm.common.KeyStorage().GetKey(exec.prm.common.SessionToken())
} }
func (exec execCtx) callOptions() []client.CallOption { func (exec execCtx) callOptions() ([]client.CallOption, error) {
key, err := exec.key()
if err != nil {
return nil, err
}
return exec.prm.common.RemoteCallOptions( return exec.prm.common.RemoteCallOptions(
util.WithNetmapEpoch(exec.curProcEpoch), util.WithNetmapEpoch(exec.curProcEpoch),
util.WithKey(exec.key())) util.WithKey(key)), nil
} }
func (exec execCtx) remotePrm() *client.GetObjectParams { func (exec execCtx) remotePrm() *client.GetObjectParams {

View file

@ -88,12 +88,17 @@ func (c *clientWrapper) getObject(exec *execCtx, info coreclient.NodeInfo) (*obj
return exec.prm.forwarder(info, c.client) return exec.prm.forwarder(info, c.client)
} }
opts, err := exec.callOptions()
if err != nil {
return nil, err
}
if exec.headOnly() { if exec.headOnly() {
return c.client.GetObjectHeader(exec.context(), return c.client.GetObjectHeader(exec.context(),
new(client.ObjectHeaderParams). new(client.ObjectHeaderParams).
WithAddress(exec.address()). WithAddress(exec.address()).
WithRawFlag(exec.isRaw()), WithRawFlag(exec.isRaw()),
exec.callOptions()..., opts...,
) )
} }
// we don't specify payload writer because we accumulate // we don't specify payload writer because we accumulate
@ -104,7 +109,7 @@ func (c *clientWrapper) getObject(exec *execCtx, info coreclient.NodeInfo) (*obj
WithAddress(exec.address()). WithAddress(exec.address()).
WithRange(rng). WithRange(rng).
WithRaw(exec.isRaw()), WithRaw(exec.isRaw()),
exec.callOptions()..., opts...,
) )
if err != nil { if err != nil {
return nil, err return nil, err
@ -115,7 +120,7 @@ func (c *clientWrapper) getObject(exec *execCtx, info coreclient.NodeInfo) (*obj
return c.client.GetObject(exec.context(), return c.client.GetObject(exec.context(),
exec.remotePrm(), exec.remotePrm(),
exec.callOptions()..., opts...,
) )
} }

View file

@ -10,7 +10,6 @@ import (
"sync" "sync"
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object" objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
sessionsdk "github.com/nspcc-dev/neofs-api-go/pkg/session"
rpcclient "github.com/nspcc-dev/neofs-api-go/rpc/client" rpcclient "github.com/nspcc-dev/neofs-api-go/rpc/client"
signature2 "github.com/nspcc-dev/neofs-api-go/util/signature" signature2 "github.com/nspcc-dev/neofs-api-go/util/signature"
objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object" objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object"
@ -33,11 +32,6 @@ var errWrongMessageSeq = errors.New("incorrect message sequence")
func (s *Service) toPrm(req *objectV2.GetRequest, stream objectSvc.GetObjectStream) (*getsvc.Prm, error) { func (s *Service) toPrm(req *objectV2.GetRequest, stream objectSvc.GetObjectStream) (*getsvc.Prm, error) {
meta := req.GetMetaHeader() meta := req.GetMetaHeader()
key, err := s.keyStorage.GetKey(sessionsdk.NewTokenFromV2(meta.GetSessionToken()))
if err != nil {
return nil, err
}
commonPrm, err := util.CommonPrmFromV2(req) commonPrm, err := util.CommonPrmFromV2(req)
if err != nil { if err != nil {
return nil, err return nil, err
@ -45,7 +39,7 @@ func (s *Service) toPrm(req *objectV2.GetRequest, stream objectSvc.GetObjectStre
p := new(getsvc.Prm) p := new(getsvc.Prm)
p.SetCommonParameters(commonPrm. p.SetCommonParameters(commonPrm.
WithPrivateKey(key), WithKeyStorage(s.keyStorage),
) )
body := req.GetBody() body := req.GetBody()
@ -59,8 +53,14 @@ func (s *Service) toPrm(req *objectV2.GetRequest, stream objectSvc.GetObjectStre
p.SetRequestForwarder(groupAddressRequestForwarder(func(addr network.Address, c client.Client, pubkey []byte) (*objectSDK.Object, error) { p.SetRequestForwarder(groupAddressRequestForwarder(func(addr network.Address, c client.Client, pubkey []byte) (*objectSDK.Object, error) {
var err error var err error
key, err := s.keyStorage.GetKey(nil)
if err != nil {
return nil, err
}
// once compose and resign forwarding request // once compose and resign forwarding request
onceResign.Do(func() { onceResign.Do(func() {
// compose meta header of the local server // compose meta header of the local server
metaHdr := new(session.RequestMetaHeader) metaHdr := new(session.RequestMetaHeader)
metaHdr.SetTTL(meta.GetTTL() - 1) metaHdr.SetTTL(meta.GetTTL() - 1)
@ -159,11 +159,6 @@ func (s *Service) toPrm(req *objectV2.GetRequest, stream objectSvc.GetObjectStre
func (s *Service) toRangePrm(req *objectV2.GetRangeRequest, stream objectSvc.GetObjectRangeStream) (*getsvc.RangePrm, error) { func (s *Service) toRangePrm(req *objectV2.GetRangeRequest, stream objectSvc.GetObjectRangeStream) (*getsvc.RangePrm, error) {
meta := req.GetMetaHeader() meta := req.GetMetaHeader()
key, err := s.keyStorage.GetKey(sessionsdk.NewTokenFromV2(meta.GetSessionToken()))
if err != nil {
return nil, err
}
commonPrm, err := util.CommonPrmFromV2(req) commonPrm, err := util.CommonPrmFromV2(req)
if err != nil { if err != nil {
return nil, err return nil, err
@ -171,7 +166,7 @@ func (s *Service) toRangePrm(req *objectV2.GetRangeRequest, stream objectSvc.Get
p := new(getsvc.RangePrm) p := new(getsvc.RangePrm)
p.SetCommonParameters(commonPrm. p.SetCommonParameters(commonPrm.
WithPrivateKey(key), WithKeyStorage(s.keyStorage),
) )
body := req.GetBody() body := req.GetBody()
@ -183,6 +178,11 @@ func (s *Service) toRangePrm(req *objectV2.GetRangeRequest, stream objectSvc.Get
if !commonPrm.LocalOnly() { if !commonPrm.LocalOnly() {
var onceResign sync.Once var onceResign sync.Once
key, err := s.keyStorage.GetKey(nil)
if err != nil {
return nil, err
}
p.SetRequestForwarder(groupAddressRequestForwarder(func(addr network.Address, c client.Client, pubkey []byte) (*objectSDK.Object, error) { p.SetRequestForwarder(groupAddressRequestForwarder(func(addr network.Address, c client.Client, pubkey []byte) (*objectSDK.Object, error) {
var err error var err error
@ -260,13 +260,6 @@ func (s *Service) toRangePrm(req *objectV2.GetRangeRequest, stream objectSvc.Get
} }
func (s *Service) toHashRangePrm(req *objectV2.GetRangeHashRequest) (*getsvc.RangeHashPrm, error) { func (s *Service) toHashRangePrm(req *objectV2.GetRangeHashRequest) (*getsvc.RangeHashPrm, error) {
meta := req.GetMetaHeader()
key, err := s.keyStorage.GetKey(sessionsdk.NewTokenFromV2(meta.GetSessionToken()))
if err != nil {
return nil, err
}
commonPrm, err := util.CommonPrmFromV2(req) commonPrm, err := util.CommonPrmFromV2(req)
if err != nil { if err != nil {
return nil, err return nil, err
@ -274,7 +267,7 @@ func (s *Service) toHashRangePrm(req *objectV2.GetRangeHashRequest) (*getsvc.Ran
p := new(getsvc.RangeHashPrm) p := new(getsvc.RangeHashPrm)
p.SetCommonParameters(commonPrm. p.SetCommonParameters(commonPrm.
WithPrivateKey(key), WithKeyStorage(s.keyStorage),
) )
body := req.GetBody() body := req.GetBody()
@ -325,11 +318,6 @@ func (w *headResponseWriter) WriteHeader(hdr *object.Object) error {
func (s *Service) toHeadPrm(ctx context.Context, req *objectV2.HeadRequest, resp *objectV2.HeadResponse) (*getsvc.HeadPrm, error) { func (s *Service) toHeadPrm(ctx context.Context, req *objectV2.HeadRequest, resp *objectV2.HeadResponse) (*getsvc.HeadPrm, error) {
meta := req.GetMetaHeader() meta := req.GetMetaHeader()
key, err := s.keyStorage.GetKey(sessionsdk.NewTokenFromV2(meta.GetSessionToken()))
if err != nil {
return nil, err
}
commonPrm, err := util.CommonPrmFromV2(req) commonPrm, err := util.CommonPrmFromV2(req)
if err != nil { if err != nil {
return nil, err return nil, err
@ -337,7 +325,7 @@ func (s *Service) toHeadPrm(ctx context.Context, req *objectV2.HeadRequest, resp
p := new(getsvc.HeadPrm) p := new(getsvc.HeadPrm)
p.SetCommonParameters(commonPrm. p.SetCommonParameters(commonPrm.
WithPrivateKey(key), WithKeyStorage(s.keyStorage),
) )
body := req.GetBody() body := req.GetBody()
@ -354,6 +342,11 @@ func (s *Service) toHeadPrm(ctx context.Context, req *objectV2.HeadRequest, resp
p.SetRequestForwarder(groupAddressRequestForwarder(func(addr network.Address, c client.Client, pubkey []byte) (*objectSDK.Object, error) { p.SetRequestForwarder(groupAddressRequestForwarder(func(addr network.Address, c client.Client, pubkey []byte) (*objectSDK.Object, error) {
var err error var err error
key, err := s.keyStorage.GetKey(nil)
if err != nil {
return nil, err
}
// once compose and resign forwarding request // once compose and resign forwarding request
onceResign.Do(func() { onceResign.Do(func() {
// compose meta header of the local server // compose meta header of the local server

View file

@ -83,11 +83,16 @@ func (c *clientWrapper) searchObjects(exec *execCtx, info client.NodeInfo) ([]*o
return exec.prm.forwarder(info, c.client) return exec.prm.forwarder(info, c.client)
} }
key, err := exec.prm.common.KeyStorage().GetKey(exec.prm.common.SessionToken())
if err != nil {
return nil, err
}
return c.client.SearchObject(exec.context(), return c.client.SearchObject(exec.context(),
&exec.prm.SearchObjectParams, &exec.prm.SearchObjectParams,
exec.prm.common.RemoteCallOptions( exec.prm.common.RemoteCallOptions(
util.WithNetmapEpoch(exec.curProcEpoch), util.WithNetmapEpoch(exec.curProcEpoch),
util.WithKey(exec.prm.common.PrivateKey()), util.WithKey(key),
)...) )...)
} }

View file

@ -8,7 +8,6 @@ import (
cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id"
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object" objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
sessionsdk "github.com/nspcc-dev/neofs-api-go/pkg/session"
rpcclient "github.com/nspcc-dev/neofs-api-go/rpc/client" rpcclient "github.com/nspcc-dev/neofs-api-go/rpc/client"
objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object" objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object"
"github.com/nspcc-dev/neofs-api-go/v2/rpc" "github.com/nspcc-dev/neofs-api-go/v2/rpc"
@ -25,11 +24,6 @@ import (
func (s *Service) toPrm(req *objectV2.SearchRequest, stream objectSvc.SearchStream) (*searchsvc.Prm, error) { func (s *Service) toPrm(req *objectV2.SearchRequest, stream objectSvc.SearchStream) (*searchsvc.Prm, error) {
meta := req.GetMetaHeader() meta := req.GetMetaHeader()
key, err := s.keyStorage.GetKey(sessionsdk.NewTokenFromV2(meta.GetSessionToken()))
if err != nil {
return nil, err
}
commonPrm, err := util.CommonPrmFromV2(req) commonPrm, err := util.CommonPrmFromV2(req)
if err != nil { if err != nil {
return nil, err return nil, err
@ -37,7 +31,7 @@ func (s *Service) toPrm(req *objectV2.SearchRequest, stream objectSvc.SearchStre
p := new(searchsvc.Prm) p := new(searchsvc.Prm)
p.SetCommonParameters(commonPrm. p.SetCommonParameters(commonPrm.
WithPrivateKey(key), WithKeyStorage(s.keyStorage),
) )
p.SetWriter(&streamWriter{ p.SetWriter(&streamWriter{
@ -47,6 +41,11 @@ func (s *Service) toPrm(req *objectV2.SearchRequest, stream objectSvc.SearchStre
if !commonPrm.LocalOnly() { if !commonPrm.LocalOnly() {
var onceResign sync.Once var onceResign sync.Once
key, err := s.keyStorage.GetKey(nil)
if err != nil {
return nil, err
}
p.SetRequestForwarder(groupAddressRequestForwarder(func(addr network.Address, c client.Client, pubkey []byte) ([]*objectSDK.ID, error) { p.SetRequestForwarder(groupAddressRequestForwarder(func(addr network.Address, c client.Client, pubkey []byte) ([]*objectSDK.ID, error) {
var err error var err error

View file

@ -20,7 +20,7 @@ type CommonPrm struct {
bearer *token.BearerToken bearer *token.BearerToken
key *ecdsa.PrivateKey keyStor *KeyStorage
callOpts []client.CallOption callOpts []client.CallOption
} }
@ -63,19 +63,19 @@ func (p *CommonPrm) WithBearerToken(token *token.BearerToken) *CommonPrm {
return p return p
} }
// WithPrivateKey sets private key to use during execution. // WithKeyStorage sets private key storage to use during execution.
func (p *CommonPrm) WithPrivateKey(key *ecdsa.PrivateKey) *CommonPrm { func (p *CommonPrm) WithKeyStorage(stor *KeyStorage) *CommonPrm {
if p != nil { if p != nil {
p.key = key p.keyStor = stor
} }
return p return p
} }
// PrivateKey returns private key to use during execution. // KeyStorage returns private key storage to use during execution.
func (p *CommonPrm) PrivateKey() *ecdsa.PrivateKey { func (p *CommonPrm) KeyStorage() *KeyStorage {
if p != nil { if p != nil {
return p.key return p.keyStor
} }
return nil return nil