commit a153cb24ab6bdca9d949fefbacdcae4467fc63d0
parent d84bc870a1f56c347517d8e57247f1b9daf44a1d
Author: Sean Enck <sean@ttypty.com>
Date: Sat, 4 Mar 2023 07:04:57 -0500
require insert -totp for inserting totp tokens
Diffstat:
6 files changed, 86 insertions(+), 41 deletions(-)
diff --git a/cmd/main.go b/cmd/main.go
@@ -79,12 +79,13 @@ func run() error {
return app.Move(t, sub, confirm)
case cli.InsertCommand:
insert := app.InsertOptions{}
+ parser := app.InsertArgsOptions{}
+ parser.IsNoTOTP = inputs.IsNoTOTP
+ parser.TOTPToken = inputs.TOTPToken
insert.Confirm = confirm
insert.IsPipe = inputs.IsInputFromPipe
- insert.IsNoTOTP = inputs.IsNoTOTP
- insert.TOTPToken = inputs.TOTPToken
insert.Input = inputs.GetUserInputPassword
- insertArgs, err := app.ParseInsertArgs(insert, sub)
+ insertArgs, err := parser.ReadArgs(insert, sub)
if err != nil {
return err
}
diff --git a/internal/app/core.go b/internal/app/core.go
@@ -4,19 +4,4 @@ package app
type (
// Confirm user inputs
Confirm func(string) bool
- // InsertOptions are functions required for insert
- InsertOptions struct {
- IsNoTOTP func() (bool, error)
- IsPipe func() bool
- TOTPToken func() string
- Input func(bool, bool) ([]byte, error)
- Confirm Confirm
- }
- // InsertArgs are parsed insert settings for insert commands
- InsertArgs struct {
- Entry string
- Multi bool
- TOTP bool
- Opts InsertOptions
- }
)
diff --git a/internal/app/insert.go b/internal/app/insert.go
@@ -12,15 +12,39 @@ import (
"github.com/enckse/lockbox/internal/totp"
)
+type (
+ // InsertOptions are functions required for insert
+ InsertOptions struct {
+ IsPipe func() bool
+ Input func(bool, bool) ([]byte, error)
+ Confirm Confirm
+ }
+ // InsertArgsOptions supports cli arg parsing
+ InsertArgsOptions struct {
+ TOTPToken func() string
+ IsNoTOTP func() (bool, error)
+ }
+ // InsertArgs are parsed insert settings for insert commands
+ InsertArgs struct {
+ Entry string
+ Multi bool
+ Opts InsertOptions
+ }
+)
+
func insertError(message string, err error) error {
return fmt.Errorf("%s (%w)", message, err)
}
-// ParseInsertArgs will parse the input args for insert commands
-func ParseInsertArgs(cmd InsertOptions, args []string) (InsertArgs, error) {
+// ReadArgs will read and check insert args
+func (p InsertArgsOptions) ReadArgs(cmd InsertOptions, args []string) (InsertArgs, error) {
multi := false
isTOTP := false
idx := 0
+ noTOTP, err := p.IsNoTOTP()
+ if err != nil {
+ return InsertArgs{}, err
+ }
switch len(args) {
case 0:
return InsertArgs{}, errors.New("insert requires an entry")
@@ -31,33 +55,37 @@ func ParseInsertArgs(cmd InsertOptions, args []string) (InsertArgs, error) {
case cli.InsertMultiCommand:
multi = true
case cli.InsertTOTPCommand:
- off, err := cmd.IsNoTOTP()
- if err != nil {
- return InsertArgs{}, err
- }
- if off {
+ if noTOTP {
return InsertArgs{}, totp.ErrNoTOTP
}
isTOTP = true
default:
return InsertArgs{}, errors.New("unknown argument")
}
- multi = true
idx = 1
default:
return InsertArgs{}, errors.New("too many arguments")
}
- return InsertArgs{Opts: cmd, Multi: multi, TOTP: isTOTP, Entry: args[idx]}, nil
+ entry := args[idx]
+ if !noTOTP {
+ totpToken := p.TOTPToken()
+ hasSuffixTOTP := strings.HasSuffix(entry, backend.NewSuffix(totpToken))
+ if isTOTP {
+ if !hasSuffixTOTP {
+ entry = backend.NewPath(entry, totpToken)
+ }
+ } else {
+ if hasSuffixTOTP {
+ return InsertArgs{}, errors.New("can not insert totp entry without totp flag")
+ }
+ }
+
+ }
+ return InsertArgs{Opts: cmd, Multi: multi, Entry: entry}, nil
}
// Do will execute an insert
func (args InsertArgs) Do(w io.Writer, t *backend.Transaction) error {
- if args.TOTP {
- totpToken := args.Opts.TOTPToken()
- if !strings.HasSuffix(args.Entry, backend.NewSuffix(totpToken)) {
- args.Entry = backend.NewPath(args.Entry, totpToken)
- }
- }
existing, err := t.Get(args.Entry, backend.BlankValue)
if err != nil {
return insertError("unable to check for existing entry", err)
diff --git a/internal/app/insert_test.go b/internal/app/insert_test.go
@@ -11,29 +11,63 @@ import (
func TestInsertArgs(t *testing.T) {
obj := app.InsertOptions{}
- if _, err := app.ParseInsertArgs(obj, []string{}); err == nil || err.Error() != "insert requires an entry" {
+ p := app.InsertArgsOptions{}
+ p.IsNoTOTP = func() (bool, error) {
+ return true, nil
+ }
+ if _, err := p.ReadArgs(obj, []string{}); err == nil || err.Error() != "insert requires an entry" {
t.Errorf("invalid error: %v", err)
}
- if _, err := app.ParseInsertArgs(obj, []string{"test", "test", "test"}); err == nil || err.Error() != "too many arguments" {
+ if _, err := p.ReadArgs(obj, []string{"test", "test", "test"}); err == nil || err.Error() != "too many arguments" {
t.Errorf("invalid error: %v", err)
}
- r, err := app.ParseInsertArgs(obj, []string{"test"})
+ r, err := p.ReadArgs(obj, []string{"test"})
if err != nil {
t.Errorf("invalid error: %v", err)
}
if r.Multi || r.Entry != "test" {
t.Error("invalid parse")
}
- if _, err := app.ParseInsertArgs(obj, []string{"-t", "b"}); err == nil || err.Error() != "unknown argument" {
+ if _, err := p.ReadArgs(obj, []string{"-t", "b"}); err == nil || err.Error() != "unknown argument" {
t.Errorf("invalid error: %v", err)
}
- r, err = app.ParseInsertArgs(obj, []string{"-multi", "test3"})
+ r, err = p.ReadArgs(obj, []string{"-multi", "test3"})
if err != nil {
t.Errorf("invalid error: %v", err)
}
if !r.Multi || r.Entry != "test3" {
t.Error("invalid parse")
}
+ p.TOTPToken = func() string {
+ return "test3"
+ }
+ r, err = p.ReadArgs(obj, []string{"-multi", "test/test3"})
+ if err != nil {
+ t.Errorf("invalid error: %v", err)
+ }
+ p.IsNoTOTP = func() (bool, error) {
+ return false, nil
+ }
+ if _, err := p.ReadArgs(obj, []string{"-multi", "test/test3"}); err == nil || err.Error() != "can not insert totp entry without totp flag" {
+ t.Errorf("invalid error: %v", err)
+ }
+ if _, err := p.ReadArgs(obj, []string{"test/test3"}); err == nil || err.Error() != "can not insert totp entry without totp flag" {
+ t.Errorf("invalid error: %v", err)
+ }
+ r, err = p.ReadArgs(obj, []string{"-totp", "test/test3"})
+ if err != nil {
+ t.Errorf("invalid error: %v", err)
+ }
+ if r.Entry != "test/test3" {
+ t.Error("invalid parse")
+ }
+ r, err = p.ReadArgs(obj, []string{"-totp", "test"})
+ if err != nil {
+ t.Errorf("invalid error: %v", err)
+ }
+ if r.Entry != "test/test3" {
+ t.Error("invalid parse")
+ }
}
func TestInsertDo(t *testing.T) {
diff --git a/scripts/testing/check.go b/scripts/testing/check.go
@@ -153,8 +153,6 @@ func execute() error {
runCommand([]string{"insert", "-totp", k}, []string{"5ae472abqdekjqykoyxk7hvc2leklq5n"})
}
totpList()
- insert("test/k/totp", []string{"5ae472abqdekjqykoyxk7hvc2leklq5n"})
- totpList()
runCommand([]string{"totp", "test/k"}, nil)
runCommand([]string{"hash", store}, nil)
rm("keys2/k/three")
diff --git a/scripts/testing/expected.log b/scripts/testing/expected.log
@@ -20,7 +20,6 @@ test3
test4
modtime: XXXX-XX-XX
test/k
-test/k
XXXXXX
key/a/one:
modtime: XXXX-XX-XX