diff --git a/action/context.go b/action/context.go new file mode 100644 index 0000000000..572f95423b --- /dev/null +++ b/action/context.go @@ -0,0 +1,69 @@ +package action + +import "context" + +type contextKey int + +const ( + ctxKeyClip contextKey = iota + ctxKeyForce + ctxKeyPasswordOnly + ctxKeyPrintQR +) + +// WithClip returns a context with the value for clip (for copy to clipboard) +// set +func WithClip(ctx context.Context, clip bool) context.Context { + return context.WithValue(ctx, ctxKeyClip, clip) +} + +// IsClip returns the value of clip or the default (false) +func IsClip(ctx context.Context) bool { + bv, ok := ctx.Value(ctxKeyClip).(bool) + if !ok { + return false + } + return bv +} + +// WithForce returns a context with the value for force set +func WithForce(ctx context.Context, force bool) context.Context { + return context.WithValue(ctx, ctxKeyForce, force) +} + +// IsForce returns the value of force or the default (false) +func IsForce(ctx context.Context) bool { + bv, ok := ctx.Value(ctxKeyForce).(bool) + if !ok { + return false + } + return bv +} + +// WithPasswordOnly returns a context with the value of password only set +func WithPasswordOnly(ctx context.Context, pw bool) context.Context { + return context.WithValue(ctx, ctxKeyPasswordOnly, pw) +} + +// IsPasswordOnly returns the value of password only or the default (false) +func IsPasswordOnly(ctx context.Context) bool { + bv, ok := ctx.Value(ctxKeyPasswordOnly).(bool) + if !ok { + return false + } + return bv +} + +// WithPrintQR returns a context with the value of print QR set +func WithPrintQR(ctx context.Context, qr bool) context.Context { + return context.WithValue(ctx, ctxKeyPrintQR, qr) +} + +// IsPrintQR returns the value of print QR or the default (false) +func IsPrintQR(ctx context.Context) bool { + bv, ok := ctx.Value(ctxKeyPrintQR).(bool) + if !ok { + return false + } + return bv +} diff --git a/action/find.go b/action/find.go index 243db894a3..c19ef39508 100644 --- a/action/find.go +++ b/action/find.go @@ -14,6 +14,8 @@ import ( // Find a string in the secret file's name func (s *Action) Find(ctx context.Context, c *cli.Context) error { + ctx = WithClip(ctx, c.Bool("clip")) + if !c.Args().Present() { return s.exitError(ctx, ExitUsage, nil, "Usage: %s find arg", s.Name) } @@ -31,11 +33,9 @@ func (s *Action) Find(ctx context.Context, c *cli.Context) error { } } - clip := c.Bool("clip") - if len(choices) == 1 { out.Green(ctx, "Found exact match in '%s'", choices[0]) - return s.show(ctx, c, choices[0], "", clip, false, false, false) + return s.show(ctx, c, choices[0], "", false) } if len(choices) < 1 && ctxutil.IsFuzzySearch(ctx) { @@ -61,17 +61,17 @@ func (s *Action) Find(ctx context.Context, c *cli.Context) error { case "copy": // display selected entry fmt.Println(choices[sel]) - return s.show(ctx, c, choices[sel], "", true, false, false, false) + return s.show(WithClip(ctx, true), c, choices[sel], "", false) case "show": // display selected entry fmt.Println(choices[sel]) - return s.show(ctx, c, choices[sel], "", clip, false, false, false) + return s.show(WithClip(ctx, false), c, choices[sel], "", false) case "sync": // run sync and re-run show/find workflow if err := s.Sync(ctx, c); err != nil { return err } - return s.show(ctx, c, needle, "", clip, false, false, true) + return s.show(ctx, c, needle, "", true) default: return s.exitError(ctx, ExitAborted, nil, "user aborted") } diff --git a/action/show.go b/action/show.go index 5c8251a24d..a96859c345 100644 --- a/action/show.go +++ b/action/show.go @@ -19,17 +19,18 @@ func (s *Action) Show(ctx context.Context, c *cli.Context) error { name := c.Args().First() key := c.Args().Get(1) - clip := c.Bool("clip") - force := c.Bool("force") - qr := c.Bool("qr") + ctx = WithClip(ctx, c.Bool("clip")) + ctx = WithForce(ctx, c.Bool("force")) + ctx = WithPrintQR(ctx, c.Bool("qr")) + ctx = WithPasswordOnly(ctx, c.Bool("password")) - if err := s.show(ctx, c, name, key, clip, force, qr, true); err != nil { + if err := s.show(ctx, c, name, key, true); err != nil { return s.exitError(ctx, ExitDecrypt, err, "%s", err) } return nil } -func (s *Action) show(ctx context.Context, c *cli.Context, name, key string, clip, force, qr, recurse bool) error { +func (s *Action) show(ctx context.Context, c *cli.Context, name, key string, recurse bool) error { if name == "" { return s.exitError(ctx, ExitUsage, nil, "Usage: %s show [name]", s.Name) } @@ -69,26 +70,29 @@ func (s *Action) show(ctx context.Context, c *cli.Context, name, key string, cli } return s.exitError(ctx, ExitUnknown, err, "failed to retrieve key '%s' from '%s': %s", key, name, err) } - if clip { + if IsClip(ctx) { return s.copyToClipboard(ctx, name, []byte(val)) } content = val - case qr: + case IsPrintQR(ctx): qr, err := qrcon.QRCode(sec.Password()) if err != nil { return s.exitError(ctx, ExitUnknown, err, "failed to encode '%s' as QR: %s", name, err) } fmt.Println(qr) return nil - case clip: + case IsClip(ctx): return s.copyToClipboard(ctx, name, []byte(sec.Password())) default: - if ctxutil.IsShowSafeContent(ctx) && !force { + switch { + case IsPasswordOnly(ctx): + content = sec.Password() + case ctxutil.IsShowSafeContent(ctx) && !IsForce(ctx): content = sec.Body() if content == "" { return s.exitError(ctx, ExitNotFound, store.ErrNoBody, "no safe content to display, you can force display with show -f") } - } else { + default: buf, err := sec.Bytes() if err != nil { return s.exitError(ctx, ExitUnknown, err, "failed to encode secret: %s", err) diff --git a/main.go b/main.go index 49535fbbbe..6ea5109171 100644 --- a/main.go +++ b/main.go @@ -919,6 +919,10 @@ func main() { Name: "force, f", Usage: "Display the password even if safecontent is enabled", }, + cli.BoolFlag{ + Name: "password, o", + Usage: "Dispaly only the password", + }, }, }, {