[#1865] cli/object: Do not open remote sessions in reading ops

It does not make sense to open remote sessions with the storage node in
`get`, `head`, `search`, `range` and `hash` sub-commands of `neofs-cli
object` command.

Do not use NeoFS API `SessionService` in mentioned commands. Decode
object session from JSON file specified `--session` flag. Perform some
sanity checks instantly on CLI side.

Signed-off-by: Leonard Lyubich <ctulhurider@gmail.com>
This commit is contained in:
Leonard Lyubich 2022-10-10 22:31:19 +04:00 committed by fyrchik
parent 49eab6318c
commit 9a006ac14f
7 changed files with 112 additions and 9 deletions

View file

@ -26,6 +26,7 @@ Changelog for NeoFS Node
- Policer marks nodes under maintenance as OK without requests (#1680)
- Unify help messages in CLI (#1854)
- `evacuate`, `set-mode` and `flush-cache` control subcommands now accept a list of shard ids (#1867)
- Reading `object` commands of NeoFS CLI don't open remote sessions (#1865)
### Fixed
- Description of command `netmap nodeinfo` (#1821)

View file

@ -10,7 +10,6 @@ import (
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key"
sessionCli "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/modules/session"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/object"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
@ -65,9 +64,12 @@ func getObject(cmd *cobra.Command, _ []string) {
pk := key.GetOrGenerate(cmd)
cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC)
var prm internalclient.GetObjectPrm
sessionCli.Prepare(cmd, cnr, &obj, pk, &prm)
prm.SetClient(cli)
Prepare(cmd, &prm)
readSession(cmd, &prm, pk, cnr, obj)
raw, _ := cmd.Flags().GetBool(rawFlag)
prm.SetRawFlag(raw)

View file

@ -95,9 +95,12 @@ func getObjectHash(cmd *cobra.Command, _ []string) {
return
}
cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC)
var hashPrm internalclient.HashPayloadRangesPrm
sessionCli.Prepare(cmd, cnr, &obj, pk, &hashPrm)
hashPrm.SetClient(cli)
Prepare(cmd, &hashPrm)
readSession(cmd, &hashPrm, pk, cnr, obj)
hashPrm.SetAddress(objAddr)
hashPrm.SetSalt(salt)
hashPrm.SetRanges(ranges)

View file

@ -11,7 +11,6 @@ import (
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key"
sessionCli "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/modules/session"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/object"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
@ -53,9 +52,12 @@ func getObjectHeader(cmd *cobra.Command, _ []string) {
mainOnly, _ := cmd.Flags().GetBool("main-only")
pk := key.GetOrGenerate(cmd)
cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC)
var prm internalclient.HeadObjectPrm
sessionCli.Prepare(cmd, cnr, &obj, pk, &prm)
prm.SetClient(cli)
Prepare(cmd, &prm)
readSession(cmd, &prm, pk, cnr, obj)
raw, _ := cmd.Flags().GetBool(rawFlag)
prm.SetRawFlag(raw)

View file

@ -13,7 +13,6 @@ import (
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key"
sessionCli "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/modules/session"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/object"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
@ -75,9 +74,12 @@ func getObjectRange(cmd *cobra.Command, _ []string) {
pk := key.GetOrGenerate(cmd)
cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC)
var prm internalclient.PayloadRangePrm
sessionCli.Prepare(cmd, cnr, &obj, pk, &prm)
prm.SetClient(cli)
Prepare(cmd, &prm)
readSession(cmd, &prm, pk, cnr, obj)
raw, _ := cmd.Flags().GetBool(rawFlag)
prm.SetRawFlag(raw)

View file

@ -9,7 +9,6 @@ import (
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key"
sessionCli "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/modules/session"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/object"
oidSDK "github.com/nspcc-dev/neofs-sdk-go/object/id"
@ -55,9 +54,12 @@ func searchObject(cmd *cobra.Command, _ []string) {
pk := key.GetOrGenerate(cmd)
cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC)
var prm internalclient.SearchObjectsPrm
sessionCli.Prepare(cmd, cnr, nil, pk, &prm)
prm.SetClient(cli)
Prepare(cmd, &prm)
readSessionGlobal(cmd, &prm, pk, cnr)
prm.SetContainerID(cnr)
prm.SetFilters(sf)

View file

@ -1,14 +1,19 @@
package object
import (
"crypto/ecdsa"
"errors"
"fmt"
"strings"
internal "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags"
"github.com/nspcc-dev/neofs-sdk-go/bearer"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
"github.com/nspcc-dev/neofs-sdk-go/session"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
@ -81,3 +86,89 @@ func readOID(cmd *cobra.Command, id *oid.ID) {
err := id.DecodeString(cmd.Flag("oid").Value.String())
common.ExitOnErr(cmd, "decode object ID string: %w", err)
}
// common interface of object operation's input which supports sessions.
// Implemented on types like internal.PutObjectPrm.
type sessionPrm interface {
SetSessionToken(*session.Object)
}
// forwards all parameters to _readSession and object as nil.
func readSessionGlobal(cmd *cobra.Command, dst sessionPrm, key *ecdsa.PrivateKey, cnr cid.ID) {
_readSession(cmd, dst, key, cnr, nil)
}
// forwards all parameters to _readSession.
func readSession(cmd *cobra.Command, dst sessionPrm, key *ecdsa.PrivateKey, cnr cid.ID, obj oid.ID) {
_readSession(cmd, dst, key, cnr, &obj)
}
// decodes object session from JSON file from "session" command flag if it is provided,
// and writes resulting session into the provided sessionPrm. Checks:
//
// - if session verb corresponds to given sessionPrm according to its type
// - relation to the given container
// - relation to the given object if non-nil
// - relation to the given private key used withing the command
// - session signature
//
// sessionPrm MUST be one of:
//
// *internal.PutObjectPrm
// *internal.DeleteObjectPrm
// *internal.GetObjectPrm
// *internal.HeadObjectPrm
// *internal.SearchObjectsPrm
// *internal.PayloadRangePrm
// *internal.HashPayloadRangesPrm
func _readSession(cmd *cobra.Command, dst sessionPrm, key *ecdsa.PrivateKey, cnr cid.ID, obj *oid.ID) {
var cmdVerb session.ObjectVerb
switch dst.(type) {
default:
panic(fmt.Sprintf("unsupported op parameters %T", dst))
case *internal.PutObjectPrm:
cmdVerb = session.VerbObjectPut
case *internal.DeleteObjectPrm:
cmdVerb = session.VerbObjectDelete
case *internal.GetObjectPrm:
cmdVerb = session.VerbObjectGet
case *internal.HeadObjectPrm:
cmdVerb = session.VerbObjectHead
case *internal.SearchObjectsPrm:
cmdVerb = session.VerbObjectSearch
case *internal.PayloadRangePrm:
cmdVerb = session.VerbObjectRange
case *internal.HashPayloadRangesPrm:
cmdVerb = session.VerbObjectRangeHash
}
sessionTokenPath, _ := cmd.Flags().GetString(commonflags.SessionToken)
if sessionTokenPath != "" {
common.PrintVerbose("Reading object session from the JSON file [%s]...", sessionTokenPath)
var tok session.Object
common.ReadSessionToken(cmd, &tok, sessionTokenPath)
common.PrintVerbose("Checking session correctness...")
switch false {
case tok.AssertContainer(cnr):
common.ExitOnErr(cmd, "", errors.New("unrelated container in the session"))
case obj == nil || tok.AssertObject(*obj):
common.ExitOnErr(cmd, "", errors.New("unrelated object in the session"))
case tok.AssertVerb(cmdVerb):
common.ExitOnErr(cmd, "", errors.New("wrong verb of the session"))
case tok.AssertAuthKey((*neofsecdsa.PublicKey)(&key.PublicKey)):
common.ExitOnErr(cmd, "", errors.New("unrelated key in the session"))
case tok.VerifySignature():
common.ExitOnErr(cmd, "", errors.New("invalid signature of the session data"))
}
common.PrintVerbose("Session is correct.")
dst.SetSessionToken(&tok)
} else {
common.PrintVerbose("Session is not provided.")
}
}