diff --git a/client/keys/cli/delete.go b/client/keys/cli/delete.go index 0f7286e05b..c8df33b52b 100644 --- a/client/keys/cli/delete.go +++ b/client/keys/cli/delete.go @@ -3,18 +3,38 @@ package keys import ( "fmt" + "bufio" + "errors" + "os" + + "github.com/irisnet/irishub/client" "github.com/irisnet/irishub/client/keys" + ck "github.com/irisnet/irishub/crypto/keys" "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +const ( + flagYes = "yes" ) func deleteKeyCommand() *cobra.Command { cmd := &cobra.Command{ - Use: "delete ", - Short: "Delete the given key", + Use: "delete ", + Short: "Delete the given key", + Long: `Delete a key from the store. +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 +gaiacli. +`, Example: "iriscli keys delete ", RunE: runDeleteCmd, Args: cobra.ExactArgs(1), } + + cmd.Flags().BoolP(flagYes, "y", false, + "Skip confirmation prompt when deleting offline or ledger key references") return cmd } @@ -26,12 +46,25 @@ func runDeleteCmd(cmd *cobra.Command, args []string) error { return err } - _, err = kb.Get(name) + info, err := kb.Get(name) if err != nil { return err } - buf := keys.BufferStdin() + buf := client.BufferStdin() + if info.GetType() == ck.TypeLedger || info.GetType() == ck.TypeOffline { + if !viper.GetBool(flagYes) { + if err := confirmDeletion(buf); err != nil { + return err + } + } + if err := kb.Delete(name, ""); err != nil { + return err + } + fmt.Fprintln(os.Stderr, "Public key reference deleted") + return nil + } + oldpass, err := keys.GetPassword( "DANGER - enter password to permanently delete key:", buf) if err != nil { @@ -42,6 +75,17 @@ func runDeleteCmd(cmd *cobra.Command, args []string) error { if err != nil { return err } - fmt.Println("Password deleted forever (uh oh!)") + fmt.Fprintln(os.Stderr, "Key deleted forever (uh oh!)") + return nil +} + +func confirmDeletion(buf *bufio.Reader) error { + answer, err := client.GetConfirmation("Key reference will be deleted. Continue?", buf) + if err != nil { + return err + } + if !answer { + return errors.New("aborted") + } return nil } diff --git a/crypto/keys/keybase.go b/crypto/keys/keybase.go index 44d7ab64a2..2a5f5beceb 100644 --- a/crypto/keys/keybase.go +++ b/crypto/keys/keybase.go @@ -365,35 +365,23 @@ func (kb dbKeybase) ImportPubKey(name string, armor string) (err error) { return } -// Delete removes key forever, but we must present the -// proper passphrase before deleting it (for security). -// A passphrase of 'yes' is used to delete stored -// references to offline and Ledger / HW wallet keys +// It returns an error if the key doesn't exist or +// passphrases don't match. +// Passphrase is ignored when deleting references to +// offline and Ledger / HW wallet keys. func (kb dbKeybase) Delete(name, passphrase string) error { // verify we have the proper password before deleting info, err := kb.Get(name) if err != nil { return err } - switch info.(type) { - case localInfo: - linfo := info.(localInfo) - _, err = mintkey.UnarmorDecryptPrivKey(linfo.PrivKeyArmor, passphrase) - if err != nil { + if linfo, ok := info.(localInfo); ok { + if _, err = mintkey.UnarmorDecryptPrivKey(linfo.PrivKeyArmor, passphrase); err != nil { return err } - kb.db.DeleteSync(addrKey(linfo.GetAddress())) - kb.db.DeleteSync(infoKey(name)) - return nil - case ledgerInfo: - case offlineInfo: - if passphrase != "yes" { - return fmt.Errorf("enter 'yes' exactly to delete the key - this cannot be undone") - } - kb.db.DeleteSync(addrKey(info.GetAddress())) - kb.db.DeleteSync(infoKey(name)) - return nil } + kb.db.DeleteSync(addrKey(info.GetAddress())) + kb.db.DeleteSync(infoKey(name)) return nil } diff --git a/crypto/keys/keybase_test.go b/crypto/keys/keybase_test.go index 349761e8d7..42a1440ef4 100644 --- a/crypto/keys/keybase_test.go +++ b/crypto/keys/keybase_test.go @@ -96,9 +96,7 @@ func TestKeyManagement(t *testing.T) { require.Equal(t, 2, len(keyS)) // delete the offline key - err = cstore.Delete(o1, "no") - require.NotNil(t, err) - err = cstore.Delete(o1, "yes") + err = cstore.Delete(o1, "") require.NoError(t, err) keyS, err = cstore.List() require.NoError(t, err)