mirror of
https://github.com/tendermint/tendermint.git
synced 2026-09-09 17:46:07 +00:00
Expose new and list via cli
This commit is contained in:
+7
-14
@@ -18,7 +18,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// listCmd represents the list command
|
||||
@@ -28,22 +27,16 @@ var listCmd = &cobra.Command{
|
||||
Long: `Return a list of all public keys stored by this key manager
|
||||
along with their associated name and address.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// TODO: Work your own magic here
|
||||
fmt.Println("list called")
|
||||
fmt.Println(viper.Get("format"))
|
||||
infos, err := manager.List()
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
printInfos(infos)
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(listCmd)
|
||||
|
||||
// Here you will define your flags and configuration settings.
|
||||
|
||||
// Cobra supports Persistent Flags which will work for this command
|
||||
// and all subcommands, e.g.:
|
||||
// listCmd.PersistentFlags().String("foo", "", "A help for foo")
|
||||
|
||||
// Cobra supports local flags which will only run when this command
|
||||
// is called directly, e.g.:
|
||||
listCmd.Flags().StringP("format", "f", "text", "Format to display (text|json)")
|
||||
}
|
||||
|
||||
+30
-12
@@ -22,28 +22,46 @@ import (
|
||||
|
||||
// newCmd represents the new command
|
||||
var newCmd = &cobra.Command{
|
||||
Use: "new",
|
||||
Use: "new <name>",
|
||||
Short: "Create a new public/private key pair",
|
||||
Long: `Add a public/private key pair to the key store.
|
||||
The password muts be entered in the terminal and not
|
||||
passed as a command line argument for security.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// TODO: Work your own magic here
|
||||
fmt.Println("new called")
|
||||
},
|
||||
Run: newPassword,
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(newCmd)
|
||||
}
|
||||
|
||||
// Here you will define your flags and configuration settings.
|
||||
func newPassword(cmd *cobra.Command, args []string) {
|
||||
if len(args) != 1 || len(args[0]) == 0 {
|
||||
fmt.Print("You must provide a name for the key")
|
||||
return
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
// Cobra supports Persistent Flags which will work for this command
|
||||
// and all subcommands, e.g.:
|
||||
// newCmd.PersistentFlags().String("foo", "", "A help for foo")
|
||||
// TODO: own function???
|
||||
pass, err := getPassword("Enter a passphrase:")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return
|
||||
}
|
||||
pass2, err := getPassword("Repeat the passphrase:")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return
|
||||
}
|
||||
if pass != pass2 {
|
||||
fmt.Println("Passphrases don't match")
|
||||
return
|
||||
}
|
||||
|
||||
// Cobra supports local flags which will only run when this command
|
||||
// is called directly, e.g.:
|
||||
// newCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
info, err := manager.Create(name, pass)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
printInfo(info)
|
||||
}
|
||||
|
||||
+27
-6
@@ -17,16 +17,22 @@ package cmd
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
keys "github.com/tendermint/go-keys"
|
||||
"github.com/tendermint/go-keys/cryptostore"
|
||||
"github.com/tendermint/go-keys/storage/filestorage"
|
||||
)
|
||||
|
||||
var (
|
||||
rootDir string
|
||||
format string
|
||||
output string
|
||||
keyDir string
|
||||
manager keys.Manager
|
||||
)
|
||||
|
||||
// RootCmd represents the base command when called without any subcommands
|
||||
@@ -53,7 +59,8 @@ func Execute() {
|
||||
func init() {
|
||||
cobra.OnInitialize(initEnv)
|
||||
RootCmd.PersistentFlags().StringP("root", "r", os.ExpandEnv("$HOME/.tlc"), "root directory for config and data (default is TM_ROOT or $HOME/.tlc)")
|
||||
RootCmd.PersistentFlags().StringP("format", "f", "text", "Output format (text|json)")
|
||||
RootCmd.PersistentFlags().StringP("output", "o", "text", "Output format (text|json)")
|
||||
RootCmd.PersistentFlags().StringP("keydir", "", "keys", "Directory to store private keys (subdir of root)")
|
||||
}
|
||||
|
||||
// initEnv sets to use ENV variables if set.
|
||||
@@ -85,11 +92,25 @@ func bindFlags(cmd *cobra.Command, args []string) error {
|
||||
|
||||
// validateFlags asserts all RootCmd flags are valid
|
||||
func validateFlags(cmd *cobra.Command) error {
|
||||
format = viper.GetString("format")
|
||||
switch format {
|
||||
// validate output format
|
||||
output = viper.GetString("output")
|
||||
switch output {
|
||||
case "text", "json":
|
||||
return nil
|
||||
default:
|
||||
return errors.Errorf("Unsupported format: %s", format)
|
||||
return errors.Errorf("Unsupported output format: %s", output)
|
||||
}
|
||||
|
||||
// store the keys directory
|
||||
keyDir = viper.GetString("keydir")
|
||||
if !filepath.IsAbs(keyDir) {
|
||||
keyDir = filepath.Join(rootDir, keyDir)
|
||||
}
|
||||
// and construct the key manager
|
||||
manager = cryptostore.New(
|
||||
cryptostore.GenEd25519, // TODO - cli switch???
|
||||
cryptostore.SecretBox,
|
||||
filestorage.New(keyDir),
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/bgentry/speakeasy"
|
||||
"github.com/pkg/errors"
|
||||
data "github.com/tendermint/go-data"
|
||||
keys "github.com/tendermint/go-keys"
|
||||
)
|
||||
|
||||
const PassLength = 10
|
||||
|
||||
func getPassword(prompt string) (string, error) {
|
||||
pass, err := speakeasy.Ask(prompt)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(pass) < PassLength {
|
||||
return "", errors.Errorf("Password must be at least %d characters", PassLength)
|
||||
}
|
||||
return pass, nil
|
||||
}
|
||||
|
||||
func printInfo(info keys.Info) {
|
||||
switch output {
|
||||
case "text":
|
||||
key, err := data.ToText(info.PubKey)
|
||||
if err != nil {
|
||||
panic(err) // really shouldn't happen...
|
||||
}
|
||||
fmt.Printf("%s\t%s\n", info.Name, key)
|
||||
case "json":
|
||||
json, err := data.ToJSON(info)
|
||||
if err != nil {
|
||||
panic(err) // really shouldn't happen...
|
||||
}
|
||||
fmt.Println(string(json))
|
||||
}
|
||||
}
|
||||
|
||||
func printInfos(infos keys.Infos) {
|
||||
switch output {
|
||||
case "text":
|
||||
fmt.Println("All keys:")
|
||||
for _, i := range infos {
|
||||
printInfo(i)
|
||||
}
|
||||
case "json":
|
||||
json, err := data.ToJSON(infos)
|
||||
if err != nil {
|
||||
panic(err) // really shouldn't happen...
|
||||
}
|
||||
fmt.Println(string(json))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user