commit 988578c2cb6eaa14cc10bbd8a0b5ce7dd69e1e24
parent 8749b4bb88e99f3c18c893ae31ee8969756a27f8
Author: Sean Enck <sean@ttypty.com>
Date: Wed, 13 Jul 2022 18:47:37 -0400
allow for dump
Diffstat:
5 files changed, 81 insertions(+), 7 deletions(-)
diff --git a/cmd/lb-bash/completions.bash b/cmd/lb-bash/completions.bash
@@ -18,12 +18,15 @@ _lb() {
fi
cur=${COMP_WORDS[COMP_CWORD]}
if [ "$COMP_CWORD" -eq 1 ]; then
- opts="version ls show insert rm rekey totp list pwgen find$clip_enabled"
+ opts="version ls show insert rm rekey totp list pwgen dump find$clip_enabled"
# shellcheck disable=SC2207
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
else
if [ "$COMP_CWORD" -eq 2 ]; then
case ${COMP_WORDS[1]} in
+ "dump")
+ opts="-yes $(lb ls)"
+ ;;
"insert")
opts="-m $(lb ls)"
;;
diff --git a/cmd/lb-totp/main.go b/cmd/lb-totp/main.go
@@ -9,8 +9,8 @@ import (
"strings"
"time"
- otp "github.com/pquerna/otp/totp"
"github.com/enckse/lockbox/internal"
+ otp "github.com/pquerna/otp/totp"
)
func getEnv() string {
diff --git a/cmd/lb/main.go b/cmd/lb/main.go
@@ -1,6 +1,7 @@
package main
import (
+ "encoding/json"
"fmt"
"os"
"os/exec"
@@ -17,6 +18,14 @@ var (
libExec = ""
)
+type (
+ // Dump represents the output structure from a JSON dump.
+ Dump struct {
+ Path string `json:"path,omitempty"`
+ Value string `json:"name"`
+ }
+)
+
func getEntry(store string, args []string, idx int) string {
if len(args) != idx+1 {
internal.Die("invalid entry given", internal.NewLockboxError("specific entry required"))
@@ -146,9 +155,20 @@ func main() {
os.Remove(entry)
hooks()
}
- case "show", "-c", "clip":
- inEntry := getEntry(store, args, 2)
- isShow := command == "show"
+ case "show", "-c", "clip", "dump":
+ isDump := command == "dump"
+ startEntry := 2
+ confirmDump := true
+ if isDump {
+ if len(args) > 2 {
+ if args[2] == "-yes" {
+ startEntry = 3
+ confirmDump = false
+ }
+ }
+ }
+ inEntry := getEntry(store, args, startEntry)
+ isShow := command == "show" || isDump
entries := []string{inEntry}
if strings.Contains(inEntry, "*") {
matches, err := filepath.Glob(inEntry)
@@ -168,6 +188,7 @@ func main() {
if err != nil {
internal.Die("unable to get color for terminal", err)
}
+ dumpData := []Dump{}
for _, entry := range entries {
if !internal.PathExists(entry) {
internal.Die("invalid entry", internal.NewLockboxError("entry not found"))
@@ -181,6 +202,7 @@ func main() {
internal.Die("unable to decrypt", err)
}
value := strings.TrimSpace(string(decrypt))
+ dump := Dump{}
if isShow {
if isGlob {
fileName := strings.ReplaceAll(entry, store, "")
@@ -188,13 +210,41 @@ func main() {
fileName = fileName[1:]
}
fileName = strings.ReplaceAll(fileName, internal.Extension, "")
- fmt.Printf("%s%s:%s\n", startColor, fileName, endColor)
+ if isDump {
+ dump.Path = fileName
+ } else {
+ fmt.Printf("%s%s:%s\n", startColor, fileName, endColor)
+ }
+ }
+ if isDump {
+ dump.Value = value
+ dumpData = append(dumpData, dump)
+ } else {
+ fmt.Println(value)
}
- fmt.Println(value)
continue
}
internal.CopyToClipboard(value)
}
+ if isDump {
+ if confirmDump {
+ if !confirm("dump data to stdout as plaintext") {
+ return
+ }
+ }
+ fmt.Println("[")
+ for idx, d := range dumpData {
+ if idx > 0 {
+ fmt.Println(",")
+ }
+ b, err := json.MarshalIndent(d, "", " ")
+ if err != nil {
+ internal.Die("failed to marshal dump item", err)
+ }
+ fmt.Println(string(b))
+ }
+ fmt.Println("]")
+ }
case "clear":
idx := 0
val, err := internal.Stdin(false)
diff --git a/tests/expected.log b/tests/expected.log
@@ -6,6 +6,17 @@ keys/one:
test
keys/one2:
test2
+[
+{
+ "path": "keys/one",
+ "name": "test"
+}
+,
+{
+ "path": "keys/one2",
+ "name": "test2"
+}
+]
HOOK RAN
keys/one
@@ -24,6 +35,11 @@ keys2/three
test2
test3
test4
+dump data to stdout as plaintext? (y/N) [
+{
+ "name": "test3\ntest4"
+}
+]
HOOK RAN
test
@@ -36,3 +52,5 @@ remove entry? (y/N) HOOK RAN
unable to decrypt (decrypt not ok)
rekeying: /keys/one2.lb
test2
+[
+]
diff --git a/tests/run.sh b/tests/run.sh
@@ -37,6 +37,7 @@ _run() {
echo "test" | "$BIN/lb" insert keys/one
echo "test2" | "$BIN/lb" insert keys/one2
"$BIN/lb" show keys/*
+ "$BIN/lb" dump -yes 'keys/*'
echo -e "test3\ntest4" | "$BIN/lb" insert keys2/three
"$BIN/lb" ls
"$BIN/lb-pwgen" -special -length 10
@@ -47,6 +48,7 @@ _run() {
"$BIN/lb" find e
"$BIN/lb" show keys/one2
"$BIN/lb" show keys2/three
+ echo "y" | "$BIN/lb" dump keys2/three
echo "5ae472abqdekjqykoyxk7hvc2leklq5n" | "$BIN/lb" insert totp/test
"$BIN/lb-totp" -ls
"$BIN/lb-totp" test | tr '[:digit:]' 'X'
@@ -58,6 +60,7 @@ _run() {
LOCKBOX_KEY="invalid" "$BIN/lb" show keys/one2
"$BIN/lb-rekey" -outkey "test" -outmode "plaintext"
"$BIN/lb-rw" -file bin/lb/keys/one2.lb -key "test" -keymode "plaintext" -mode "decrypt"
+ echo "y" | "$BIN/lb" dump -yes "*"
}
LOG=$TESTS/lb.log