[#1216] neofs-cli: Allow to create and save session token

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgenii Stratonikov 2022-03-28 13:32:18 +03:00 committed by LeL
parent 8d79168129
commit a95bdb1811
4 changed files with 155 additions and 29 deletions

View file

@ -16,6 +16,7 @@ import (
"github.com/cheggaaa/pb" "github.com/cheggaaa/pb"
objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object" objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object"
internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client" internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client"
sessionCli "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/modules/session"
"github.com/nspcc-dev/neofs-sdk-go/checksum" "github.com/nspcc-dev/neofs-sdk-go/checksum"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id" cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/object" "github.com/nspcc-dev/neofs-sdk-go/object"
@ -316,30 +317,11 @@ func prepareSessionPrmWithOwner(
ownerID *owner.ID, ownerID *owner.ID,
prms ...clientKeySession, prms ...clientKeySession,
) { ) {
var ( cli, err := getSDKClient(key)
sessionPrm internalclient.CreateSessionPrm exitOnErr(cmd, errf("create API client: %w", err))
netInfoPrm internalclient.NetworkInfoPrm
)
cws := make([]clientWithKey, 2, len(prms)+2) sessionToken, err := sessionCli.CreateSession(cli, ownerID, sessionTokenLifetime)
cws[0] = &sessionPrm exitOnErr(cmd, err)
cws[1] = &netInfoPrm
for i := range prms {
cws = append(cws, prms[i])
}
prepareAPIClientWithKey(cmd, key, cws...)
ni, err := internalclient.NetworkInfo(netInfoPrm)
exitOnErr(cmd, errf("read network info: %w", err))
cur := ni.NetworkInfo().CurrentEpoch()
exp := cur + sessionTokenLifetime
sessionPrm.SetExp(exp)
sessionRes, err := internalclient.CreateSession(sessionPrm)
exitOnErr(cmd, errf("open session: %w", err))
for i := range prms { for i := range prms {
objectContext := session.NewObjectContext() objectContext := session.NewObjectContext()
@ -364,17 +346,18 @@ func prepareSessionPrmWithOwner(
objectContext.ApplyTo(addr) objectContext.ApplyTo(addr)
tok := session.NewToken() tok := session.NewToken()
tok.SetID(sessionRes.ID()) tok.SetID(sessionToken.ID())
tok.SetSessionKey(sessionRes.SessionKey()) tok.SetSessionKey(sessionToken.SessionKey())
tok.SetOwnerID(ownerID) tok.SetOwnerID(sessionToken.OwnerID())
tok.SetContext(objectContext) tok.SetContext(objectContext)
tok.SetExp(exp) tok.SetExp(sessionToken.Exp())
tok.SetIat(cur) tok.SetIat(sessionToken.Iat())
tok.SetNbf(cur) tok.SetNbf(sessionToken.Nbf())
err = tok.Sign(key) err = tok.Sign(key)
exitOnErr(cmd, errf("session token signing: %w", err)) exitOnErr(cmd, errf("session token signing: %w", err))
prms[i].SetClient(cli)
prms[i].SetSessionToken(tok) prms[i].SetSessionToken(tok)
} }
} }

View file

@ -14,6 +14,7 @@ import (
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/modules/acl" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/modules/acl"
bearerCli "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/modules/bearer" bearerCli "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/modules/bearer"
sessionCli "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/modules/session"
"github.com/nspcc-dev/neofs-node/misc" "github.com/nspcc-dev/neofs-node/misc"
"github.com/nspcc-dev/neofs-node/pkg/network" "github.com/nspcc-dev/neofs-node/pkg/network"
"github.com/nspcc-dev/neofs-sdk-go/client" "github.com/nspcc-dev/neofs-sdk-go/client"
@ -120,6 +121,7 @@ func init() {
rootCmd.AddCommand(acl.Cmd) rootCmd.AddCommand(acl.Cmd)
rootCmd.AddCommand(bearerCli.Cmd) rootCmd.AddCommand(bearerCli.Cmd)
rootCmd.AddCommand(sessionCli.Cmd)
} }
func entryPoint(cmd *cobra.Command, _ []string) { func entryPoint(cmd *cobra.Command, _ []string) {

View file

@ -0,0 +1,127 @@
package session
import (
"fmt"
"io/ioutil"
internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key"
"github.com/nspcc-dev/neofs-node/pkg/network"
"github.com/nspcc-dev/neofs-sdk-go/client"
"github.com/nspcc-dev/neofs-sdk-go/owner"
"github.com/nspcc-dev/neofs-sdk-go/session"
"github.com/spf13/cobra"
)
const (
lifetimeFlag = "lifetime"
walletFlag = "wallet"
accountFlag = "address"
outFlag = "out"
jsonFlag = "json"
rpcFlag = "rpc-endpoint"
)
const defaultLifetime = 10
var createCmd = &cobra.Command{
Use: "create",
Short: "Create session token",
RunE: createSession,
}
func init() {
createCmd.Flags().Uint64P(lifetimeFlag, "l", defaultLifetime, "number of epochs for token to stay valid")
createCmd.Flags().StringP(walletFlag, "w", "", "path to the wallet")
createCmd.Flags().StringP(accountFlag, "a", "", "account address")
createCmd.Flags().String(outFlag, "", "file to write session token to")
createCmd.Flags().Bool(jsonFlag, false, "output token in JSON")
createCmd.Flags().StringP(rpcFlag, "r", "", "rpc-endpoint")
_ = cobra.MarkFlagRequired(createCmd.Flags(), lifetimeFlag)
_ = cobra.MarkFlagRequired(createCmd.Flags(), walletFlag)
_ = cobra.MarkFlagRequired(createCmd.Flags(), outFlag)
_ = cobra.MarkFlagRequired(createCmd.Flags(), rpcFlag)
}
func createSession(cmd *cobra.Command, _ []string) error {
walletPath, _ := cmd.Flags().GetString(walletFlag)
accPath, _ := cmd.Flags().GetString(accountFlag)
privKey, err := key.Get(walletPath, accPath)
if err != nil {
return err
}
var netAddr network.Address
addrStr, _ := cmd.Flags().GetString(rpcFlag)
if err := netAddr.FromString(addrStr); err != nil {
return err
}
c, err := internalclient.GetSDKClient(privKey, netAddr)
if err != nil {
return err
}
lifetime := uint64(defaultLifetime)
if lfArg, _ := cmd.Flags().GetUint64(lifetimeFlag); lfArg != 0 {
lifetime = lfArg
}
ownerID := owner.NewIDFromPublicKey(&privKey.PublicKey)
tok, err := CreateSession(c, ownerID, lifetime)
if err != nil {
return err
}
var data []byte
if toJSON, _ := cmd.Flags().GetBool(jsonFlag); toJSON {
data, err = tok.MarshalJSON()
} else {
data, err = tok.Marshal()
}
if err != nil {
return fmt.Errorf("can't marshal token: %w", err)
}
filename, _ := cmd.Flags().GetString(outFlag)
if err := ioutil.WriteFile(filename, data, 0644); err != nil {
return fmt.Errorf("can't write token to file: %w", err)
}
return nil
}
// CreateSession returns newly created session token with the specified owner and lifetime.
// `Issued-At` and `Not-Valid-Before` fields are set to current epoch.
func CreateSession(c *client.Client, owner *owner.ID, lifetime uint64) (*session.Token, error) {
var netInfoPrm internalclient.NetworkInfoPrm
netInfoPrm.SetClient(c)
ni, err := internalclient.NetworkInfo(netInfoPrm)
if err != nil {
return nil, fmt.Errorf("can't fetch network info: %w", err)
}
cur := ni.NetworkInfo().CurrentEpoch()
exp := cur + lifetime
var sessionPrm internalclient.CreateSessionPrm
sessionPrm.SetClient(c)
sessionPrm.SetExp(exp)
sessionRes, err := internalclient.CreateSession(sessionPrm)
if err != nil {
return nil, fmt.Errorf("can't open session: %w", err)
}
tok := session.NewToken()
tok.SetID(sessionRes.ID())
tok.SetSessionKey(sessionRes.SessionKey())
tok.SetOwnerID(owner)
tok.SetExp(exp)
tok.SetIat(cur)
tok.SetNbf(cur)
return tok, nil
}

View file

@ -0,0 +1,14 @@
package session
import (
"github.com/spf13/cobra"
)
var Cmd = &cobra.Command{
Use: "session",
Short: "Operations with session token",
}
func init() {
Cmd.AddCommand(createCmd)
}