lockbox

password manager
Log | Files | Refs | README | LICENSE

commit b0e5a905b93bfb7ae3a986ae65749b6d17cfaa4f
parent 13181c6206287cc37f445e95e4958656910af146
Author: Sean Enck <sean@ttypty.com>
Date:   Sat, 16 Jul 2022 09:34:30 -0400

cleaning up clipboard

Diffstat:
Mcmd/lb-totp/main.go | 9++++++++-
Mcmd/lb/main.go | 19+++++++++++++------
Minternal/clip.go | 44+++++++++++++++++++++++---------------------
Ainternal/clip_test.go | 27+++++++++++++++++++++++++++
4 files changed, 71 insertions(+), 28 deletions(-)

diff --git a/cmd/lb-totp/main.go b/cmd/lb-totp/main.go @@ -117,6 +117,13 @@ func display(token string, args internal.Arguments) error { clear() } } + clip := internal.ClipboardCommands{} + if args.Clip { + clip, err = internal.NewClipboardCommands() + if err != nil { + internal.Die("invalid clipboard", err) + } + } for { if !first { time.Sleep(500 * time.Millisecond) @@ -157,7 +164,7 @@ func display(token string, args internal.Arguments) error { } } else { fmt.Printf("-> %s\n", expires) - internal.CopyToClipboard(code, exe) + clip.CopyToClipboard(code, exe) return nil } if !args.Once { diff --git a/cmd/lb/main.go b/cmd/lb/main.go @@ -186,6 +186,13 @@ func main() { internal.Die("unable to get color for terminal", err) } dumpData := []Dump{} + clip := internal.ClipboardCommands{} + if !isShow { + clip, err = internal.NewClipboardCommands() + if err != nil { + internal.Die("unable to get clipboard", err) + } + } for _, entry := range entries { if !internal.PathExists(entry) { internal.Die("invalid entry", errors.New("entry not found")) @@ -221,7 +228,7 @@ func main() { } continue } - internal.CopyToClipboard(value, getExecutable()) + clip.CopyToClipboard(value, getExecutable()) } if isDump { if !options.Yes { @@ -248,19 +255,19 @@ func main() { if err != nil { internal.Die("unable to read value to clear", err) } - _, paste, err := internal.GetClipboardCommand() + clip, err := internal.NewClipboardCommands() if err != nil { internal.Die("unable to get paste command", err) } var args []string - if len(paste) > 1 { - args = paste[1:] + if len(clip.Paste) > 1 { + args = clip.Paste[1:] } val = strings.TrimSpace(val) for idx < internal.MaxClipTime { idx++ time.Sleep(1 * time.Second) - out, err := exec.Command(paste[0], args...).Output() + out, err := exec.Command(clip.Paste[0], args...).Output() if err != nil { continue } @@ -270,7 +277,7 @@ func main() { return } } - internal.CopyToClipboard("", getExecutable()) + clip.CopyToClipboard("", getExecutable()) default: lib := os.Getenv("LOCKBOX_LIBEXEC") if lib == "" { diff --git a/internal/clip.go b/internal/clip.go @@ -18,13 +18,21 @@ const ( wslMode = "wsl" ) -// GetClipboardCommand will retrieve the commands to use for clipboard operations. -func GetClipboardCommand() ([]string, []string, error) { +type ( + // ClipboardCommands represent system clipboard operations. + ClipboardCommands struct { + Copy []string + Paste []string + } +) + +// NewClipboardCommands will retrieve the commands to use for clipboard operations. +func NewClipboardCommands() (ClipboardCommands, error) { env := strings.TrimSpace(os.Getenv("LOCKBOX_CLIPMODE")) if env == "" { b, err := exec.Command("uname", "-a").Output() if err != nil { - return nil, nil, err + return ClipboardCommands{}, err } raw := strings.TrimSpace(string(b)) parts := strings.Split(raw, " ") @@ -37,7 +45,7 @@ func GetClipboardCommand() ([]string, []string, error) { } else { if strings.TrimSpace(os.Getenv("WAYLAND_DISPLAY")) == "" { if strings.TrimSpace(os.Getenv("DISPLAY")) == "" { - return nil, nil, errors.New("unable to detect linux clipboard mode") + return ClipboardCommands{}, errors.New("unable to detect linux clipboard mode") } env = xClipMode } else { @@ -45,36 +53,30 @@ func GetClipboardCommand() ([]string, []string, error) { } } default: - return nil, nil, errors.New("unable to detect clipboard mode") + return ClipboardCommands{}, errors.New("unable to detect clipboard mode") } } switch env { case pbClipMode: - return []string{"pbcopy"}, []string{"pbpaste"}, nil + return ClipboardCommands{Copy: []string{"pbcopy"}, Paste: []string{"pbpaste"}}, nil case xClipMode: - return []string{"xclip"}, []string{"xclip", "-o"}, nil + return ClipboardCommands{Copy: []string{"xclip"}, Paste: []string{"xclip", "-o"}}, nil case waylandClipMode: - return []string{"wl-copy"}, []string{"wl-paste"}, nil + return ClipboardCommands{Copy: []string{"wl-copy"}, Paste: []string{"wl-paste"}}, nil case wslMode: - return []string{"clip.exe"}, []string{"powershell.exe", "-command", "Get-Clipboard"}, nil - case "off": - return nil, nil, errors.New("clipboard is turned off") + return ClipboardCommands{Copy: []string{"clip.exe"}, Paste: []string{"powershell.exe", "-command", "Get-Clipboard"}}, nil + default: + return ClipboardCommands{}, errors.New("clipboard is unavailable") } - return nil, nil, errors.New("unable to get clipboard command(s)") } // CopyToClipboard will copy to clipboard, if non-empty will clear later. -func CopyToClipboard(value, executable string) { - cp, _, err := GetClipboardCommand() - if err != nil { - fmt.Printf("unable to copy to clipboard: %v\n", err) - return - } +func (c ClipboardCommands) CopyToClipboard(value, executable string) { var args []string - if len(cp) > 1 { - args = cp[1:] + if len(c.Copy) > 1 { + args = c.Copy[1:] } - pipeTo(cp[0], value, true, args...) + pipeTo(c.Copy[0], value, true, args...) if value != "" { fmt.Printf("clipboard will clear in %d seconds\n", MaxClipTime) pipeTo(filepath.Join(filepath.Dir(executable), "lb"), value, false, "clear") diff --git a/internal/clip_test.go b/internal/clip_test.go @@ -0,0 +1,27 @@ +package internal + +import ( + "os" + "testing" +) + +func TestNoClipboard(t *testing.T) { + os.Setenv("LOCKBOX_CLIPMODE", "off") + _, err := NewClipboardCommands() + if err == nil || err.Error() != "clipboard is unavailable" { + t.Errorf("invalid error: %v", err) + } +} + +func TestClipboardInstances(t *testing.T) { + for _, item := range []string{pbClipMode, xClipMode, waylandClipMode, wslMode} { + os.Setenv("LOCKBOX_CLIPMODE", item) + c, err := NewClipboardCommands() + if err != nil { + t.Errorf("invalid clipboard: %v", err) + } + if len(c.Copy) == 0 || len(c.Paste) == 0 { + t.Error("invalid command retrieved") + } + } +}