Skip to content

Commit

Permalink
Handle errors gracefully (#524)
Browse files Browse the repository at this point in the history
Fixes #489
  • Loading branch information
dominikschulz authored Dec 15, 2017
1 parent 1e713cd commit 16b8ee5
Show file tree
Hide file tree
Showing 35 changed files with 197 additions and 166 deletions.
4 changes: 2 additions & 2 deletions action/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func New(ctx context.Context, cfg *config.Config, sv semver.Version) (*Action, e
}

var err error
act.gpg, err = gpgcli.New(gpgcli.Config{
act.gpg, err = gpgcli.New(ctx, gpgcli.Config{
Umask: umask(),
Args: gpgOpts(),
})
Expand All @@ -64,7 +64,7 @@ func New(ctx context.Context, cfg *config.Config, sv semver.Version) (*Action, e

store, err := root.New(ctx, cfg, act.gpg)
if err != nil {
return nil, err
return nil, exitError(ctx, ExitUnknown, err, "failed to init root store: %s", err)
}
act.Store = store

Expand Down
4 changes: 2 additions & 2 deletions action/audit.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type auditedSecret struct {
func (s *Action) Audit(ctx context.Context, c *cli.Context) error {
t, err := s.Store.Tree()
if err != nil {
return s.exitError(ctx, ExitList, err, "failed to get store tree: %s", err)
return exitError(ctx, ExitList, err, "failed to get store tree: %s", err)
}
list := t.List(0)

Expand Down Expand Up @@ -111,7 +111,7 @@ func (s *Action) Audit(ctx context.Context, c *cli.Context) error {

if foundWeakPasswords || foundDuplicates || foundErrors {
_ = notify.Notify("gopass - audit", "Finished. Found weak passwords and/or duplicates")
return s.exitError(ctx, ExitAudit, nil, "found weak passwords or duplicates")
return exitError(ctx, ExitAudit, nil, "found weak passwords or duplicates")
}

_ = notify.Notify("gopass - audit", "Finished. No weak passwords or duplicates found!")
Expand Down
16 changes: 8 additions & 8 deletions action/binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const (
func (s *Action) BinaryCat(ctx context.Context, c *cli.Context) error {
name := c.Args().First()
if name == "" {
return s.exitError(ctx, ExitNoName, nil, "need a name")
return exitError(ctx, ExitNoName, nil, "need a name")
}
if !strings.HasSuffix(name, BinarySuffix) {
name += BinarySuffix
Expand All @@ -38,15 +38,15 @@ func (s *Action) BinaryCat(ctx context.Context, c *cli.Context) error {
// handle pipe to stdin
info, err := os.Stdin.Stat()
if err != nil {
return s.exitError(ctx, ExitIO, err, "failed to stat stdin: %s", err)
return exitError(ctx, ExitIO, err, "failed to stat stdin: %s", err)
}

// if content is piped to stdin, read and save it
if info.Mode()&os.ModeCharDevice == 0 {
content := &bytes.Buffer{}

if written, err := io.Copy(content, os.Stdin); err != nil {
return s.exitError(ctx, ExitIO, err, "Failed to copy after %d bytes: %s", written, err)
return exitError(ctx, ExitIO, err, "Failed to copy after %d bytes: %s", written, err)
}

return s.Store.Set(
Expand All @@ -58,7 +58,7 @@ func (s *Action) BinaryCat(ctx context.Context, c *cli.Context) error {

buf, err := s.binaryGet(ctx, name)
if err != nil {
return s.exitError(ctx, ExitDecrypt, err, "failed to read secret: %s", err)
return exitError(ctx, ExitDecrypt, err, "failed to read secret: %s", err)
}
color.Yellow(string(buf))
return nil
Expand All @@ -68,15 +68,15 @@ func (s *Action) BinaryCat(ctx context.Context, c *cli.Context) error {
func (s *Action) BinarySum(ctx context.Context, c *cli.Context) error {
name := c.Args().First()
if name == "" {
return s.exitError(ctx, ExitUsage, nil, "Usage: %s binary sha256 name", s.Name)
return exitError(ctx, ExitUsage, nil, "Usage: %s binary sha256 name", s.Name)
}
if !strings.HasSuffix(name, BinarySuffix) {
name += BinarySuffix
}

buf, err := s.binaryGet(ctx, name)
if err != nil {
return s.exitError(ctx, ExitDecrypt, err, "failed to read secret: %s", err)
return exitError(ctx, ExitDecrypt, err, "failed to read secret: %s", err)
}

h := sha256.New()
Expand All @@ -93,7 +93,7 @@ func (s *Action) BinaryCopy(ctx context.Context, c *cli.Context) error {
to := c.Args().Get(1)

if err := s.binaryCopy(ctx, from, to, false); err != nil {
return s.exitError(ctx, ExitUnknown, err, "%s", err)
return exitError(ctx, ExitUnknown, err, "%s", err)
}
return nil
}
Expand All @@ -106,7 +106,7 @@ func (s *Action) BinaryMove(ctx context.Context, c *cli.Context) error {
to := c.Args().Get(1)

if err := s.binaryCopy(ctx, from, to, true); err != nil {
return s.exitError(ctx, ExitUnknown, err, "%s", err)
return exitError(ctx, ExitUnknown, err, "%s", err)
}
return nil
}
Expand Down
3 changes: 1 addition & 2 deletions action/clipboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package action

import (
"context"
"fmt"

"github.com/atotto/clipboard"
"github.com/fatih/color"
Expand All @@ -25,6 +24,6 @@ func (s *Action) copyToClipboard(ctx context.Context, name string, content []byt
return errors.Wrapf(err, "failed to clear clipboard")
}

fmt.Printf("Copied %s to clipboard. Will clear in %d seconds.\n", color.YellowString(name), ctxutil.GetClipTimeout(ctx))
out.Print(ctx, "Copied %s to clipboard. Will clear in %d seconds.\n", color.YellowString(name), ctxutil.GetClipTimeout(ctx))
return nil
}
16 changes: 8 additions & 8 deletions action/clone.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
// Clone will fetch and mount a new password store from a git repo
func (s *Action) Clone(ctx context.Context, c *cli.Context) error {
if len(c.Args()) < 1 {
return errors.Errorf("Usage: %s clone repo [mount]", s.Name)
return exitError(ctx, ExitUsage, nil, "Usage: %s clone repo [mount]", s.Name)
}

repo := c.Args()[0]
Expand All @@ -36,28 +36,28 @@ func (s *Action) clone(ctx context.Context, repo, mount, path string) error {
path = config.PwStoreDir(mount)
}
if mount == "" && s.Store.Initialized() {
return s.exitError(ctx, ExitAlreadyInitialized, nil, "Can not clone %s to the root store, as this store is already initialized. Please try cloning to a submount: `%s clone %s sub`", repo, s.Name, repo)
return exitError(ctx, ExitAlreadyInitialized, nil, "Can not clone %s to the root store, as this store is already initialized. Please try cloning to a submount: `%s clone %s sub`", repo, s.Name, repo)
}

// clone repo
if err := gitClone(ctx, repo, path); err != nil {
return s.exitError(ctx, ExitGit, err, "failed to clone repo '%s' to '%s'", repo, path)
return exitError(ctx, ExitGit, err, "failed to clone repo '%s' to '%s'", repo, path)
}

// add mount
if mount != "" {
if !s.Store.Initialized() {
return s.exitError(ctx, ExitNotInitialized, nil, "Root-Store is not initialized. Clone or init root store first")
return exitError(ctx, ExitNotInitialized, nil, "Root-Store is not initialized. Clone or init root store first")
}
if err := s.Store.AddMount(ctx, mount, path); err != nil {
return s.exitError(ctx, ExitMount, err, "Failed to add mount: %s", err)
return exitError(ctx, ExitMount, err, "Failed to add mount: %s", err)
}
fmt.Printf("Mounted password store %s at mount point `%s` ...\n", path, mount)
}

// save new mount in config file
if err := s.cfg.Save(); err != nil {
return s.exitError(ctx, ExitIO, err, "Failed to update config: %s", err)
return exitError(ctx, ExitIO, err, "Failed to update config: %s", err)
}

// try to init git config
Expand All @@ -73,14 +73,14 @@ func (s *Action) clone(ctx context.Context, repo, mount, path string) error {
var err error
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")
return exitError(ctx, ExitIO, err, "Failed to read user input: %s", err)
}
}
if userEmail == "" {
var err error
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")
return exitError(ctx, ExitIO, err, "Failed to read user input: %s", err)
}
}
if err := s.Store.GitInitConfig(ctx, mount, sk, userName, userEmail); err != nil {
Expand Down
25 changes: 13 additions & 12 deletions action/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,63 +5,64 @@ import (
"fmt"
"sort"

"github.com/justwatchcom/gopass/utils/out"
"github.com/pkg/errors"
"github.com/urfave/cli"
)

// Config handles changes to the gopass configuration
func (s *Action) Config(ctx context.Context, c *cli.Context) error {
if len(c.Args()) < 1 {
if err := s.printConfigValues(""); err != nil {
return s.exitError(ctx, ExitUnknown, err, "Error printing config")
if err := s.printConfigValues(ctx, ""); err != nil {
return exitError(ctx, ExitUnknown, err, "Error printing config")
}
return nil
}

if len(c.Args()) == 1 {
if err := s.printConfigValues("", c.Args()[0]); err != nil {
return s.exitError(ctx, ExitUnknown, err, "Error printing config value")
if err := s.printConfigValues(ctx, "", c.Args()[0]); err != nil {
return exitError(ctx, ExitUnknown, err, "Error printing config value")
}
return nil
}

if len(c.Args()) > 2 {
return s.exitError(ctx, ExitUsage, nil, "Usage: %s config key value", s.Name)
return exitError(ctx, ExitUsage, nil, "Usage: %s config key value", s.Name)
}

if err := s.setConfigValue(ctx, c.String("store"), c.Args()[0], c.Args()[1]); err != nil {
return s.exitError(ctx, ExitUnknown, err, "Error setting config value")
return exitError(ctx, ExitUnknown, err, "Error setting config value")
}
return nil
}

func (s *Action) printConfigValues(store string, needles ...string) error {
func (s *Action) printConfigValues(ctx context.Context, store string, needles ...string) error {
prefix := ""
if len(needles) < 1 {
fmt.Printf("root store config:\n")
out.Print(ctx, "root store config:\n")
prefix = " "
}

m := s.cfg.Root.ConfigMap()
if store == "" {
for _, k := range filter(m, needles) {
fmt.Printf("%s%s: %s\n", prefix, k, m[k])
out.Print(ctx, "%s%s: %s\n", prefix, k, m[k])
}
}
for mp, sc := range s.cfg.Mounts {
if store != "" && mp != store {
continue
}
if len(needles) < 1 {
fmt.Printf("mount '%s' config:\n", mp)
out.Print(ctx, "mount '%s' config:\n", mp)
mp = " "
} else {
mp += "/"
}
sm := sc.ConfigMap()
for _, k := range filter(sm, needles) {
if sm[k] != m[k] || store != "" {
fmt.Printf("%s%s: %s\n", mp, k, sm[k])
out.Print(ctx, "%s%s: %s\n", mp, k, sm[k])
}
}
}
Expand Down Expand Up @@ -96,7 +97,7 @@ func (s *Action) setConfigValue(ctx context.Context, store, key, value string) e
if err := s.cfg.SetConfigValue(store, key, value); err != nil {
return errors.Wrapf(err, "failed to set config value '%s'", key)
}
return s.printConfigValues(store, key)
return s.printConfigValues(ctx, store, key)
}

// ConfigComplete will print the list of valid config keys
Expand Down
8 changes: 4 additions & 4 deletions action/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,24 @@ func (s *Action) Copy(ctx context.Context, c *cli.Context) error {
force := c.Bool("force")

if len(c.Args()) != 2 {
return s.exitError(ctx, ExitUsage, nil, "Usage: %s cp old-path new-path", s.Name)
return exitError(ctx, ExitUsage, nil, "Usage: %s cp old-path new-path", s.Name)
}

from := c.Args()[0]
to := c.Args()[1]

if !s.Store.Exists(ctx, from) {
return s.exitError(ctx, ExitNotFound, nil, "%s does not exist", from)
return exitError(ctx, ExitNotFound, nil, "%s does not exist", from)
}

if !force {
if s.Store.Exists(ctx, to) && !s.AskForConfirmation(ctx, fmt.Sprintf("%s already exists. Overwrite it?", to)) {
return s.exitError(ctx, ExitAborted, nil, "not overwriting your current secret")
return exitError(ctx, ExitAborted, nil, "not overwriting your current secret")
}
}

if err := s.Store.Copy(ctx, from, to); err != nil {
return s.exitError(ctx, ExitIO, err, "failed to copy from '%s' to '%s'", from, to)
return exitError(ctx, ExitIO, err, "failed to copy from '%s' to '%s'", from, to)
}

return nil
Expand Down
12 changes: 6 additions & 6 deletions action/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (s *Action) Create(ctx context.Context, c *cli.Context) error {
return s.createGeneric(ctx, c)
}
default:
return s.exitError(ctx, ExitAborted, nil, "user aborted")
return exitError(ctx, ExitAborted, nil, "user aborted")
}
return nil
}
Expand Down Expand Up @@ -115,7 +115,7 @@ func (s *Action) createWebsite(ctx context.Context, c *cli.Context) error {
_ = sec.SetValue("username", username)
_ = sec.SetValue("comment", comment)
if err := s.Store.Set(sub.WithReason(ctx, "Created new entry"), name, sec); err != nil {
return s.exitError(ctx, ExitEncrypt, err, "failed to set '%s': %s", name, err)
return exitError(ctx, ExitEncrypt, err, "failed to set '%s': %s", name, err)
}
if genPw {
fmt.Printf(
Expand Down Expand Up @@ -188,7 +188,7 @@ func (s *Action) createPIN(ctx context.Context, c *cli.Context) error {
_ = sec.SetValue("application", application)
_ = sec.SetValue("comment", comment)
if err := s.Store.Set(sub.WithReason(ctx, "Created new entry"), name, sec); err != nil {
return s.exitError(ctx, ExitEncrypt, err, "failed to set '%s': %s", name, err)
return exitError(ctx, ExitEncrypt, err, "failed to set '%s': %s", name, err)
}
if genPw {
fmt.Printf(
Expand Down Expand Up @@ -256,7 +256,7 @@ func (s *Action) createAWS(ctx context.Context, c *cli.Context) error {
_ = sec.SetValue("accesskey", accesskey)
_ = sec.SetValue("region", region)
if err := s.Store.Set(sub.WithReason(ctx, "Created new entry"), name, sec); err != nil {
return s.exitError(ctx, ExitEncrypt, err, "failed to set '%s': %s", name, err)
return exitError(ctx, ExitEncrypt, err, "failed to set '%s': %s", name, err)
}
return nil
}
Expand Down Expand Up @@ -319,7 +319,7 @@ func (s *Action) createGCP(ctx context.Context, c *cli.Context) error {
}
sec := secret.New("", string(buf))
if err := s.Store.Set(sub.WithReason(ctx, "Created new entry"), name, sec); err != nil {
return s.exitError(ctx, ExitEncrypt, err, "failed to set '%s': %s", name, err)
return exitError(ctx, ExitEncrypt, err, "failed to set '%s': %s", name, err)
}
return nil
}
Expand Down Expand Up @@ -409,7 +409,7 @@ func (s *Action) createGeneric(ctx context.Context, c *cli.Context) error {
_ = sec.SetValue(key, val)
}
if err := s.Store.Set(sub.WithReason(ctx, "Created new entry"), name, sec); err != nil {
return s.exitError(ctx, ExitEncrypt, err, "failed to set '%s': %s", name, err)
return exitError(ctx, ExitEncrypt, err, "failed to set '%s': %s", name, err)
}
if genPw {
fmt.Printf(
Expand Down
12 changes: 6 additions & 6 deletions action/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func (s *Action) Delete(ctx context.Context, c *cli.Context) error {

name := c.Args().First()
if name == "" {
return s.exitError(ctx, ExitUsage, nil, "Usage: %s rm name", s.Name)
return exitError(ctx, ExitUsage, nil, "Usage: %s rm name", s.Name)
}

key := c.Args().Get(1)
Expand All @@ -33,7 +33,7 @@ func (s *Action) Delete(ctx context.Context, c *cli.Context) error {

if recursive {
if err := s.Store.Prune(ctx, name); err != nil {
return s.exitError(ctx, ExitUnknown, err, "failed to prune '%s': %s", name, err)
return exitError(ctx, ExitUnknown, err, "failed to prune '%s': %s", name, err)
}
return nil
}
Expand All @@ -46,19 +46,19 @@ func (s *Action) Delete(ctx context.Context, c *cli.Context) error {
if key != "" {
sec, err := s.Store.Get(ctx, name)
if err != nil {
return s.exitError(ctx, ExitIO, err, "Can not delete key '%s' from '%s': %s", key, name, err)
return exitError(ctx, ExitIO, err, "Can not delete key '%s' from '%s': %s", key, name, err)
}
if err := sec.DeleteKey(key); err != nil {
return s.exitError(ctx, ExitIO, err, "Can not delete key '%s' from '%s': %s", key, name, err)
return exitError(ctx, ExitIO, err, "Can not delete key '%s' from '%s': %s", key, name, err)
}
if err := s.Store.Set(sub.WithReason(ctx, "Updated Key in YAML"), name, sec); err != nil {
return s.exitError(ctx, ExitIO, err, "Can not delete key '%s' from '%s': %s", key, name, err)
return exitError(ctx, ExitIO, err, "Can not delete key '%s' from '%s': %s", key, name, err)
}
return nil
}

if err := s.Store.Delete(ctx, name); err != nil {
return s.exitError(ctx, ExitIO, err, "Can not delete '%s': %s", name, err)
return exitError(ctx, ExitIO, err, "Can not delete '%s': %s", name, err)
}
return nil
}
Loading

0 comments on commit 16b8ee5

Please sign in to comment.