2022-03-28 10:32:18 +00:00
|
|
|
package session
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
|
|
|
|
internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client"
|
2022-05-18 09:22:02 +00:00
|
|
|
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags"
|
2022-03-28 10:32:18 +00:00
|
|
|
"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/session"
|
2022-05-17 13:59:46 +00:00
|
|
|
"github.com/nspcc-dev/neofs-sdk-go/user"
|
2022-03-28 10:32:18 +00:00
|
|
|
"github.com/spf13/cobra"
|
2022-05-18 10:38:45 +00:00
|
|
|
"github.com/spf13/viper"
|
2022-03-28 10:32:18 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
lifetimeFlag = "lifetime"
|
|
|
|
outFlag = "out"
|
|
|
|
jsonFlag = "json"
|
|
|
|
)
|
|
|
|
|
|
|
|
const defaultLifetime = 10
|
|
|
|
|
|
|
|
var createCmd = &cobra.Command{
|
|
|
|
Use: "create",
|
|
|
|
Short: "Create session token",
|
|
|
|
RunE: createSession,
|
2022-05-18 10:38:45 +00:00
|
|
|
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
|
|
|
|
_ = viper.BindPFlag(commonflags.WalletPath, cmd.Flags().Lookup(commonflags.WalletPath))
|
|
|
|
_ = viper.BindPFlag(commonflags.Account, cmd.Flags().Lookup(commonflags.Account))
|
|
|
|
},
|
2022-03-28 10:32:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
createCmd.Flags().Uint64P(lifetimeFlag, "l", defaultLifetime, "number of epochs for token to stay valid")
|
2022-05-18 09:22:02 +00:00
|
|
|
createCmd.Flags().StringP(commonflags.WalletPath, commonflags.WalletPathShorthand, commonflags.WalletPathDefault, commonflags.WalletPathUsage)
|
|
|
|
createCmd.Flags().StringP(commonflags.Account, commonflags.AccountShorthand, commonflags.AccountDefault, commonflags.AccountUsage)
|
2022-03-28 10:32:18 +00:00
|
|
|
createCmd.Flags().String(outFlag, "", "file to write session token to")
|
|
|
|
createCmd.Flags().Bool(jsonFlag, false, "output token in JSON")
|
2022-05-18 09:22:02 +00:00
|
|
|
createCmd.Flags().StringP(commonflags.RPC, commonflags.RPCShorthand, commonflags.RPCDefault, commonflags.RPCUsage)
|
2022-03-28 10:32:18 +00:00
|
|
|
|
|
|
|
_ = cobra.MarkFlagRequired(createCmd.Flags(), lifetimeFlag)
|
2022-05-18 09:22:02 +00:00
|
|
|
_ = cobra.MarkFlagRequired(createCmd.Flags(), commonflags.WalletPath)
|
2022-03-28 10:32:18 +00:00
|
|
|
_ = cobra.MarkFlagRequired(createCmd.Flags(), outFlag)
|
2022-05-18 09:22:02 +00:00
|
|
|
_ = cobra.MarkFlagRequired(createCmd.Flags(), commonflags.RPC)
|
2022-03-28 10:32:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func createSession(cmd *cobra.Command, _ []string) error {
|
2022-05-24 08:22:23 +00:00
|
|
|
privKey := key.Get(cmd)
|
2022-03-28 10:32:18 +00:00
|
|
|
|
|
|
|
var netAddr network.Address
|
2022-05-18 09:22:02 +00:00
|
|
|
addrStr, _ := cmd.Flags().GetString(commonflags.RPC)
|
2022-03-28 10:32:18 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2022-05-17 13:59:46 +00:00
|
|
|
var ownerID user.ID
|
|
|
|
user.IDFromKey(&ownerID, privKey.PublicKey)
|
|
|
|
|
|
|
|
tok, err := CreateSession(c, &ownerID, lifetime)
|
2022-03-28 10:32:18 +00:00
|
|
|
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.
|
2022-05-17 13:59:46 +00:00
|
|
|
func CreateSession(c *client.Client, owner *user.ID, lifetime uint64) (*session.Token, error) {
|
2022-03-28 10:32:18 +00:00
|
|
|
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
|
|
|
|
}
|