From c30aa20b044b951249421495d33df2b789c6189b Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Tue, 26 Oct 2021 15:07:28 +0300 Subject: [PATCH] [#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 --- pkg/services/object/delete/v2/util.go | 10 +----- pkg/services/object/get/exec.go | 13 +++++--- pkg/services/object/get/util.go | 11 +++++-- pkg/services/object/get/v2/util.go | 47 ++++++++++++--------------- pkg/services/object/search/util.go | 7 +++- pkg/services/object/search/v2/util.go | 13 ++++---- pkg/services/object/util/prm.go | 14 ++++---- 7 files changed, 57 insertions(+), 58 deletions(-) diff --git a/pkg/services/object/delete/v2/util.go b/pkg/services/object/delete/v2/util.go index a1411934..894c0b87 100644 --- a/pkg/services/object/delete/v2/util.go +++ b/pkg/services/object/delete/v2/util.go @@ -2,7 +2,6 @@ package deletesvc import ( "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" deletesvc "github.com/nspcc-dev/neofs-node/pkg/services/object/delete" "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) { - meta := req.GetMetaHeader() - - key, err := s.keyStorage.GetKey(session.NewTokenFromV2(meta.GetSessionToken())) - if err != nil { - return nil, err - } - commonPrm, err := util.CommonPrmFromV2(req) if err != nil { return nil, err @@ -27,7 +19,7 @@ func (s *Service) toPrm(req *objectV2.DeleteRequest, respBody *objectV2.DeleteRe p := new(deletesvc.Prm) p.SetCommonParameters(commonPrm. - WithPrivateKey(key), + WithKeyStorage(s.keyStorage), ) body := req.GetBody() diff --git a/pkg/services/object/get/exec.go b/pkg/services/object/get/exec.go index f63fb906..63c0a220 100644 --- a/pkg/services/object/get/exec.go +++ b/pkg/services/object/get/exec.go @@ -104,14 +104,19 @@ func (exec execCtx) isChild(obj *object.Object) bool { return par != nil && equalAddresses(exec.address(), par.Address()) } -func (exec execCtx) key() *ecdsa.PrivateKey { - return exec.prm.common.PrivateKey() +func (exec execCtx) key() (*ecdsa.PrivateKey, error) { + 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( util.WithNetmapEpoch(exec.curProcEpoch), - util.WithKey(exec.key())) + util.WithKey(key)), nil } func (exec execCtx) remotePrm() *client.GetObjectParams { diff --git a/pkg/services/object/get/util.go b/pkg/services/object/get/util.go index bb1ec14b..bc10f60b 100644 --- a/pkg/services/object/get/util.go +++ b/pkg/services/object/get/util.go @@ -88,12 +88,17 @@ func (c *clientWrapper) getObject(exec *execCtx, info coreclient.NodeInfo) (*obj return exec.prm.forwarder(info, c.client) } + opts, err := exec.callOptions() + if err != nil { + return nil, err + } + if exec.headOnly() { return c.client.GetObjectHeader(exec.context(), new(client.ObjectHeaderParams). WithAddress(exec.address()). WithRawFlag(exec.isRaw()), - exec.callOptions()..., + opts..., ) } // 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()). WithRange(rng). WithRaw(exec.isRaw()), - exec.callOptions()..., + opts..., ) if err != nil { return nil, err @@ -115,7 +120,7 @@ func (c *clientWrapper) getObject(exec *execCtx, info coreclient.NodeInfo) (*obj return c.client.GetObject(exec.context(), exec.remotePrm(), - exec.callOptions()..., + opts..., ) } diff --git a/pkg/services/object/get/v2/util.go b/pkg/services/object/get/v2/util.go index bc8ed26b..b80d3190 100644 --- a/pkg/services/object/get/v2/util.go +++ b/pkg/services/object/get/v2/util.go @@ -10,7 +10,6 @@ import ( "sync" 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" signature2 "github.com/nspcc-dev/neofs-api-go/util/signature" 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) { meta := req.GetMetaHeader() - key, err := s.keyStorage.GetKey(sessionsdk.NewTokenFromV2(meta.GetSessionToken())) - if err != nil { - return nil, err - } - commonPrm, err := util.CommonPrmFromV2(req) if err != nil { return nil, err @@ -45,7 +39,7 @@ func (s *Service) toPrm(req *objectV2.GetRequest, stream objectSvc.GetObjectStre p := new(getsvc.Prm) p.SetCommonParameters(commonPrm. - WithPrivateKey(key), + WithKeyStorage(s.keyStorage), ) 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) { var err error + key, err := s.keyStorage.GetKey(nil) + if err != nil { + return nil, err + } + // once compose and resign forwarding request onceResign.Do(func() { + // compose meta header of the local server metaHdr := new(session.RequestMetaHeader) 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) { meta := req.GetMetaHeader() - key, err := s.keyStorage.GetKey(sessionsdk.NewTokenFromV2(meta.GetSessionToken())) - if err != nil { - return nil, err - } - commonPrm, err := util.CommonPrmFromV2(req) if err != nil { return nil, err @@ -171,7 +166,7 @@ func (s *Service) toRangePrm(req *objectV2.GetRangeRequest, stream objectSvc.Get p := new(getsvc.RangePrm) p.SetCommonParameters(commonPrm. - WithPrivateKey(key), + WithKeyStorage(s.keyStorage), ) body := req.GetBody() @@ -183,6 +178,11 @@ func (s *Service) toRangePrm(req *objectV2.GetRangeRequest, stream objectSvc.Get if !commonPrm.LocalOnly() { 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) { 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) { - meta := req.GetMetaHeader() - - key, err := s.keyStorage.GetKey(sessionsdk.NewTokenFromV2(meta.GetSessionToken())) - if err != nil { - return nil, err - } - commonPrm, err := util.CommonPrmFromV2(req) if err != nil { return nil, err @@ -274,7 +267,7 @@ func (s *Service) toHashRangePrm(req *objectV2.GetRangeHashRequest) (*getsvc.Ran p := new(getsvc.RangeHashPrm) p.SetCommonParameters(commonPrm. - WithPrivateKey(key), + WithKeyStorage(s.keyStorage), ) 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) { meta := req.GetMetaHeader() - key, err := s.keyStorage.GetKey(sessionsdk.NewTokenFromV2(meta.GetSessionToken())) - if err != nil { - return nil, err - } - commonPrm, err := util.CommonPrmFromV2(req) if err != nil { return nil, err @@ -337,7 +325,7 @@ func (s *Service) toHeadPrm(ctx context.Context, req *objectV2.HeadRequest, resp p := new(getsvc.HeadPrm) p.SetCommonParameters(commonPrm. - WithPrivateKey(key), + WithKeyStorage(s.keyStorage), ) 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) { var err error + key, err := s.keyStorage.GetKey(nil) + if err != nil { + return nil, err + } + // once compose and resign forwarding request onceResign.Do(func() { // compose meta header of the local server diff --git a/pkg/services/object/search/util.go b/pkg/services/object/search/util.go index 6d1813d9..2a36a700 100644 --- a/pkg/services/object/search/util.go +++ b/pkg/services/object/search/util.go @@ -83,11 +83,16 @@ func (c *clientWrapper) searchObjects(exec *execCtx, info client.NodeInfo) ([]*o 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(), &exec.prm.SearchObjectParams, exec.prm.common.RemoteCallOptions( util.WithNetmapEpoch(exec.curProcEpoch), - util.WithKey(exec.prm.common.PrivateKey()), + util.WithKey(key), )...) } diff --git a/pkg/services/object/search/v2/util.go b/pkg/services/object/search/v2/util.go index 3c0f15f6..72bedf47 100644 --- a/pkg/services/object/search/v2/util.go +++ b/pkg/services/object/search/v2/util.go @@ -8,7 +8,6 @@ import ( cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" 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" objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object" "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) { meta := req.GetMetaHeader() - key, err := s.keyStorage.GetKey(sessionsdk.NewTokenFromV2(meta.GetSessionToken())) - if err != nil { - return nil, err - } - commonPrm, err := util.CommonPrmFromV2(req) if err != nil { return nil, err @@ -37,7 +31,7 @@ func (s *Service) toPrm(req *objectV2.SearchRequest, stream objectSvc.SearchStre p := new(searchsvc.Prm) p.SetCommonParameters(commonPrm. - WithPrivateKey(key), + WithKeyStorage(s.keyStorage), ) p.SetWriter(&streamWriter{ @@ -47,6 +41,11 @@ func (s *Service) toPrm(req *objectV2.SearchRequest, stream objectSvc.SearchStre if !commonPrm.LocalOnly() { 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) { var err error diff --git a/pkg/services/object/util/prm.go b/pkg/services/object/util/prm.go index bb9b01f8..26147502 100644 --- a/pkg/services/object/util/prm.go +++ b/pkg/services/object/util/prm.go @@ -20,7 +20,7 @@ type CommonPrm struct { bearer *token.BearerToken - key *ecdsa.PrivateKey + keyStor *KeyStorage callOpts []client.CallOption } @@ -63,19 +63,19 @@ func (p *CommonPrm) WithBearerToken(token *token.BearerToken) *CommonPrm { return p } -// WithPrivateKey sets private key to use during execution. -func (p *CommonPrm) WithPrivateKey(key *ecdsa.PrivateKey) *CommonPrm { +// WithKeyStorage sets private key storage to use during execution. +func (p *CommonPrm) WithKeyStorage(stor *KeyStorage) *CommonPrm { if p != nil { - p.key = key + p.keyStor = stor } return p } -// PrivateKey returns private key to use during execution. -func (p *CommonPrm) PrivateKey() *ecdsa.PrivateKey { +// KeyStorage returns private key storage to use during execution. +func (p *CommonPrm) KeyStorage() *KeyStorage { if p != nil { - return p.key + return p.keyStor } return nil