keys: CLI Remove Viper (#6613)

* init commit

* Update ListKeysCmd

* updates

* updates

* test updates

* fix tests

* keys: Fix Test_runAddCmdLedgerWithCustomCoinType

* keys: Fix Test_runAddCmdLedger

* keys: Fix Test_runAddCmdBasic

* keys: Fix root tests

* keys: Fix Test_runMigrateCmd

* keys: Fix Test_runListCmd

* keys: Fix remaining tests
This commit is contained in:
Alexander Bezobchuk 2020-07-06 15:50:09 -04:00 committed by GitHub
parent e76a765e14
commit de7885a594
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 515 additions and 388 deletions

View File

@ -5,10 +5,12 @@ import (
"bytes"
"errors"
"fmt"
"io"
"sort"
bip39 "github.com/cosmos/go-bip39"
"github.com/spf13/cobra"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/input"
@ -16,12 +18,6 @@ import (
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/cli"
)
const (
@ -65,8 +61,9 @@ the flag --nosort is set.
Args: cobra.ExactArgs(1),
RunE: runAddCmd,
}
cmd.Flags().StringSlice(flagMultisig, nil, "Construct and store a multisig public key (implies --pubkey)")
cmd.Flags().Uint(flagMultiSigThreshold, 1, "K out of N required signatures. For use in conjunction with --multisig")
cmd.Flags().Int(flagMultiSigThreshold, 1, "K out of N required signatures. For use in conjunction with --multisig")
cmd.Flags().Bool(flagNoSort, false, "Keys passed to --multisig are taken in the order they're supplied")
cmd.Flags().String(FlagPublicKey, "", "Parse a public key in bech32 format and save it to disk")
cmd.Flags().BoolP(flagInteractive, "i", false, "Interactively prompt user for BIP39 passphrase and mnemonic")
@ -86,23 +83,29 @@ the flag --nosort is set.
return cmd
}
func getKeybase(transient bool, buf io.Reader) (keyring.Keyring, error) {
if transient {
return keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, viper.GetString(flags.FlagHome), buf)
}
return keyring.New(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), buf)
}
func runAddCmd(cmd *cobra.Command, args []string) error {
inBuf := bufio.NewReader(cmd.InOrStdin())
kb, err := getKeybase(viper.GetBool(flags.FlagDryRun), inBuf)
buf := bufio.NewReader(cmd.InOrStdin())
homeDir, _ := cmd.Flags().GetString(flags.FlagHome)
dryRun, _ := cmd.Flags().GetBool(flags.FlagHome)
var (
kr keyring.Keyring
err error
)
if dryRun {
kr, err = keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, homeDir, buf)
} else {
backend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
kr, err = keyring.New(sdk.KeyringServiceName(), backend, homeDir, buf)
}
if err != nil {
return err
}
return RunAddCmd(cmd, args, kb, inBuf)
return RunAddCmd(cmd, args, kr, buf)
}
/*
@ -118,16 +121,18 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf
var err error
name := args[0]
interactive := viper.GetBool(flagInteractive)
showMnemonic := !viper.GetBool(flagNoBackup)
interactive, _ := cmd.Flags().GetBool(flagInteractive)
noBackup, _ := cmd.Flags().GetBool(flagNoBackup)
showMnemonic := !noBackup
keyringAlgos, _ := kb.SupportedAlgorithms()
algo, err := keyring.NewSigningAlgoFromString(viper.GetString(flagKeyAlgo), keyringAlgos)
algoStr, _ := cmd.Flags().GetString(flagKeyAlgo)
algo, err := keyring.NewSigningAlgoFromString(algoStr, keyringAlgos)
if err != nil {
return err
}
if !viper.GetBool(flags.FlagDryRun) {
if dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun); !dryRun {
_, err = kb.Key(name)
if err == nil {
// account exists, ask for user confirmation
@ -146,11 +151,11 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf
}
}
multisigKeys := viper.GetStringSlice(flagMultisig)
multisigKeys, _ := cmd.Flags().GetStringSlice(flagMultisig)
if len(multisigKeys) != 0 {
var pks []crypto.PubKey
multisigThreshold := viper.GetInt(flagMultiSigThreshold)
multisigThreshold, _ := cmd.Flags().GetInt(flagMultiSigThreshold)
if err := validateMultisigThreshold(multisigThreshold, len(multisigKeys)); err != nil {
return err
}
@ -164,8 +169,7 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf
pks = append(pks, k.GetPubKey())
}
// Handle --nosort
if !viper.GetBool(flagNoSort) {
if noSort, _ := cmd.Flags().GetBool(flagNoSort); !noSort {
sort.Slice(pks, func(i, j int) bool {
return bytes.Compare(pks[i].Address(), pks[j].Address()) < 0
})
@ -177,13 +181,13 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf
}
cmd.PrintErrf("Key %q saved to disk.\n", name)
return nil
}
}
if viper.GetString(FlagPublicKey) != "" {
pk, err := sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeAccPub, viper.GetString(FlagPublicKey))
pubKey, _ := cmd.Flags().GetString(FlagPublicKey)
if pubKey != "" {
pk, err := sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeAccPub, pubKey)
if err != nil {
return err
}
@ -195,19 +199,20 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf
return nil
}
coinType := uint32(viper.GetInt(flagCoinType))
account := uint32(viper.GetInt(flagAccount))
index := uint32(viper.GetInt(flagIndex))
hdPath := viper.GetString(flagHDPath)
coinType, _ := cmd.Flags().GetUint32(flagCoinType)
account, _ := cmd.Flags().GetUint32(flagAccount)
index, _ := cmd.Flags().GetUint32(flagIndex)
hdPath, _ := cmd.Flags().GetString(flagHDPath)
useLedger, _ := cmd.Flags().GetBool(flags.FlagUseLedger)
if len(hdPath) == 0 {
hdPath = hd.CreateHDPath(coinType, account, index).String()
} else if viper.GetBool(flags.FlagUseLedger) {
} else if useLedger {
return errors.New("cannot set custom bip32 path with ledger")
}
// If we're using ledger, only thing we need is the path and the bech32 prefix.
if viper.GetBool(flags.FlagUseLedger) {
if useLedger {
bech32PrefixAccAddr := sdk.GetConfig().GetBech32AccountAddrPrefix()
info, err := kb.SaveLedgerKey(name, hd.Secp256k1, bech32PrefixAccAddr, coinType, account, index)
@ -221,9 +226,10 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf
// Get bip39 mnemonic
var mnemonic, bip39Passphrase string
if interactive || viper.GetBool(flagRecover) {
recover, _ := cmd.Flags().GetBool(flagRecover)
if interactive || recover {
bip39Message := "Enter your bip39 mnemonic"
if !viper.GetBool(flagRecover) {
if !recover {
bip39Message = "Enter your bip39 mnemonic, or hit enter to generate one."
}
@ -278,7 +284,7 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf
}
// Recover key from seed passphrase
if viper.GetBool(flagRecover) {
if recover {
// Hide mnemonic from output
showMnemonic = false
mnemonic = ""
@ -288,12 +294,12 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf
}
func printCreate(cmd *cobra.Command, info keyring.Info, showMnemonic bool, mnemonic string) error {
output := viper.Get(cli.OutputFlag)
output, _ := cmd.Flags().GetString(cli.OutputFlag)
switch output {
case OutputFormatText:
cmd.PrintErrln()
printKeyInfo(cmd.OutOrStdout(), info, keyring.Bech32KeyOutput)
printKeyInfo(cmd.OutOrStdout(), info, keyring.Bech32KeyOutput, output)
// print mnemonic unless requested not to.
if showMnemonic {

View File

@ -3,9 +3,9 @@
package keys
import (
"fmt"
"testing"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/libs/cli"
@ -34,29 +34,31 @@ func Test_runAddCmdLedgerWithCustomCoinType(t *testing.T) {
config.SetBech32PrefixForConsensusNode(bech32PrefixConsAddr, bech32PrefixConsPub)
cmd := AddKeyCommand()
require.NotNil(t, cmd)
cmd.Flags().AddFlagSet(Commands().PersistentFlags())
// Prepare a keybase
kbHome, kbCleanUp := tests.NewTestCaseDir(t)
require.NotNil(t, kbHome)
t.Cleanup(kbCleanUp)
viper.Set(flags.FlagHome, kbHome)
viper.Set(flags.FlagUseLedger, true)
viper.Set(flagAccount, "0")
viper.Set(flagIndex, "0")
viper.Set(flagCoinType, "330")
// Test Text
viper.Set(cli.OutputFlag, OutputFormatText)
// set algo flag value to the default
viper.Set(flagKeyAlgo, string(hd.Secp256k1Type))
// Now enter password
cmd.SetArgs([]string{
"keyname1",
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=true", flags.FlagUseLedger),
fmt.Sprintf("--%s=0", flagAccount),
fmt.Sprintf("--%s=0", flagIndex),
fmt.Sprintf("--%s=330", flagCoinType),
fmt.Sprintf("--%s=%s", cli.OutputFlag, OutputFormatText),
fmt.Sprintf("--%s=%s", flagKeyAlgo, string(hd.Secp256k1Type)),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})
mockIn, _, _ := tests.ApplyMockIO(cmd)
mockIn.Reset("test1234\ntest1234\n")
require.NoError(t, runAddCmd(cmd, []string{"keyname1"}))
require.NoError(t, cmd.Execute())
// Now check that it has been stored properly
kb, err := keyring.New(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), kbHome, mockIn)
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn)
require.NoError(t, err)
require.NotNil(t, kb)
t.Cleanup(func() {
@ -82,32 +84,35 @@ func Test_runAddCmdLedgerWithCustomCoinType(t *testing.T) {
func Test_runAddCmdLedger(t *testing.T) {
cmd := AddKeyCommand()
require.NotNil(t, cmd)
cmd.Flags().AddFlagSet(Commands().PersistentFlags())
mockIn, _, _ := tests.ApplyMockIO(cmd)
// Prepare a keybase
kbHome, kbCleanUp := tests.NewTestCaseDir(t)
require.NotNil(t, kbHome)
t.Cleanup(kbCleanUp)
viper.Set(flags.FlagHome, kbHome)
viper.Set(flags.FlagUseLedger, true)
// Test Text
viper.Set(cli.OutputFlag, OutputFormatText)
// set algo flag value to the default
viper.Set(flagKeyAlgo, string(hd.Secp256k1Type))
// Now enter password
cmd.SetArgs([]string{
"keyname1",
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=true", flags.FlagUseLedger),
fmt.Sprintf("--%s=%s", cli.OutputFlag, OutputFormatText),
fmt.Sprintf("--%s=%s", flagKeyAlgo, string(hd.Secp256k1Type)),
fmt.Sprintf("--%s=%d", flagCoinType, sdk.CoinType),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})
mockIn.Reset("test1234\ntest1234\n")
viper.Set(flagCoinType, sdk.CoinType)
require.NoError(t, runAddCmd(cmd, []string{"keyname1"}))
require.NoError(t, cmd.Execute())
// Now check that it has been stored properly
kb, err := keyring.New(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), kbHome, mockIn)
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn)
require.NoError(t, err)
require.NotNil(t, kb)
t.Cleanup(func() {
_ = kb.Delete("keyname1")
})
mockIn.Reset("test1234\n")
key1, err := kb.Key("keyname1")
require.NoError(t, err)

View File

@ -1,9 +1,9 @@
package keys
import (
"fmt"
"testing"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/libs/cli"
@ -17,41 +17,66 @@ import (
func Test_runAddCmdBasic(t *testing.T) {
cmd := AddKeyCommand()
require.NotNil(t, cmd)
cmd.Flags().AddFlagSet(Commands().PersistentFlags())
mockIn, _, _ := tests.ApplyMockIO(cmd)
kbHome, kbCleanUp := tests.NewTestCaseDir(t)
require.NotNil(t, kbHome)
t.Cleanup(kbCleanUp)
viper.Set(flags.FlagHome, kbHome)
viper.Set(cli.OutputFlag, OutputFormatText)
viper.Set(flags.FlagUseLedger, false)
mockIn.Reset("y\n")
// set algo flag value to the default
viper.Set(flagKeyAlgo, string(hd.Secp256k1Type))
kb, err := keyring.New(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), kbHome, mockIn)
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn)
require.NoError(t, err)
t.Cleanup(func() {
_ = kb.Delete("keyname1")
_ = kb.Delete("keyname2")
})
require.NoError(t, runAddCmd(cmd, []string{"keyname1"}))
cmd.SetArgs([]string{
"keyname1",
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", cli.OutputFlag, OutputFormatText),
fmt.Sprintf("--%s=%s", flagKeyAlgo, string(hd.Secp256k1Type)),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})
mockIn.Reset("y\n")
require.NoError(t, cmd.Execute())
mockIn.Reset("N\n")
require.Error(t, runAddCmd(cmd, []string{"keyname1"}))
require.Error(t, cmd.Execute())
cmd.SetArgs([]string{
"keyname2",
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", cli.OutputFlag, OutputFormatText),
fmt.Sprintf("--%s=%s", flagKeyAlgo, string(hd.Secp256k1Type)),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})
require.NoError(t, cmd.Execute())
require.Error(t, cmd.Execute())
require.NoError(t, runAddCmd(cmd, []string{"keyname2"}))
require.Error(t, runAddCmd(cmd, []string{"keyname2"}))
mockIn.Reset("y\n")
require.NoError(t, runAddCmd(cmd, []string{"keyname2"}))
require.NoError(t, cmd.Execute())
// test --dry-run
require.NoError(t, runAddCmd(cmd, []string{"keyname4"}))
require.Error(t, runAddCmd(cmd, []string{"keyname4"}))
cmd.SetArgs([]string{
"keyname4",
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", cli.OutputFlag, OutputFormatText),
fmt.Sprintf("--%s=%s", flagKeyAlgo, string(hd.Secp256k1Type)),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})
viper.Set(flags.FlagDryRun, true)
require.NoError(t, runAddCmd(cmd, []string{"keyname4"}))
require.NoError(t, cmd.Execute())
require.Error(t, cmd.Execute())
cmd.SetArgs([]string{
"keyname5",
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=true", flags.FlagDryRun),
fmt.Sprintf("--%s=%s", cli.OutputFlag, OutputFormatText),
fmt.Sprintf("--%s=%s", flagKeyAlgo, string(hd.Secp256k1Type)),
})
require.NoError(t, cmd.Execute())
}

View File

@ -9,7 +9,6 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
const (
@ -28,50 +27,49 @@ Note that removing offline or ledger keys will remove
only the public key references stored locally, i.e.
private keys stored in a ledger device cannot be deleted with the CLI.
`,
RunE: runDeleteCmd,
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
buf := bufio.NewReader(cmd.InOrStdin())
backend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
homeDir, _ := cmd.Flags().GetString(flags.FlagHome)
kb, err := keyring.New(sdk.KeyringServiceName(), backend, homeDir, buf)
if err != nil {
return err
}
for _, name := range args {
info, err := kb.Key(name)
if err != nil {
return err
}
// confirm deletion, unless -y is passed
if skip, _ := cmd.Flags().GetBool(flagYes); !skip {
if yes, err := input.GetConfirmation("Key reference will be deleted. Continue?", buf, cmd.ErrOrStderr()); err != nil {
return err
} else if !yes {
continue
}
}
if err := kb.Delete(name); err != nil {
return err
}
if info.GetType() == keyring.TypeLedger || info.GetType() == keyring.TypeOffline {
cmd.PrintErrln("Public key reference deleted")
continue
}
cmd.PrintErrln("Key deleted forever (uh oh!)")
}
return nil
},
}
cmd.Flags().BoolP(flagYes, "y", false,
"Skip confirmation prompt when deleting offline or ledger key references")
cmd.Flags().BoolP(flagForce, "f", false,
"Remove the key unconditionally without asking for the passphrase. Deprecated.")
cmd.Flags().BoolP(flagYes, "y", false, "Skip confirmation prompt when deleting offline or ledger key references")
cmd.Flags().BoolP(flagForce, "f", false, "Remove the key unconditionally without asking for the passphrase. Deprecated.")
return cmd
}
func runDeleteCmd(cmd *cobra.Command, args []string) error {
buf := bufio.NewReader(cmd.InOrStdin())
kb, err := keyring.New(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), buf)
if err != nil {
return err
}
for _, name := range args {
info, err := kb.Key(name)
if err != nil {
return err
}
// confirm deletion, unless -y is passed
if !viper.GetBool(flagYes) {
if yes, err := input.GetConfirmation("Key reference will be deleted. Continue?", buf, cmd.ErrOrStderr()); err != nil {
return err
} else if !yes {
continue
}
}
if err := kb.Delete(name); err != nil {
return err
}
if info.GetType() == keyring.TypeLedger || info.GetType() == keyring.TypeOffline {
cmd.PrintErrln("Public key reference deleted")
continue
}
cmd.PrintErrln("Key deleted forever (uh oh!)")
}
return nil
}

View File

@ -1,25 +1,25 @@
package keys
import (
"fmt"
"testing"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/tests"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func Test_runDeleteCmd(t *testing.T) {
deleteKeyCommand := DeleteKeyCommand()
mockIn, _, _ := tests.ApplyMockIO(deleteKeyCommand)
cmd := DeleteKeyCommand()
cmd.Flags().AddFlagSet(Commands().PersistentFlags())
mockIn, _, _ := tests.ApplyMockIO(cmd)
yesF, _ := deleteKeyCommand.Flags().GetBool(flagYes)
forceF, _ := deleteKeyCommand.Flags().GetBool(flagForce)
yesF, _ := cmd.Flags().GetBool(flagYes)
forceF, _ := cmd.Flags().GetBool(flagForce)
require.False(t, yesF)
require.False(t, forceF)
@ -29,24 +29,30 @@ func Test_runDeleteCmd(t *testing.T) {
// Now add a temporary keybase
kbHome, cleanUp := tests.NewTestCaseDir(t)
t.Cleanup(cleanUp)
viper.Set(flags.FlagHome, kbHome)
// Now
path := sdk.GetConfig().GetFullFundraiserPath()
backend := viper.GetString(flags.FlagKeyringBackend)
kb, err := keyring.New(sdk.KeyringServiceName(), backend, kbHome, mockIn)
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn)
require.NoError(t, err)
_, err = kb.NewAccount(fakeKeyName1, tests.TestMnemonic, "", path, hd.Secp256k1)
require.NoError(t, err)
_, _, err = kb.NewMnemonic(fakeKeyName2, keyring.English, sdk.FullFundraiserPath, hd.Secp256k1)
require.NoError(t, err)
err = runDeleteCmd(deleteKeyCommand, []string{"blah"})
cmd.SetArgs([]string{"blah", fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome)})
err = cmd.Execute()
require.Error(t, err)
require.Equal(t, "The specified item could not be found in the keyring", err.Error())
// User confirmation missing
err = runDeleteCmd(deleteKeyCommand, []string{fakeKeyName1})
cmd.SetArgs([]string{
fakeKeyName1,
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})
err = cmd.Execute()
require.Error(t, err)
require.Equal(t, "EOF", err.Error())
@ -54,17 +60,28 @@ func Test_runDeleteCmd(t *testing.T) {
require.NoError(t, err)
// Now there is a confirmation
viper.Set(flagYes, true)
require.NoError(t, runDeleteCmd(deleteKeyCommand, []string{fakeKeyName1}))
cmd.SetArgs([]string{
fakeKeyName1,
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=true", flagYes),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})
require.NoError(t, cmd.Execute())
_, err = kb.Key(fakeKeyName1)
require.Error(t, err) // Key1 is gone
viper.Set(flagYes, true)
_, err = kb.Key(fakeKeyName2)
require.NoError(t, err)
err = runDeleteCmd(deleteKeyCommand, []string{fakeKeyName2})
require.NoError(t, err)
cmd.SetArgs([]string{
fakeKeyName2,
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=true", flagYes),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})
require.NoError(t, cmd.Execute())
_, err = kb.Key(fakeKeyName2)
require.Error(t, err) // Key2 is gone
}

View File

@ -4,7 +4,6 @@ import (
"bufio"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/input"
@ -19,27 +18,28 @@ func ExportKeyCommand() *cobra.Command {
Short: "Export private keys",
Long: `Export a private key from the local keybase in ASCII-armored encrypted format.`,
Args: cobra.ExactArgs(1),
RunE: runExportCmd,
RunE: func(cmd *cobra.Command, args []string) error {
buf := bufio.NewReader(cmd.InOrStdin())
backend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
homeDir, _ := cmd.Flags().GetString(flags.FlagHome)
kb, err := keyring.New(sdk.KeyringServiceName(), backend, homeDir, buf)
if err != nil {
return err
}
encryptPassword, err := input.GetPassword("Enter passphrase to encrypt the exported key:", buf)
if err != nil {
return err
}
armored, err := kb.ExportPrivKeyArmor(args[0], encryptPassword)
if err != nil {
return err
}
cmd.Println(armored)
return nil
},
}
}
func runExportCmd(cmd *cobra.Command, args []string) error {
buf := bufio.NewReader(cmd.InOrStdin())
kb, err := keyring.New(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), buf)
if err != nil {
return err
}
encryptPassword, err := input.GetPassword("Enter passphrase to encrypt the exported key:", buf)
if err != nil {
return err
}
armored, err := kb.ExportPrivKeyArmor(args[0], encryptPassword)
if err != nil {
return err
}
cmd.Println(armored)
return nil
}

View File

@ -1,9 +1,9 @@
package keys
import (
"fmt"
"testing"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/crypto/hd"
@ -15,16 +15,16 @@ import (
)
func Test_runExportCmd(t *testing.T) {
exportKeyCommand := ExportKeyCommand()
mockIn, _, _ := tests.ApplyMockIO(exportKeyCommand)
cmd := ExportKeyCommand()
cmd.Flags().AddFlagSet(Commands().PersistentFlags())
mockIn, _, _ := tests.ApplyMockIO(cmd)
// Now add a temporary keybase
kbHome, cleanUp := tests.NewTestCaseDir(t)
t.Cleanup(cleanUp)
viper.Set(flags.FlagHome, kbHome)
// create a key
kb, err := keyring.New(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), kbHome, mockIn)
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn)
require.NoError(t, err)
t.Cleanup(func() {
kb.Delete("keyname1") // nolint:errcheck
@ -36,5 +36,11 @@ func Test_runExportCmd(t *testing.T) {
// Now enter password
mockIn.Reset("123456789\n123456789\n")
require.NoError(t, runExportCmd(exportKeyCommand, []string{"keyname1"}))
cmd.SetArgs([]string{
"keyname1",
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})
require.NoError(t, cmd.Execute())
}

View File

@ -5,7 +5,6 @@ import (
"io/ioutil"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/input"
@ -20,26 +19,27 @@ func ImportKeyCommand() *cobra.Command {
Short: "Import private keys into the local keybase",
Long: "Import a ASCII armored private key into the local keybase.",
Args: cobra.ExactArgs(2),
RunE: runImportCmd,
RunE: func(cmd *cobra.Command, args []string) error {
buf := bufio.NewReader(cmd.InOrStdin())
backend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
homeDir, _ := cmd.Flags().GetString(flags.FlagHome)
kb, err := keyring.New(sdk.KeyringServiceName(), backend, homeDir, buf)
if err != nil {
return err
}
bz, err := ioutil.ReadFile(args[1])
if err != nil {
return err
}
passphrase, err := input.GetPassword("Enter passphrase to decrypt your key:", buf)
if err != nil {
return err
}
return kb.ImportPrivKey(args[0], string(bz), passphrase)
},
}
}
func runImportCmd(cmd *cobra.Command, args []string) error {
buf := bufio.NewReader(cmd.InOrStdin())
kb, err := keyring.New(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), buf)
if err != nil {
return err
}
bz, err := ioutil.ReadFile(args[1])
if err != nil {
return err
}
passphrase, err := input.GetPassword("Enter passphrase to decrypt your key:", buf)
if err != nil {
return err
}
return kb.ImportPrivKey(args[0], string(bz), passphrase)
}

View File

@ -1,11 +1,11 @@
package keys
import (
"fmt"
"io/ioutil"
"path/filepath"
"testing"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/client/flags"
@ -15,15 +15,15 @@ import (
)
func Test_runImportCmd(t *testing.T) {
importKeyCommand := ImportKeyCommand()
mockIn, _, _ := tests.ApplyMockIO(importKeyCommand)
cmd := ImportKeyCommand()
cmd.Flags().AddFlagSet(Commands().PersistentFlags())
mockIn, _, _ := tests.ApplyMockIO(cmd)
// Now add a temporary keybase
kbHome, cleanUp := tests.NewTestCaseDir(t)
t.Cleanup(cleanUp)
viper.Set(flags.FlagHome, kbHome)
kb, err := keyring.New(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), kbHome, mockIn)
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn)
require.NoError(t, err)
t.Cleanup(func() {
kb.Delete("keyname1") // nolint:errcheck
@ -41,7 +41,11 @@ HbP+c6JmeJy9JXe2rbbF1QtCX1gLqGcDQPBXiCtFvP7/8wTZtVOPj8vREzhZ9ElO
`
require.NoError(t, ioutil.WriteFile(keyfile, []byte(armoredKey), 0644))
// Now enter password
mockIn.Reset("123456789\n")
require.NoError(t, runImportCmd(importKeyCommand, []string{"keyname1", keyfile}))
cmd.SetArgs([]string{
"keyname1", keyfile,
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})
require.NoError(t, cmd.Execute())
}

View File

@ -2,7 +2,7 @@ package keys
import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
@ -26,7 +26,9 @@ along with their associated name and address.`,
}
func runListCmd(cmd *cobra.Command, _ []string) error {
kb, err := keyring.New(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), cmd.InOrStdin())
backend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
homeDir, _ := cmd.Flags().GetString(flags.FlagHome)
kb, err := keyring.New(sdk.KeyringServiceName(), backend, homeDir, cmd.InOrStdin())
if err != nil {
return err
}
@ -37,8 +39,10 @@ func runListCmd(cmd *cobra.Command, _ []string) error {
}
cmd.SetOut(cmd.OutOrStdout())
if !viper.GetBool(flagListNames) {
printInfos(cmd.OutOrStdout(), infos)
if ok, _ := cmd.Flags().GetBool(flagListNames); !ok {
output, _ := cmd.Flags().GetString(cli.OutputFlag)
printInfos(cmd.OutOrStdout(), infos, output)
return nil
}

View File

@ -1,39 +1,31 @@
package keys
import (
"fmt"
"testing"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/tests"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func Test_runListCmd(t *testing.T) {
type args struct {
cmd *cobra.Command
args []string
}
cmd := ListKeysCmd()
cmd.Flags().AddFlagSet(Commands().PersistentFlags())
cmdBasic := ListKeysCmd()
// Prepare some keybases
kbHome1, cleanUp1 := tests.NewTestCaseDir(t)
t.Cleanup(cleanUp1)
// Do nothing, leave home1 empty
kbHome2, cleanUp2 := tests.NewTestCaseDir(t)
t.Cleanup(cleanUp2)
viper.Set(flags.FlagHome, kbHome2)
mockIn, _, _ := tests.ApplyMockIO(cmdBasic)
kb, err := keyring.New(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), mockIn)
mockIn, _, _ := tests.ApplyMockIO(cmd)
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome2, mockIn)
require.NoError(t, err)
path := "" //sdk.GetConfig().GetFullFundraiserPath()
@ -42,28 +34,41 @@ func Test_runListCmd(t *testing.T) {
t.Cleanup(func() {
kb.Delete("something") // nolint:errcheck
})
type args struct {
cmd *cobra.Command
args []string
}
testData := []struct {
name string
kbDir string
args args
wantErr bool
}{
{"keybase: empty", kbHome1, args{cmdBasic, []string{}}, false},
{"keybase: w/key", kbHome2, args{cmdBasic, []string{}}, false},
{"keybase: empty", kbHome1, false},
{"keybase: w/key", kbHome2, false},
}
for _, tt := range testData {
tt := tt
t.Run(tt.name, func(t *testing.T) {
viper.Set(flagListNames, false)
viper.Set(flags.FlagHome, tt.kbDir)
if err := runListCmd(tt.args.cmd, tt.args.args); (err != nil) != tt.wantErr {
cmd.SetArgs([]string{
fmt.Sprintf("--%s=%s", flags.FlagHome, tt.kbDir),
fmt.Sprintf("--%s=false", flagListNames),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})
if err := cmd.Execute(); (err != nil) != tt.wantErr {
t.Errorf("runListCmd() error = %v, wantErr %v", err, tt.wantErr)
}
viper.Set(flagListNames, true)
if err := runListCmd(tt.args.cmd, tt.args.args); (err != nil) != tt.wantErr {
cmd.SetArgs([]string{
fmt.Sprintf("--%s=%s", flags.FlagHome, tt.kbDir),
fmt.Sprintf("--%s=true", flagListNames),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})
if err := cmd.Execute(); (err != nil) != tt.wantErr {
t.Errorf("runListCmd() error = %v, wantErr %v", err, tt.wantErr)
}
})

View File

@ -6,14 +6,13 @@ import (
"io/ioutil"
"os"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/input"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
// migratePassphrase is used as a no-op migration key passphrase as a passphrase
@ -41,13 +40,15 @@ It is recommended to run in 'dry-run' mode first to verify all key migration mat
}
func runMigrateCmd(cmd *cobra.Command, args []string) error {
rootDir, _ := cmd.Flags().GetString(flags.FlagHome)
// instantiate legacy keybase
rootDir := viper.GetString(flags.FlagHome)
var legacyKb keyring.LegacyKeybase
legacyKb, err := NewLegacyKeyBaseFromDir(rootDir)
if err != nil {
return err
}
defer legacyKb.Close()
// fetch list of keys from legacy keybase
@ -64,7 +65,7 @@ func runMigrateCmd(cmd *cobra.Command, args []string) error {
migrator keyring.InfoImporter
)
if viper.GetBool(flags.FlagDryRun) {
if dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun); dryRun {
tmpDir, err = ioutil.TempDir("", "migrator-migrate-dryrun")
if err != nil {
return errors.Wrap(err, "failed to create temporary directory for dryrun migration")
@ -74,8 +75,10 @@ func runMigrateCmd(cmd *cobra.Command, args []string) error {
migrator, err = keyring.NewInfoImporter(keyringServiceName, "test", tmpDir, buf)
} else {
migrator, err = keyring.NewInfoImporter(keyringServiceName, viper.GetString(flags.FlagKeyringBackend), rootDir, buf)
backend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
migrator, err = keyring.NewInfoImporter(keyringServiceName, backend, rootDir, buf)
}
if err != nil {
return errors.Wrap(err, fmt.Sprintf(
"failed to initialize keybase for service %s at directory %s",

View File

@ -1,36 +1,48 @@
package keys
import (
"fmt"
"io/ioutil"
"testing"
"github.com/otiai10/copy"
"github.com/stretchr/testify/assert"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/tendermint/tendermint/libs/cli"
)
func Test_runMigrateCmd(t *testing.T) {
cmd := AddKeyCommand()
assert.NotNil(t, cmd)
cmd.SetErr(ioutil.Discard)
cmd.SetOut(ioutil.Discard)
cmd.Flags().AddFlagSet(Commands().PersistentFlags())
kbHome, kbCleanUp := tests.NewTestCaseDir(t)
copy.Copy("testdata", kbHome)
assert.NotNil(t, kbHome)
t.Cleanup(kbCleanUp)
viper.Set(flags.FlagHome, kbHome)
viper.Set(cli.OutputFlag, OutputFormatText)
cmd.SetArgs([]string{
"keyname1",
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", cli.OutputFlag, OutputFormatText),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})
assert.NoError(t, cmd.Execute())
assert.NoError(t, runAddCmd(cmd, []string{"keyname1"}))
viper.Set(flags.FlagDryRun, true)
cmd = MigrateCommand()
cmd.Flags().AddFlagSet(Commands().PersistentFlags())
mockIn, _, _ := tests.ApplyMockIO(cmd)
cmd.SetArgs([]string{
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=true", flags.FlagDryRun),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})
mockIn.Reset("test1234\ntest1234\n")
assert.NoError(t, runMigrateCmd(cmd, []string{}))
assert.NoError(t, cmd.Execute())
}

View File

@ -23,54 +23,53 @@ func MnemonicKeyCommand() *cobra.Command {
Use: "mnemonic",
Short: "Compute the bip39 mnemonic for some input entropy",
Long: "Create a bip39 mnemonic, sometimes called a seed phrase, by reading from the system entropy. To pass your own entropy, use --unsafe-entropy",
RunE: runMnemonicCmd,
RunE: func(cmd *cobra.Command, args []string) error {
var entropySeed []byte
if userEntropy, _ := cmd.Flags().GetBool(flagUserEntropy); userEntropy {
// prompt the user to enter some entropy
buf := bufio.NewReader(cmd.InOrStdin())
inputEntropy, err := input.GetString("> WARNING: Generate at least 256-bits of entropy and enter the results here:", buf)
if err != nil {
return err
}
if len(inputEntropy) < 43 {
return fmt.Errorf("256-bits is 43 characters in Base-64, and 100 in Base-6. You entered %v, and probably want more", len(inputEntropy))
}
conf, err := input.GetConfirmation(fmt.Sprintf("> Input length: %d", len(inputEntropy)), buf, cmd.ErrOrStderr())
if err != nil {
return err
}
if !conf {
return nil
}
// hash input entropy to get entropy seed
hashedEntropy := sha256.Sum256([]byte(inputEntropy))
entropySeed = hashedEntropy[:]
} else {
// read entropy seed straight from crypto.Rand
var err error
entropySeed, err = bip39.NewEntropy(mnemonicEntropySize)
if err != nil {
return err
}
}
mnemonic, err := bip39.NewMnemonic(entropySeed)
if err != nil {
return err
}
cmd.Println(mnemonic)
return nil
},
}
cmd.Flags().Bool(flagUserEntropy, false, "Prompt the user to supply their own entropy, instead of relying on the system")
return cmd
}
func runMnemonicCmd(cmd *cobra.Command, args []string) error {
flags := cmd.Flags()
userEntropy, _ := flags.GetBool(flagUserEntropy)
var entropySeed []byte
if userEntropy {
// prompt the user to enter some entropy
buf := bufio.NewReader(cmd.InOrStdin())
inputEntropy, err := input.GetString("> WARNING: Generate at least 256-bits of entropy and enter the results here:", buf)
if err != nil {
return err
}
if len(inputEntropy) < 43 {
return fmt.Errorf("256-bits is 43 characters in Base-64, and 100 in Base-6. You entered %v, and probably want more", len(inputEntropy))
}
conf, err := input.GetConfirmation(fmt.Sprintf("> Input length: %d", len(inputEntropy)), buf, cmd.ErrOrStderr())
if err != nil {
return err
}
if !conf {
return nil
}
// hash input entropy to get entropy seed
hashedEntropy := sha256.Sum256([]byte(inputEntropy))
entropySeed = hashedEntropy[:]
} else {
// read entropy seed straight from crypto.Rand
var err error
entropySeed, err = bip39.NewEntropy(mnemonicEntropySize)
if err != nil {
return err
}
}
mnemonic, err := bip39.NewMnemonic(entropySeed)
if err != nil {
return err
}
cmd.Println(mnemonic)
return nil
}

View File

@ -1,33 +1,38 @@
package keys
import (
"fmt"
"io/ioutil"
"strings"
"testing"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/tests"
)
func Test_RunMnemonicCmdNormal(t *testing.T) {
cmdBasic := MnemonicKeyCommand()
require.NoError(t, runMnemonicCmd(cmdBasic, []string{}))
cmd := MnemonicKeyCommand()
cmd.SetErr(ioutil.Discard)
cmd.SetOut(ioutil.Discard)
cmd.SetArgs([]string{})
require.NoError(t, cmd.Execute())
}
func Test_RunMnemonicCmdUser(t *testing.T) {
cmdUser := MnemonicKeyCommand()
err := cmdUser.Flags().Set(flagUserEntropy, "1")
assert.NoError(t, err)
cmd := MnemonicKeyCommand()
cmd.SetErr(ioutil.Discard)
cmd.SetOut(ioutil.Discard)
err = runMnemonicCmd(cmdUser, []string{})
cmd.SetArgs([]string{fmt.Sprintf("--%s=1", flagUserEntropy)})
err := cmd.Execute()
require.Error(t, err)
require.Equal(t, "EOF", err.Error())
// Try again
mockIn, _, _ := tests.ApplyMockIO(cmdUser)
mockIn, _, _ := tests.ApplyMockIO(cmd)
mockIn.Reset("Hi!\n")
err = runMnemonicCmd(cmdUser, []string{})
err = cmd.Execute()
require.Error(t, err)
require.Equal(t,
"256-bits is 43 characters in Base-64, and 100 in Base-6. You entered 3, and probably want more",
@ -36,15 +41,15 @@ func Test_RunMnemonicCmdUser(t *testing.T) {
// Now provide "good" entropy :)
fakeEntropy := strings.Repeat(":)", 40) + "\ny\n" // entropy + accept count
mockIn.Reset(fakeEntropy)
require.NoError(t, runMnemonicCmd(cmdUser, []string{}))
require.NoError(t, cmd.Execute())
// Now provide "good" entropy but no answer
fakeEntropy = strings.Repeat(":)", 40) + "\n" // entropy + accept count
mockIn.Reset(fakeEntropy)
require.Error(t, runMnemonicCmd(cmdUser, []string{}))
require.Error(t, cmd.Execute())
// Now provide "good" entropy but say no
fakeEntropy = strings.Repeat(":)", 40) + "\nn\n" // entropy + accept count
mockIn.Reset(fakeEntropy)
require.NoError(t, runMnemonicCmd(cmdUser, []string{}))
require.NoError(t, cmd.Execute())
}

View File

@ -9,14 +9,11 @@ import (
"strings"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
yaml "gopkg.in/yaml.v2"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/types/bech32"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/bech32"
)
func bech32Prefixes(config *sdk.Config) []string {
@ -101,7 +98,8 @@ func doParseKey(cmd *cobra.Command, config *sdk.Config, args []string) error {
return errors.New("couldn't parse empty input")
}
if !(runFromBech32(outstream, addr) || runFromHex(config, outstream, addr)) {
output, _ := cmd.Flags().GetString(cli.OutputFlag)
if !(runFromBech32(outstream, addr, output) || runFromHex(config, outstream, addr, output)) {
return errors.New("couldn't find valid bech32 nor hex data")
}
@ -109,36 +107,36 @@ func doParseKey(cmd *cobra.Command, config *sdk.Config, args []string) error {
}
// print info from bech32
func runFromBech32(w io.Writer, bech32str string) bool {
func runFromBech32(w io.Writer, bech32str, output string) bool {
hrp, bz, err := bech32.DecodeAndConvert(bech32str)
if err != nil {
return false
}
displayParseKeyInfo(w, newHexOutput(hrp, bz))
displayParseKeyInfo(w, newHexOutput(hrp, bz), output)
return true
}
// print info from hex
func runFromHex(config *sdk.Config, w io.Writer, hexstr string) bool {
func runFromHex(config *sdk.Config, w io.Writer, hexstr, output string) bool {
bz, err := hex.DecodeString(hexstr)
if err != nil {
return false
}
displayParseKeyInfo(w, newBech32Output(config, bz))
displayParseKeyInfo(w, newBech32Output(config, bz), output)
return true
}
func displayParseKeyInfo(w io.Writer, stringer fmt.Stringer) {
func displayParseKeyInfo(w io.Writer, stringer fmt.Stringer, output string) {
var (
err error
out []byte
)
switch viper.Get(cli.OutputFlag) {
switch output {
case OutputFormatText:
out, err = yaml.Marshal(&stringer)

View File

@ -2,7 +2,7 @@ package keys
import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/client/flags"
)
@ -36,6 +36,7 @@ information:
The pass backend requires GnuPG: https://gnupg.org/
`,
}
cmd.AddCommand(
MnemonicKeyCommand(),
AddKeyCommand(),
@ -48,7 +49,10 @@ The pass backend requires GnuPG: https://gnupg.org/
ParseKeyStringCommand(),
MigrateCommand(),
)
cmd.PersistentFlags().String(flags.FlagHome, "", "The application home directory")
cmd.PersistentFlags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
viper.BindPFlag(flags.FlagKeyringBackend, cmd.Flags().Lookup(flags.FlagKeyringBackend))
cmd.PersistentFlags().String(cli.OutputFlag, "text", "Output format (text|json)")
return cmd
}

View File

@ -1,15 +1,9 @@
package keys
import (
"os"
"testing"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func TestCommands(t *testing.T) {
@ -19,9 +13,3 @@ func TestCommands(t *testing.T) {
// Commands are registered
assert.Equal(t, 10, len(rootCommands.Commands()))
}
func TestMain(m *testing.M) {
viper.Set(flags.FlagKeyringBackend, keyring.BackendTest)
viper.Set(flagCoinType, sdk.CoinType)
os.Exit(m.Run())
}

View File

@ -5,8 +5,6 @@ import (
"fmt"
"github.com/spf13/cobra"
"github.com/spf13/viper"
tmcrypto "github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/cli"
@ -48,7 +46,7 @@ consisting of all the keys provided by name and multisig threshold.`,
cmd.Flags().BoolP(FlagAddress, "a", false, "Output the address only (overrides --output)")
cmd.Flags().BoolP(FlagPublicKey, "p", false, "Output the public key only (overrides --output)")
cmd.Flags().BoolP(FlagDevice, "d", false, "Output the address in a ledger device")
cmd.Flags().Uint(flagMultiSigThreshold, 1, "K out of N required signatures")
cmd.Flags().Int(flagMultiSigThreshold, 1, "K out of N required signatures")
return cmd
}
@ -56,10 +54,13 @@ consisting of all the keys provided by name and multisig threshold.`,
func runShowCmd(cmd *cobra.Command, args []string) (err error) {
var info keyring.Info
kb, err := keyring.New(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), cmd.InOrStdin())
backend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
homeDir, _ := cmd.Flags().GetString(flags.FlagHome)
kb, err := keyring.New(sdk.KeyringServiceName(), backend, homeDir, cmd.InOrStdin())
if err != nil {
return err
}
if len(args) == 1 {
info, err = fetchKey(kb, args[0])
if err != nil {
@ -76,7 +77,7 @@ func runShowCmd(cmd *cobra.Command, args []string) (err error) {
pks[i] = info.GetPubKey()
}
multisigThreshold := viper.GetInt(flagMultiSigThreshold)
multisigThreshold, _ := cmd.Flags().GetInt(flagMultiSigThreshold)
err = validateMultisigThreshold(multisigThreshold, len(args))
if err != nil {
return err
@ -86,9 +87,9 @@ func runShowCmd(cmd *cobra.Command, args []string) (err error) {
info = keyring.NewMultiInfo(defaultMultiSigKeyName, multikey)
}
isShowAddr := viper.GetBool(FlagAddress)
isShowPubKey := viper.GetBool(FlagPublicKey)
isShowDevice := viper.GetBool(FlagDevice)
isShowAddr, _ := cmd.Flags().GetBool(FlagAddress)
isShowPubKey, _ := cmd.Flags().GetBool(FlagPublicKey)
isShowDevice, _ := cmd.Flags().GetBool(FlagDevice)
isOutputSet := false
tmp := cmd.Flag(cli.OutputFlag)
@ -104,27 +105,31 @@ func runShowCmd(cmd *cobra.Command, args []string) (err error) {
return errors.New("cannot use --output with --address or --pubkey")
}
bechKeyOut, err := getBechKeyOut(viper.GetString(FlagBechPrefix))
bechPrefix, _ := cmd.Flags().GetString(FlagBechPrefix)
bechKeyOut, err := getBechKeyOut(bechPrefix)
if err != nil {
return err
}
output, _ := cmd.Flags().GetString(cli.OutputFlag)
switch {
case isShowAddr:
printKeyAddress(cmd.OutOrStdout(), info, bechKeyOut)
case isShowPubKey:
printPubKey(cmd.OutOrStdout(), info, bechKeyOut)
default:
printKeyInfo(cmd.OutOrStdout(), info, bechKeyOut)
printKeyInfo(cmd.OutOrStdout(), info, bechKeyOut, output)
}
if isShowDevice {
if isShowPubKey {
return fmt.Errorf("the device flag (-d) can only be used for addresses not pubkeys")
}
if viper.GetString(FlagBechPrefix) != "acc" {
if bechPrefix != "acc" {
return fmt.Errorf("the device flag (-d) can only be used for accounts")
}
// Override and show in the device
if info.GetType() != keyring.TypeLedger {
return fmt.Errorf("the device flag (-d) can only be used for accounts stored in devices")

View File

@ -1,9 +1,9 @@
package keys
import (
"fmt"
"testing"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
@ -37,19 +37,22 @@ func Test_showKeysCmd(t *testing.T) {
func Test_runShowCmd(t *testing.T) {
cmd := ShowKeysCmd()
cmd.Flags().AddFlagSet(Commands().PersistentFlags())
mockIn, _, _ := tests.ApplyMockIO(cmd)
require.EqualError(t, runShowCmd(cmd, []string{"invalid"}), "invalid is not a valid name or address: decoding bech32 failed: invalid bech32 string length 7")
require.EqualError(t, runShowCmd(cmd, []string{"invalid1", "invalid2"}), "invalid1 is not a valid name or address: decoding bech32 failed: invalid index of 1")
// Prepare a key base
// Now add a temporary keybase
cmd.SetArgs([]string{"invalid"})
require.EqualError(t, cmd.Execute(), "invalid is not a valid name or address: decoding bech32 failed: invalid bech32 string length 7")
cmd.SetArgs([]string{"invalid1", "invalid2"})
require.EqualError(t, cmd.Execute(), "invalid1 is not a valid name or address: decoding bech32 failed: invalid index of 1")
kbHome, cleanUp := tests.NewTestCaseDir(t)
t.Cleanup(cleanUp)
viper.Set(flags.FlagHome, kbHome)
fakeKeyName1 := "runShowCmd_Key1"
fakeKeyName2 := "runShowCmd_Key2"
kb, err := keyring.New(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), mockIn)
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn)
require.NoError(t, err)
t.Cleanup(func() {
kb.Delete("runShowCmd_Key1")
@ -65,44 +68,86 @@ func Test_runShowCmd(t *testing.T) {
require.NoError(t, err)
// Now try single key
require.EqualError(t, runShowCmd(cmd, []string{fakeKeyName1}), "invalid Bech32 prefix encoding provided: ")
cmd.SetArgs([]string{
fakeKeyName1,
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
fmt.Sprintf("--%s=", FlagBechPrefix),
})
require.EqualError(t, cmd.Execute(), "invalid Bech32 prefix encoding provided: ")
// Now try single key - set bech to acc
viper.Set(FlagBechPrefix, sdk.PrefixAccount)
cmd.SetArgs([]string{
fakeKeyName1,
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
fmt.Sprintf("--%s=%s", FlagBechPrefix, sdk.PrefixAccount),
})
// try fetch by name
require.NoError(t, runShowCmd(cmd, []string{fakeKeyName1}))
require.NoError(t, cmd.Execute())
// try fetch by addr
info, err := kb.Key(fakeKeyName1)
cmd.SetArgs([]string{
info.GetAddress().String(),
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
fmt.Sprintf("--%s=%s", FlagBechPrefix, sdk.PrefixAccount),
})
require.NoError(t, err)
require.NoError(t, runShowCmd(cmd, []string{info.GetAddress().String()}))
require.NoError(t, cmd.Execute())
// Now try multisig key - set bech to acc
viper.Set(FlagBechPrefix, sdk.PrefixAccount)
require.EqualError(t, runShowCmd(cmd, []string{fakeKeyName1, fakeKeyName2}), "threshold must be a positive integer")
cmd.SetArgs([]string{
fakeKeyName1, fakeKeyName2,
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
fmt.Sprintf("--%s=%s", FlagBechPrefix, sdk.PrefixAccount),
fmt.Sprintf("--%s=0", flagMultiSigThreshold),
})
require.EqualError(t, cmd.Execute(), "threshold must be a positive integer")
cmd.SetArgs([]string{
fakeKeyName1, fakeKeyName2,
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
fmt.Sprintf("--%s=%s", FlagBechPrefix, sdk.PrefixAccount),
fmt.Sprintf("--%s=2", flagMultiSigThreshold),
})
require.NoError(t, cmd.Execute())
// Now try multisig key - set bech to acc + threshold=2
viper.Set(FlagBechPrefix, sdk.PrefixAccount)
viper.Set(flagMultiSigThreshold, 2)
err = runShowCmd(cmd, []string{fakeKeyName1, fakeKeyName2})
require.NoError(t, err)
cmd.SetArgs([]string{
fakeKeyName1, fakeKeyName2,
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
fmt.Sprintf("--%s=acc", FlagBechPrefix),
fmt.Sprintf("--%s=true", FlagDevice),
fmt.Sprintf("--%s=2", flagMultiSigThreshold),
})
require.EqualError(t, cmd.Execute(), "the device flag (-d) can only be used for accounts stored in devices")
// Now try multisig key - set bech to acc + threshold=2
viper.Set(FlagBechPrefix, "acc")
viper.Set(FlagDevice, true)
viper.Set(flagMultiSigThreshold, 2)
err = runShowCmd(cmd, []string{fakeKeyName1, fakeKeyName2})
require.EqualError(t, err, "the device flag (-d) can only be used for accounts stored in devices")
cmd.SetArgs([]string{
fakeKeyName1, fakeKeyName2,
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
fmt.Sprintf("--%s=val", FlagBechPrefix),
fmt.Sprintf("--%s=true", FlagDevice),
fmt.Sprintf("--%s=2", flagMultiSigThreshold),
})
require.EqualError(t, cmd.Execute(), "the device flag (-d) can only be used for accounts")
viper.Set(FlagBechPrefix, "val")
err = runShowCmd(cmd, []string{fakeKeyName1, fakeKeyName2})
require.EqualError(t, err, "the device flag (-d) can only be used for accounts")
viper.Set(FlagPublicKey, true)
err = runShowCmd(cmd, []string{fakeKeyName1, fakeKeyName2})
require.EqualError(t, err, "the device flag (-d) can only be used for addresses not pubkeys")
// TODO: Capture stdout and compare
cmd.SetArgs([]string{
fakeKeyName1, fakeKeyName2,
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
fmt.Sprintf("--%s=val", FlagBechPrefix),
fmt.Sprintf("--%s=true", FlagDevice),
fmt.Sprintf("--%s=2", flagMultiSigThreshold),
fmt.Sprintf("--%s=true", FlagPublicKey),
})
require.EqualError(t, cmd.Execute(), "the device flag (-d) can only be used for addresses not pubkeys")
}
func Test_validateMultisigThreshold(t *testing.T) {

View File

@ -5,8 +5,6 @@ import (
"io"
"path/filepath"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"gopkg.in/yaml.v2"
cryptokeyring "github.com/cosmos/cosmos-sdk/crypto/keyring"
@ -33,13 +31,13 @@ func getLegacyKeyBaseFromDir(rootDir string, opts ...cryptokeyring.KeybaseOption
return cryptokeyring.NewLegacy(defaultKeyDBName, filepath.Join(rootDir, "keys"), opts...)
}
func printKeyInfo(w io.Writer, keyInfo cryptokeyring.Info, bechKeyOut bechKeyOutFn) {
func printKeyInfo(w io.Writer, keyInfo cryptokeyring.Info, bechKeyOut bechKeyOutFn, output string) {
ko, err := bechKeyOut(keyInfo)
if err != nil {
panic(err)
}
switch viper.Get(cli.OutputFlag) {
switch output {
case OutputFormatText:
printTextInfos(w, []cryptokeyring.KeyOutput{ko})
@ -53,13 +51,13 @@ func printKeyInfo(w io.Writer, keyInfo cryptokeyring.Info, bechKeyOut bechKeyOut
}
}
func printInfos(w io.Writer, infos []cryptokeyring.Info) {
func printInfos(w io.Writer, infos []cryptokeyring.Info, output string) {
kos, err := cryptokeyring.Bech32KeysOutput(infos)
if err != nil {
panic(err)
}
switch viper.Get(cli.OutputFlag) {
switch output {
case OutputFormatText:
printTextInfos(w, kos)