Skip to content

Commit

Permalink
Merge branch 'master' of github.com:justwatchcom/gopass
Browse files Browse the repository at this point in the history
* 'master' of github.com:justwatchcom/gopass:
  Improve context usage (#388)
  • Loading branch information
Dominik Schulz committed Oct 9, 2017
2 parents 2052391 + 79602af commit f77712a
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 65 deletions.
48 changes: 38 additions & 10 deletions action/clihelper.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ func (s *Action) ConfirmRecipients(ctx context.Context, name string, recipients

fmt.Printf("gopass: Encrypting %s for these recipients:\n", name)
for _, r := range recipients {
// check for context cancelation
select {
case <-ctx.Done():
return nil, errors.New("user aborted")
default:
}

kl, err := s.gpg.FindPublicKeys(ctx, r)
if err != nil {
fmt.Println(color.RedString("Failed to read public key for '%s': %s", name, err))
Expand All @@ -41,7 +48,7 @@ func (s *Action) ConfirmRecipients(ctx context.Context, name string, recipients
}
fmt.Println("")

yes, err := s.askForBool("Do you want to continue?", true)
yes, err := s.askForBool(ctx, "Do you want to continue?", true)
if err != nil {
return recipients, errors.Wrapf(err, "failed to read user input")
}
Expand All @@ -61,7 +68,7 @@ func (s *Action) AskForConfirmation(ctx context.Context, text string) bool {
}

for i := 0; i < maxTries; i++ {
if choice, err := s.askForBool(text, false); err == nil {
if choice, err := s.askForBool(ctx, text, false); err == nil {
return choice
}
}
Expand All @@ -71,13 +78,13 @@ func (s *Action) AskForConfirmation(ctx context.Context, text string) bool {
// askForBool ask for a bool (yes or no) exactly once.
// The empty answer uses the specified default, any other answer
// is an error.
func (s *Action) askForBool(text string, def bool) (bool, error) {
func (s *Action) askForBool(ctx context.Context, text string, def bool) (bool, error) {
choices := "y/N"
if def {
choices = "Y/n"
}

str, err := s.askForString(text, choices)
str, err := s.askForString(ctx, text, choices)
if err != nil {
return false, errors.Wrapf(err, "failed to read user input")
}
Expand All @@ -101,7 +108,14 @@ func (s *Action) askForBool(text string, def bool) (bool, error) {

// askForString asks for a string once, using the default if the
// anser is empty. Errors are only returned on I/O errors
func (s *Action) askForString(text, def string) (string, error) {
func (s *Action) askForString(ctx context.Context, text, def string) (string, error) {
// check for context cancelation
select {
case <-ctx.Done():
return "", errors.New("user aborted")
default:
}

reader := bufio.NewReader(os.Stdin)

fmt.Printf("%s [%s]: ", text, def)
Expand All @@ -118,8 +132,8 @@ func (s *Action) askForString(text, def string) (string, error) {

// askForInt asks for an valid interger once. If the input
// can not be converted to an int it returns an error
func (s *Action) askForInt(text string, def int) (int, error) {
str, err := s.askForString(text, strconv.Itoa(def))
func (s *Action) askForInt(ctx context.Context, text string, def int) (int, error) {
str, err := s.askForString(ctx, text, strconv.Itoa(def))
if err != nil {
return 0, err
}
Expand All @@ -143,6 +157,13 @@ func (s *Action) askForPassword(ctx context.Context, name string, askFn func(con
askFn = s.promptPass
}
for i := 0; i < maxTries; i++ {
// check for context cancelation
select {
case <-ctx.Done():
return "", errors.New("user aborted")
default:
}

pass, err := askFn(ctx, fmt.Sprintf("Enter password for %s", name))
if err != nil {
return "", err
Expand Down Expand Up @@ -171,7 +192,7 @@ func (s *Action) AskForKeyImport(ctx context.Context, key string) bool {
return false
}

ok, err := s.askForBool(fmt.Sprintf("Do you want to import the public key '%s' into your keyring?", key), false)
ok, err := s.askForBool(ctx, fmt.Sprintf("Do you want to import the public key '%s' into your keyring?", key), false)
if err != nil {
return false
}
Expand All @@ -196,12 +217,18 @@ func (s *Action) askForPrivateKey(ctx context.Context, prompt string) (string, e
if ctxutil.IsAlwaysYes(ctx) {
return kl[0].Fingerprint, nil
}
// check for context cancelation
select {
case <-ctx.Done():
return "", errors.New("user aborted")
default:
}

fmt.Println(prompt)
for i, k := range kl {
fmt.Printf("[%d] %s\n", i, k.OneLine())
}
iv, err := s.askForInt(fmt.Sprintf("Please enter the number of a key (0-%d)", len(kl)-1), 0)
iv, err := s.askForInt(ctx, fmt.Sprintf("Please enter the number of a key (0-%d)", len(kl)-1), 0)
if err != nil {
continue
}
Expand Down Expand Up @@ -243,7 +270,8 @@ func (s *Action) askForGitConfigUser(ctx context.Context) (string, string, error
}

useCurrent, err = s.askForBool(
fmt.Sprintf("Use %s (%s) for password store git config?", identity.Name, identity.Email), false)
ctx,
fmt.Sprintf("Use %s (%s) for password store git config?", identity.Name, identity.Email), true)
if err != nil {
return "", "", err
}
Expand Down
58 changes: 29 additions & 29 deletions action/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,19 @@ func (s *Action) createWebsite(ctx context.Context, c *cli.Context) error {
err error
genPw bool
)
urlStr, err = s.askForString("Please enter the URL", "")
urlStr, err = s.askForString(ctx, "Please enter the URL", "")
if err != nil {
return err
}
u, err := url.Parse(urlStr)
if err != nil {
return errors.Wrapf(err, "Can not parse URL. Please use 'gopass edit' to manually create the secret")
}
username, err = s.askForString("Please enter the Username/Login", "")
username, err = s.askForString(ctx, "Please enter the Username/Login", "")
if err != nil {
return err
}
genPw, err = s.askForBool("Do you want to generate a new password?", true)
genPw, err = s.askForBool(ctx, "Do you want to generate a new password?", true)
if err != nil {
return err
}
Expand All @@ -85,7 +85,7 @@ func (s *Action) createWebsite(ctx context.Context, c *cli.Context) error {
return err
}
}
comment, _ = s.askForString("Comments (optional)", "")
comment, _ = s.askForString(ctx, "Comments (optional)", "")
// select store
stores := []string{"<root>"}
stores = append(stores, s.Store.MountPoints()...)
Expand All @@ -105,7 +105,7 @@ func (s *Action) createWebsite(ctx context.Context, c *cli.Context) error {
}
name := fmt.Sprintf("%swebsites/%s/%s", store, u.Hostname(), username)
if s.Store.Exists(ctx, name) {
name, err = s.askForString("Secret already exists, please choose another path", name)
name, err = s.askForString(ctx, "Secret already exists, please choose another path", name)
if err != nil {
return err
}
Expand Down Expand Up @@ -136,15 +136,15 @@ func (s *Action) createPIN(ctx context.Context, c *cli.Context) error {
err error
genPw bool
)
authority, err = s.askForString("Please enter the authoriy (e.g. MyBank) this PIN is for", "")
authority, err = s.askForString(ctx, "Please enter the authoriy (e.g. MyBank) this PIN is for", "")
if err != nil {
return err
}
application, err = s.askForString("Please enter the entity (e.g. Credit Card) this PIN is for", "")
application, err = s.askForString(ctx, "Please enter the entity (e.g. Credit Card) this PIN is for", "")
if err != nil {
return err
}
genPw, err = s.askForBool("Do you want to generate a new PIN?", true)
genPw, err = s.askForBool(ctx, "Do you want to generate a new PIN?", true)
if err != nil {
return err
}
Expand All @@ -159,7 +159,7 @@ func (s *Action) createPIN(ctx context.Context, c *cli.Context) error {
return err
}
}
comment, _ = s.askForString("Comments (optional)", "")
comment, _ = s.askForString(ctx, "Comments (optional)", "")
// select store
stores := []string{"<root>"}
stores = append(stores, s.Store.MountPoints()...)
Expand All @@ -179,7 +179,7 @@ func (s *Action) createPIN(ctx context.Context, c *cli.Context) error {
}
name := fmt.Sprintf("%spins/%s/%s", store, authority, application)
if s.Store.Exists(ctx, name) {
name, err = s.askForString("Secret already exists, please choose another path", name)
name, err = s.askForString(ctx, "Secret already exists, please choose another path", name)
if err != nil {
return err
}
Expand Down Expand Up @@ -209,23 +209,23 @@ func (s *Action) createAWS(ctx context.Context, c *cli.Context) error {
store string
err error
)
account, err = s.askForString("Please enter the AWS Account this key belongs to", "")
account, err = s.askForString(ctx, "Please enter the AWS Account this key belongs to", "")
if err != nil {
return err
}
username, err = s.askForString("Please enter the name of the AWS IAM User this key belongs to", "")
username, err = s.askForString(ctx, "Please enter the name of the AWS IAM User this key belongs to", "")
if err != nil {
return err
}
accesskey, err = s.askForString("Please enter the Access Key ID (AWS_ACCESS_KEY_ID)", "")
accesskey, err = s.askForString(ctx, "Please enter the Access Key ID (AWS_ACCESS_KEY_ID)", "")
if err != nil {
return err
}
secretkey, err = s.askForPassword(ctx, "Please enter the Secret Access Key (AWS_SECRET_ACCESS_KEY)", nil)
if err != nil {
return err
}
region, _ = s.askForString("Please enter the default Region (AWS_DEFAULT_REGION) (optional)", "")
region, _ = s.askForString(ctx, "Please enter the default Region (AWS_DEFAULT_REGION) (optional)", "")
// select store
stores := []string{"<root>"}
stores = append(stores, s.Store.MountPoints()...)
Expand All @@ -245,7 +245,7 @@ func (s *Action) createAWS(ctx context.Context, c *cli.Context) error {
}
name := fmt.Sprintf("%saws/iam/%s/%s", store, account, username)
if s.Store.Exists(ctx, name) {
name, err = s.askForString("Secret already exists, please choose another path", name)
name, err = s.askForString(ctx, "Secret already exists, please choose another path", name)
if err != nil {
return err
}
Expand All @@ -269,7 +269,7 @@ func (s *Action) createGCP(ctx context.Context, c *cli.Context) error {
store string
err error
)
svcaccfn, err = s.askForString("Please enter path to the Service Account JSON file", "")
svcaccfn, err = s.askForString(ctx, "Please enter path to the Service Account JSON file", "")
if err != nil {
return err
}
Expand All @@ -282,13 +282,13 @@ func (s *Action) createGCP(ctx context.Context, c *cli.Context) error {
return err
}
if username == "" {
username, err = s.askForString("Please enter the name of this service account", "")
username, err = s.askForString(ctx, "Please enter the name of this service account", "")
if err != nil {
return err
}
}
if project == "" {
project, err = s.askForString("Please enter the name of this GCP project", "")
project, err = s.askForString(ctx, "Please enter the name of this GCP project", "")
if err != nil {
return err
}
Expand All @@ -312,7 +312,7 @@ func (s *Action) createGCP(ctx context.Context, c *cli.Context) error {
}
name := fmt.Sprintf("%sgcp/iam/%s/%s", store, project, username)
if s.Store.Exists(ctx, name) {
name, err = s.askForString("Secret already exists, please choose another path", name)
name, err = s.askForString(ctx, "Secret already exists, please choose another path", name)
if err != nil {
return err
}
Expand Down Expand Up @@ -349,11 +349,11 @@ func (s *Action) createGeneric(ctx context.Context, c *cli.Context) error {
err error
genPw bool
)
shortname, err = s.askForString("Please enter a name for the secret", "")
shortname, err = s.askForString(ctx, "Please enter a name for the secret", "")
if err != nil {
return err
}
genPw, err = s.askForBool("Do you want to generate a new password?", true)
genPw, err = s.askForBool(ctx, "Do you want to generate a new password?", true)
if err != nil {
return err
}
Expand Down Expand Up @@ -387,22 +387,22 @@ func (s *Action) createGeneric(ctx context.Context, c *cli.Context) error {
}
name := fmt.Sprintf("%smisc/%s", store, shortname)
if s.Store.Exists(ctx, name) {
name, err = s.askForString("Secret already exists, please choose another path", name)
name, err = s.askForString(ctx, "Secret already exists, please choose another path", name)
if err != nil {
return err
}
}
sec := secret.New(password, "")
fmt.Println("Enter zero or more key value pairs for this secret:")
for {
key, err := s.askForString("Name for Key Value pair (enter to quit)", "")
key, err := s.askForString(ctx, "Name for Key Value pair (enter to quit)", "")
if err != nil {
return err
}
if key == "" {
break
}
val, err := s.askForString("Value for Key '"+key+"'", "")
val, err := s.askForString(ctx, "Value for Key '"+key+"'", "")
if err != nil {
return err
}
Expand All @@ -421,12 +421,12 @@ func (s *Action) createGeneric(ctx context.Context, c *cli.Context) error {
}

func (s *Action) createGeneratePassword(ctx context.Context) (string, error) {
xkcd, err := s.askForBool("Do you want an rememberable password?", true)
xkcd, err := s.askForBool(ctx, "Do you want an rememberable password?", true)
if err != nil {
return "", err
}
if xkcd {
length, err := s.askForInt("How many words should be cominbed into a passphrase?", 4)
length, err := s.askForInt(ctx, "How many words should be cominbed into a passphrase?", 4)
if err != nil {
return "", err
}
Expand All @@ -437,19 +437,19 @@ func (s *Action) createGeneratePassword(ctx context.Context) (string, error) {
return string(g.GeneratePassword()), nil
}

length, err := s.askForInt("How long should the password be?", defaultLength)
length, err := s.askForInt(ctx, "How long should the password be?", defaultLength)
if err != nil {
return "", err
}
symbols, err := s.askForBool("Do you want to include symbols?", false)
symbols, err := s.askForBool(ctx, "Do you want to include symbols?", false)
if err != nil {
return "", err
}
return string(pwgen.GeneratePassword(length, symbols)), nil
}

func (s *Action) createGeneratePIN(ctx context.Context) (string, error) {
length, err := s.askForInt("How long should the PIN be?", 4)
length, err := s.askForInt(ctx, "How long should the PIN be?", 4)
if err != nil {
return "", err
}
Expand Down
4 changes: 2 additions & 2 deletions action/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (s *Action) Generate(ctx context.Context, c *cli.Context) error {

if name == "" {
var err error
name, err = s.askForString("Which name do you want to use?", "")
name, err = s.askForString(ctx, "Which name do you want to use?", "")
if err != nil || name == "" {
return s.exitError(ctx, ExitNoName, err, "please provide a password name")
}
Expand All @@ -70,7 +70,7 @@ func (s *Action) Generate(ctx context.Context, c *cli.Context) error {
question = "How many words should be combined to a password?"
}
var err error
if length, err = s.askForString(question, string(candidateLength)); err != nil {
if length, err = s.askForString(ctx, question, string(candidateLength)); err != nil {
panic(err) // panic on i/o error only, string -> int conversion is done below
}
}
Expand Down
4 changes: 2 additions & 2 deletions action/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ func (s *Action) gitInit(ctx context.Context, store, sk string) error {

if userName == "" {
var err error
userName, err = s.askForString(color.CyanString("Please enter a user name for password store git config"), userName)
userName, err = s.askForString(ctx, color.CyanString("Please enter a user name for password store git config"), userName)
if err != nil {
return errors.Wrapf(err, "failed to ask for user input")
}
}
if userEmail == "" {
var err error
userEmail, err = s.askForString(color.CyanString("Please enter an email address for password store git config"), userEmail)
userEmail, err = s.askForString(ctx, color.CyanString("Please enter an email address for password store git config"), userEmail)
if err != nil {
return errors.Wrapf(err, "failed to ask for user input")
}
Expand Down
Loading

0 comments on commit f77712a

Please sign in to comment.