diff --git a/cmd/neofs-cli/internal/commonflags/session.go b/cmd/neofs-cli/internal/commonflags/session.go new file mode 100644 index 00000000..b118b4f1 --- /dev/null +++ b/cmd/neofs-cli/internal/commonflags/session.go @@ -0,0 +1,14 @@ +package commonflags + +import "github.com/spf13/cobra" + +const SessionToken = "session" + +// InitSession initializes session parameter for cmd. +func InitSession(cmd *cobra.Command) { + cmd.Flags().String( + SessionToken, + "", + "path to a JSON-encoded container session token", + ) +} diff --git a/cmd/neofs-cli/modules/container.go b/cmd/neofs-cli/modules/container.go index a8a56669..1341d8ff 100644 --- a/cmd/neofs-cli/modules/container.go +++ b/cmd/neofs-cli/modules/container.go @@ -61,11 +61,6 @@ var wellKnownBasicACL = map[string]acl.BasicACL{ basicACLNoFinalAppend: acl.EACLPublicAppendRule, } -const sessionTokenFlag = "session" - -// path to a file with an encoded session token -var sessionTokenPath string - var ( containerOwner string @@ -163,6 +158,7 @@ It will be stored in sidechain when inner ring will accepts it.`, cnr := container.New() var tok *session.Container + sessionTokenPath, _ := cmd.Flags().GetString(commonflags.SessionToken) if sessionTokenPath != "" { tok = new(session.Container) common.ReadSessionToken(cmd, tok, sessionTokenPath) @@ -232,6 +228,7 @@ Only owner of the container has a permission to remove container.`, var tok *session.Container + sessionTokenPath, _ := cmd.Flags().GetString(commonflags.SessionToken) if sessionTokenPath != "" { tok = new(session.Container) common.ReadSessionToken(cmd, tok, sessionTokenPath) @@ -424,6 +421,7 @@ Container ID in EACL table will be substituted with ID from the CLI.`, var tok *session.Container + sessionTokenPath, _ := cmd.Flags().GetString(commonflags.SessionToken) if sessionTokenPath != "" { tok = new(session.Container) common.ReadSessionToken(cmd, tok, sessionTokenPath) @@ -586,12 +584,7 @@ func init() { deleteContainerCmd, setExtendedACLCmd, } { - cmd.Flags().StringVar( - &sessionTokenPath, - sessionTokenFlag, - "", - "path to a JSON-encoded container session token", - ) + commonflags.InitSession(cmd) } } diff --git a/cmd/neofs-cli/modules/lock.go b/cmd/neofs-cli/modules/lock.go index 39119716..220b5c29 100644 --- a/cmd/neofs-cli/modules/lock.go +++ b/cmd/neofs-cli/modules/lock.go @@ -7,6 +7,7 @@ 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" @@ -50,7 +51,7 @@ var cmdObjectLock = &cobra.Command{ var prm internalclient.PutObjectPrm - prepareSessionPrmWithOwner(cmd, cnr, nil, key, *idOwner, &prm) + sessionCli.Prepare(cmd, cnr, nil, key, &prm) prepareObjectPrm(cmd, &prm) prm.SetHeader(obj) diff --git a/cmd/neofs-cli/modules/object.go b/cmd/neofs-cli/modules/object.go index 515c1173..885c7331 100644 --- a/cmd/neofs-cli/modules/object.go +++ b/cmd/neofs-cli/modules/object.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "path/filepath" "strconv" @@ -45,8 +44,6 @@ const ( const bearerTokenFlag = "bearer" -const sessionTokenLifetime = 10 // in epochs - var ( // objectCmd represents the object command objectCmd = &cobra.Command{ @@ -301,12 +298,7 @@ func init() { objectRangeCmd, cmdObjectLock, } { - cmd.Flags().StringVar( - &sessionTokenPath, - sessionTokenFlag, - "", - "path to a JSON-encoded container session token", - ) + commonflags.InitSession(cmd) } } @@ -315,75 +307,9 @@ type clientKeySession interface { SetSessionToken(*session.Object) } -func prepareSessionPrm(cmd *cobra.Command, cnr cid.ID, obj *oid.ID, prms ...clientKeySession) { +func prepareSessionPrm(cmd *cobra.Command, cnr cid.ID, obj *oid.ID, prms ...sessionCli.RPCParameters) { pk := key.GetOrGenerate(cmd) - - prepareSessionPrmWithKey(cmd, cnr, obj, pk, prms...) -} - -func prepareSessionPrmWithKey(cmd *cobra.Command, cnr cid.ID, obj *oid.ID, key *ecdsa.PrivateKey, prms ...clientKeySession) { - ownerID, err := getOwnerID(key) - common.ExitOnErr(cmd, "owner ID from key: %w", err) - - prepareSessionPrmWithOwner(cmd, cnr, obj, key, *ownerID, prms...) -} - -func prepareSessionPrmWithOwner( - cmd *cobra.Command, - cnr cid.ID, - obj *oid.ID, - key *ecdsa.PrivateKey, - ownerID user.ID, - prms ...clientKeySession, -) { - cli := internalclient.GetSDKClientByFlag(cmd, key, commonflags.RPC) - - var tok session.Object - if tokenPath, _ := cmd.Flags().GetString(sessionTokenFlag); len(tokenPath) != 0 { - data, err := ioutil.ReadFile(tokenPath) - common.ExitOnErr(cmd, "can't read session token: %w", err) - - if err := tok.Unmarshal(data); err != nil { - err = tok.UnmarshalJSON(data) - common.ExitOnErr(cmd, "can't unmarshal session token: %w", err) - } - } else { - err := sessionCli.CreateSession(&tok, cli, sessionTokenLifetime) - common.ExitOnErr(cmd, "create session: %w", err) - } - - for i := range prms { - switch prms[i].(type) { - case *internalclient.GetObjectPrm: - tok.ForVerb(session.VerbObjectGet) - case *internalclient.HeadObjectPrm: - tok.ForVerb(session.VerbObjectHead) - case *internalclient.PutObjectPrm: - tok.ForVerb(session.VerbObjectPut) - case *internalclient.DeleteObjectPrm: - tok.ForVerb(session.VerbObjectDelete) - case *internalclient.SearchObjectsPrm: - tok.ForVerb(session.VerbObjectSearch) - case *internalclient.PayloadRangePrm: - tok.ForVerb(session.VerbObjectRange) - case *internalclient.HashPayloadRangesPrm: - tok.ForVerb(session.VerbObjectRangeHash) - default: - panic("invalid client parameter type") - } - - tok.BindContainer(cnr) - - if obj != nil { - tok.LimitByObject(*obj) - } - - err := tok.Sign(*key) - common.ExitOnErr(cmd, "session token signing: %w", err) - - prms[i].SetClient(cli) - prms[i].SetSessionToken(&tok) - } + sessionCli.Prepare(cmd, cnr, obj, pk, prms...) } type objectPrm interface { @@ -464,7 +390,7 @@ func putObject(cmd *cobra.Command, _ []string) { var prm internalclient.PutObjectPrm - prepareSessionPrmWithOwner(cmd, cnr, nil, pk, *ownerID, &prm) + sessionCli.Prepare(cmd, cnr, nil, pk, &prm) prepareObjectPrm(cmd, &prm) prm.SetHeader(obj) @@ -678,7 +604,7 @@ func getObjectHash(cmd *cobra.Command, _ []string) { hashPrm internalclient.HashPayloadRangesPrm headPrm internalclient.HeadObjectPrm - sesPrms = []clientKeySession{&hashPrm} + sesPrms = []sessionCli.RPCParameters{&hashPrm} objPrms = []objectPrm{&hashPrm} ) diff --git a/cmd/neofs-cli/modules/session/util.go b/cmd/neofs-cli/modules/session/util.go new file mode 100644 index 00000000..636c1bdd --- /dev/null +++ b/cmd/neofs-cli/modules/session/util.go @@ -0,0 +1,74 @@ +package session + +import ( + "crypto/ecdsa" + "io/ioutil" + + internalclient "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/client" + cid "github.com/nspcc-dev/neofs-sdk-go/container/id" + oid "github.com/nspcc-dev/neofs-sdk-go/object/id" + "github.com/nspcc-dev/neofs-sdk-go/session" + "github.com/spf13/cobra" +) + +// RPCParameters represents parameters for operations with session token. +type RPCParameters interface { + SetClient(*client.Client) + SetSessionToken(*session.Object) +} + +const sessionTokenLifetime = 10 // in epochs + +// Prepare prepares session for a command. +func Prepare(cmd *cobra.Command, cnr cid.ID, obj *oid.ID, key *ecdsa.PrivateKey, prms ...RPCParameters) { + cli := internalclient.GetSDKClientByFlag(cmd, key, commonflags.RPC) + + var tok session.Object + if tokenPath, _ := cmd.Flags().GetString(commonflags.SessionToken); len(tokenPath) != 0 { + data, err := ioutil.ReadFile(tokenPath) + common.ExitOnErr(cmd, "can't read session token: %w", err) + + if err := tok.Unmarshal(data); err != nil { + err = tok.UnmarshalJSON(data) + common.ExitOnErr(cmd, "can't unmarshal session token: %w", err) + } + } else { + err := CreateSession(&tok, cli, sessionTokenLifetime) + common.ExitOnErr(cmd, "create session: %w", err) + } + + for i := range prms { + switch prms[i].(type) { + case *internalclient.GetObjectPrm: + tok.ForVerb(session.VerbObjectGet) + case *internalclient.HeadObjectPrm: + tok.ForVerb(session.VerbObjectHead) + case *internalclient.PutObjectPrm: + tok.ForVerb(session.VerbObjectPut) + case *internalclient.DeleteObjectPrm: + tok.ForVerb(session.VerbObjectDelete) + case *internalclient.SearchObjectsPrm: + tok.ForVerb(session.VerbObjectSearch) + case *internalclient.PayloadRangePrm: + tok.ForVerb(session.VerbObjectRange) + case *internalclient.HashPayloadRangesPrm: + tok.ForVerb(session.VerbObjectRangeHash) + default: + panic("invalid client parameter type") + } + + tok.BindContainer(cnr) + if obj != nil { + tok.LimitByObject(*obj) + } + + err := tok.Sign(*key) + common.ExitOnErr(cmd, "session token signing: %w", err) + + prms[i].SetClient(cli) + prms[i].SetSessionToken(&tok) + } +} diff --git a/cmd/neofs-cli/modules/storagegroup.go b/cmd/neofs-cli/modules/storagegroup.go index 2b5cb28a..6cb83d0b 100644 --- a/cmd/neofs-cli/modules/storagegroup.go +++ b/cmd/neofs-cli/modules/storagegroup.go @@ -10,6 +10,7 @@ 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" "github.com/nspcc-dev/neofs-node/pkg/services/object_manager/storagegroup" cid "github.com/nspcc-dev/neofs-sdk-go/container/id" "github.com/nspcc-dev/neofs-sdk-go/object" @@ -147,8 +148,7 @@ type sgHeadReceiver struct { func (c sgHeadReceiver) Head(addr oid.Address) (interface{}, error) { obj := addr.Object() - prepareSessionPrmWithOwner(c.cmd, addr.Container(), &obj, c.key, c.ownerID, &c.prm) - + sessionCli.Prepare(c.cmd, addr.Container(), &obj, c.key, &c.prm) c.prm.SetAddress(addr) res, err := internalclient.HeadObject(c.prm) @@ -188,7 +188,7 @@ func putSG(cmd *cobra.Command, _ []string) { putPrm internalclient.PutObjectPrm ) - prepareSessionPrmWithOwner(cmd, cnr, nil, pk, *ownerID, &putPrm) + sessionCli.Prepare(cmd, cnr, nil, pk, &putPrm) prepareObjectPrm(cmd, &headPrm, &putPrm) headPrm.SetRawFlag(true)