From 03dc660797449ee13401ad4364bb5dc4b7d496b3 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 28 Feb 2018 15:20:46 +0100 Subject: [PATCH] Cleanup client/input.go per buckys request --- client/input.go | 31 +++++++++++++++---------------- client/keys/add.go | 8 ++++++-- client/keys/delete.go | 4 +++- client/keys/update.go | 8 ++++++-- x/bank/commands/account.go | 4 ++-- x/bank/commands/sendtx.go | 3 ++- 6 files changed, 34 insertions(+), 24 deletions(-) diff --git a/client/input.go b/client/input.go index db06f404ca8f..6036b68f9fe3 100644 --- a/client/input.go +++ b/client/input.go @@ -14,17 +14,19 @@ import ( // MinPassLength is the minimum acceptable password length const MinPassLength = 8 -// if we read from non-tty, we just need to init the buffer reader once, -// in case we try to read multiple passwords (eg. update) -var buf *bufio.Reader +// BufferStdin is used to allow reading prompts for stdin +// multiple times, when we read from non-tty +func BufferStdin() *bufio.Reader { + return bufio.NewReader(os.Stdin) +} // GetPassword will prompt for a password one-time (to sign a tx) // It enforces the password length -func GetPassword(prompt string) (pass string, err error) { +func GetPassword(prompt string, buf *bufio.Reader) (pass string, err error) { if inputIsTty() { pass, err = speakeasy.Ask(prompt) } else { - pass, err = stdinPassword() + pass, err = readLineFromBuf(buf) } if err != nil { return "", err @@ -37,11 +39,11 @@ func GetPassword(prompt string) (pass string, err error) { // GetSeed will request a seed phrase from stdin and trims off // leading/trailing spaces -func GetSeed(prompt string) (seed string, err error) { +func GetSeed(prompt string, buf *bufio.Reader) (seed string, err error) { if inputIsTty() { fmt.Println(prompt) } - seed, err = stdinPassword() + seed, err = readLineFromBuf(buf) seed = strings.TrimSpace(seed) return } @@ -50,18 +52,18 @@ func GetSeed(prompt string) (seed string, err error) { // match (for creating a new password). // It enforces the password length. Only parses password once if // input is piped in. -func GetCheckPassword(prompt, prompt2 string) (string, error) { +func GetCheckPassword(prompt, prompt2 string, buf *bufio.Reader) (string, error) { // simple read on no-tty if !inputIsTty() { - return GetPassword(prompt) + return GetPassword(prompt, buf) } // TODO: own function??? - pass, err := GetPassword(prompt) + pass, err := GetPassword(prompt, buf) if err != nil { return "", err } - pass2, err := GetPassword(prompt2) + pass2, err := GetPassword(prompt2, buf) if err != nil { return "", err } @@ -78,13 +80,10 @@ func inputIsTty() bool { return isatty.IsTerminal(os.Stdin.Fd()) || isatty.IsCygwinTerminal(os.Stdin.Fd()) } -// stdinPassword reads one line from stdin. +// readLineFromBuf reads one line from stdin. // Subsequent calls reuse the same buffer, so we don't lose // any input when reading a password twice (to verify) -func stdinPassword() (string, error) { - if buf == nil { - buf = bufio.NewReader(os.Stdin) - } +func readLineFromBuf(buf *bufio.Reader) (string, error) { pass, err := buf.ReadString('\n') if err != nil { return "", err diff --git a/client/keys/add.go b/client/keys/add.go index 07b1deba1c96..cef0b6260129 100644 --- a/client/keys/add.go +++ b/client/keys/add.go @@ -54,6 +54,7 @@ func runAddCmd(cmd *cobra.Command, args []string) error { var err error var name, pass string + buf := client.BufferStdin() if viper.GetBool(flagDryRun) { // we throw this away, so don't enforce args, // we want to get a new random seed phrase quickly @@ -69,14 +70,17 @@ func runAddCmd(cmd *cobra.Command, args []string) error { if err != nil { return err } - pass, err = client.GetCheckPassword("Enter a passphrase for your key:", "Repeat the passphrase:") + pass, err = client.GetCheckPassword( + "Enter a passphrase for your key:", + "Repeat the passphrase:", buf) if err != nil { return err } } if viper.GetBool(flagRecover) { - seed, err := client.GetSeed("Enter your recovery seed phrase:") + seed, err := client.GetSeed( + "Enter your recovery seed phrase:", buf) if err != nil { return err } diff --git a/client/keys/delete.go b/client/keys/delete.go index 58050087a5b5..3477ed6d4099 100644 --- a/client/keys/delete.go +++ b/client/keys/delete.go @@ -38,7 +38,9 @@ func runDeleteCmd(cmd *cobra.Command, args []string) error { } name := args[0] - oldpass, err := client.GetPassword("DANGER - enter password to permanently delete key:") + buf := client.BufferStdin() + oldpass, err := client.GetPassword( + "DANGER - enter password to permanently delete key:", buf) if err != nil { return err } diff --git a/client/keys/update.go b/client/keys/update.go index a7197dd96813..c809b988eef8 100644 --- a/client/keys/update.go +++ b/client/keys/update.go @@ -38,11 +38,15 @@ func runUpdateCmd(cmd *cobra.Command, args []string) error { } name := args[0] - oldpass, err := client.GetPassword("Enter the current passphrase:") + buf := client.BufferStdin() + oldpass, err := client.GetPassword( + "Enter the current passphrase:", buf) if err != nil { return err } - newpass, err := client.GetCheckPassword("Enter the new passphrase:", "Repeat the new passphrase:") + newpass, err := client.GetCheckPassword( + "Enter the new passphrase:", + "Repeat the new passphrase:", buf) if err != nil { return err } diff --git a/x/bank/commands/account.go b/x/bank/commands/account.go index 87f4066d9d1e..2f7f9132ef33 100644 --- a/x/bank/commands/account.go +++ b/x/bank/commands/account.go @@ -13,8 +13,8 @@ import ( rpcclient "github.com/tendermint/tendermint/rpc/client" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/examples/basecoin/app" - "github.com/cosmos/cosmos-sdk/examples/basecoin/types" + "github.com/cosmos/cosmos-sdk/examples/basecoin/app" // XXX: not good + "github.com/cosmos/cosmos-sdk/examples/basecoin/types" // XXX: not good ) // GetAccountCmd returns a query account that will display the diff --git a/x/bank/commands/sendtx.go b/x/bank/commands/sendtx.go index dc0a6bdd9675..6293661e6d69 100644 --- a/x/bank/commands/sendtx.go +++ b/x/bank/commands/sendtx.go @@ -90,8 +90,9 @@ func buildTx() ([]byte, error) { // sign and build bz := msg.GetSignBytes() + buf := client.BufferStdin() prompt := fmt.Sprintf("Password to sign with '%s':", name) - passphrase, err := client.GetPassword(prompt) + passphrase, err := client.GetPassword(prompt, buf) if err != nil { return nil, err }