commit e071ba30f6128511b86ee2a99ba66ad6ae0a06db
parent 25faededdb01bc44a02df10d363a6bfb699e214e
Author: Sean Enck <sean@ttypty.com>
Date: Mon, 9 Jun 2025 14:51:33 -0400
deprecate ask mode
Diffstat:
10 files changed, 22 insertions(+), 155 deletions(-)
diff --git a/cmd/lb/main_test.go b/cmd/lb/main_test.go
@@ -179,15 +179,6 @@ func test(profile string) error {
}
r.writeConfig(c)
r.run("echo testing |", "insert test1/key1/password")
- if hasPass {
- delete(c, "credentials.password")
- c["interactive"] = "true"
- c["credentials.password_mode"] = c.quoteString("ask")
- r.writeConfig(c)
- } else {
- r.logAppend("printf \"password: \"")
- }
- r.raw(fmt.Sprintf("echo %s |", testPass), "ls", r.log, "/dev/null")
c = r.newConf()
c["interactive"] = "false"
if hasPass {
diff --git a/cmd/lb/tests/expected.log b/cmd/lb/tests/expected.log
@@ -1,4 +1,3 @@
-password: test1/key1/password
'test3' is not an allowed field name
'' is not an allowed field name
'still' is not an allowed field name
diff --git a/internal/app/completions/core.go b/internal/app/completions/core.go
@@ -45,7 +45,6 @@ type (
ReadOnly string
CanClip string
CanTOTP string
- AskMode string
Ever string
}
Exported []string
@@ -89,7 +88,6 @@ func NewConditionals() Conditionals {
c.Not.ReadOnly = registerIsNotEqual(config.EnvReadOnly, config.YesValue)
c.Not.CanClip = registerIsNotEqual(config.EnvClipEnabled, config.NoValue)
c.Not.CanTOTP = registerIsNotEqual(config.EnvTOTPEnabled, config.NoValue)
- c.Not.AskMode = registerIsNotEqual(config.EnvPasswordMode, string(config.AskKeyMode))
c.Not.Ever = fmt.Sprintf(shellIsNotText, "1", "0")
return c
}
diff --git a/internal/app/completions/core_test.go b/internal/app/completions/core_test.go
@@ -23,7 +23,7 @@ func TestCompletions(t *testing.T) {
func TestConditionals(t *testing.T) {
c := completions.NewConditionals()
sort.Strings(c.Exported)
- need := []string{"LOCKBOX_CLIP_ENABLED", "LOCKBOX_CREDENTIALS_PASSWORD_MODE", "LOCKBOX_READONLY", "LOCKBOX_TOTP_ENABLED"}
+ need := []string{"LOCKBOX_CLIP_ENABLED", "LOCKBOX_READONLY", "LOCKBOX_TOTP_ENABLED"}
if len(c.Exported) != len(need) || fmt.Sprintf("%v", c.Exported) != fmt.Sprintf("%v", need) {
t.Errorf("invalid exports: %v", c.Exported)
}
@@ -36,8 +36,6 @@ func TestConditionals(t *testing.T) {
switch n {
case "LOCKBOX_READONLY":
value = "true"
- case "LOCKBOX_CREDENTIALS_PASSWORD_MODE":
- value = "ask"
}
if !slices.Contains(fields, fmt.Sprintf(`[ "$%s" != "%s" ]`, n, value)) {
t.Errorf("needed conditional %s not found: %v", n, fields)
diff --git a/internal/app/completions/shell/bash.sh b/internal/app/completions/shell/bash.sh
@@ -34,14 +34,10 @@ _{{ $.Executable }}() {
opts="{{ $.HelpAdvancedCommand }} {{ $.HelpConfigCommand }}"
;;
"{{ $.MoveCommand }}" | "{{ $.RemoveCommand }}" | "{{ $.InsertCommand }}")
- if {{ $.Conditionals.Not.AskMode }}; then
- opts="$opts $({{ $.DoGroups }})"
- fi
+ opts="$opts $({{ $.DoGroups }})"
;;
"{{ $.UnsetCommand }}")
- if {{ $.Conditionals.Not.AskMode }}; then
- opts="$opts $({{ $.DoList }})"
- fi
+ opts="$opts $({{ $.DoList }})"
;;
"{{ $.TOTPCommand }}")
opts="{{ $.TOTPListCommand }} "
@@ -52,27 +48,21 @@ _{{ $.Executable }}() {
{{- end}}
;;
"{{ $.ShowCommand }}" | "{{ $.JSONCommand }}" | "{{ $.ClipCommand }}")
- if {{ $.Conditionals.Not.AskMode }}; then
- opts=$({{ $.DoList }})
- fi
+ opts=$({{ $.DoList }})
;;
esac
else
if [ "$COMP_CWORD" -eq 3 ]; then
case "$chosen" in
"{{ $.MoveCommand }}")
- if {{ $.Conditionals.Not.AskMode }}; then
- opts=$({{ $.DoGroups }})
- fi
+ opts=$({{ $.DoGroups }})
;;
"{{ $.TOTPCommand }}")
case "${COMP_WORDS[2]}" in
{{- range $key, $value := $.TOTPSubCommands }}
"{{ $value.Key }}")
if {{ $value.Conditional }}; then
- if {{ $.Conditionals.Not.AskMode }}; then
- opts=$({{ $.DoTOTPList }})
- fi
+ opts=$({{ $.DoTOTPList }})
fi
;;
{{- end}}
diff --git a/internal/app/completions/shell/zsh.sh b/internal/app/completions/shell/zsh.sh
@@ -47,24 +47,18 @@ _{{ $.Executable }}() {
;;
"{{ $.RemoveCommand }}" | "{{ $.InsertCommand }}")
if [ "$len" -eq 3 ]; then
- if {{ $.Conditionals.Not.AskMode }}; then
- compadd "$@" $({{ $.DoGroups }})
- fi
+ compadd "$@" $({{ $.DoGroups }})
fi
;;
"{{ $.UnsetCommand }}")
if [ "$len" -eq 3 ]; then
- if {{ $.Conditionals.Not.AskMode }}; then
- compadd "$@" $({{ $.DoList }})
- fi
+ compadd "$@" $({{ $.DoList }})
fi
;;
"{{ $.MoveCommand }}")
case "$len" in
3 | 4)
- if {{ $.Conditionals.Not.AskMode }}; then
- compadd "$@" $({{ $.DoGroups }})
- fi
+ compadd "$@" $({{ $.DoGroups }})
;;
esac
;;
@@ -83,9 +77,7 @@ _{{ $.Executable }}() {
{{- range $key, $value := .TOTPSubCommands }}
"{{ $value.Key }}")
if {{ $value.Conditional }}; then
- if {{ $.Conditionals.Not.AskMode }}; then
- compadd "$@" $({{ $.DoTOTPList }})
- fi
+ compadd "$@" $({{ $.DoTOTPList }})
fi
;;
{{- end}}
@@ -94,9 +86,7 @@ _{{ $.Executable }}() {
;;
"{{ $.ShowCommand }}" | "{{ $.JSONCommand }}" | "{{ $.ClipCommand }}")
if [ "$len" -eq 3 ]; then
- if {{ $.Conditionals.Not.AskMode }}; then
- compadd "$@" $({{ $.DoList }})
- fi
+ compadd "$@" $({{ $.DoList }})
fi
;;
esac
diff --git a/internal/config/key.go b/internal/config/key.go
@@ -11,8 +11,6 @@ import (
type (
// KeyModeType are valid ways to get the key
KeyModeType string
- // AskPassword is a function to prompt for passwords (when required)
- AskPassword func() (string, error)
// Key is a wrapper to help manage the returned key
Key struct {
mode KeyModeType
@@ -23,9 +21,7 @@ type (
const (
plainKeyMode KeyModeType = "plaintext"
- // AskKeyMode is the mode in which the user is prompted for key input (each time)
- AskKeyMode KeyModeType = "ask"
- noKeyMode KeyModeType = "none"
+ noKeyMode KeyModeType = "none"
// IgnoreKeyMode will ignore the value set in the key (acts like no key)
IgnoreKeyMode KeyModeType = "ignore"
commandKeyMode KeyModeType = "command"
@@ -46,12 +42,6 @@ func NewKey(defaultKeyModeType KeyModeType) (Key, error) {
case string(noKeyMode):
requireEmptyKey = true
case string(commandKeyMode), string(plainKeyMode):
- case string(AskKeyMode):
- isInteractive := EnvInteractive.Get()
- if !isInteractive {
- return Key{}, errors.New("ask key mode requested in non-interactive mode")
- }
- requireEmptyKey = true
default:
return Key{}, fmt.Errorf("unknown key mode: %s", keyMode)
}
@@ -78,20 +68,12 @@ func (k Key) empty() bool {
return k.valid && len(k.inputKey) == 0
}
-// Ask will indicate if prompting is required to get the key
-func (k Key) Ask() bool {
- return k.valid && k.mode == AskKeyMode
-}
-
// Read will read the key as configured by the mode
-func (k Key) Read(ask AskPassword) (string, error) {
- if ask == nil {
- return "", errors.New("invalid function given")
- }
+func (k Key) Read() (string, error) {
if !k.valid {
return "", errors.New("invalid key given")
}
- if k.empty() && !k.Ask() {
+ if k.empty() {
return "", nil
}
var useKey string
@@ -99,12 +81,6 @@ func (k Key) Read(ask AskPassword) (string, error) {
useKey = k.inputKey[0]
}
switch k.mode {
- case AskKeyMode:
- read, err := ask()
- if err != nil {
- return "", err
- }
- useKey = read
case commandKeyMode:
exe := k.inputKey[0]
var args []string
diff --git a/internal/config/key_test.go b/internal/config/key_test.go
@@ -1,7 +1,6 @@
package config_test
import (
- "errors"
"strings"
"testing"
@@ -32,11 +31,6 @@ func TestNewKeyErrors(t *testing.T) {
if _, err := config.NewKey(config.IgnoreKeyMode); err == nil || err.Error() != "key can NOT be set in this key mode" {
t.Errorf("invalid error: %v", err)
}
- store.SetString("LOCKBOX_CREDENTIALS_PASSWORD_MODE", "ask")
- store.SetArray("LOCKBOX_CREDENTIALS_PASSWORD", []string{"test"})
- if _, err := config.NewKey(config.IgnoreKeyMode); err == nil || err.Error() != "key can NOT be set in this key mode" {
- t.Errorf("invalid error: %v", err)
- }
store.SetString("LOCKBOX_CREDENTIALS_PASSWORD_MODE", "command")
store.SetArray("LOCKBOX_CREDENTIALS_PASSWORD", []string{})
if _, err := config.NewKey(config.IgnoreKeyMode); err == nil || err.Error() != "key MUST be set in this key mode" {
@@ -47,59 +41,6 @@ func TestNewKeyErrors(t *testing.T) {
if _, err := config.NewKey(config.IgnoreKeyMode); err == nil || err.Error() != "key MUST be set in this key mode" {
t.Errorf("invalid error: %v", err)
}
- store.SetBool("LOCKBOX_INTERACTIVE", true)
- store.SetString("LOCKBOX_CREDENTIALS_PASSWORD_MODE", "ask")
- store.SetArray("LOCKBOX_CREDENTIALS_PASSWORD", []string{})
- if _, err := config.NewKey(config.IgnoreKeyMode); err != nil {
- t.Errorf("invalid error: %v", err)
- }
- store.SetBool("LOCKBOX_INTERACTIVE", false)
- if _, err := config.NewKey(config.IgnoreKeyMode); err == nil || err.Error() != "ask key mode requested in non-interactive mode" {
- t.Errorf("invalid error: %v", err)
- }
-}
-
-func TestAskKey(t *testing.T) {
- store.Clear()
- store.SetArray("LOCKBOX_CREDENTIALS_PASSWORD", []string{"test"})
- k, _ := config.NewKey(config.IgnoreKeyMode)
- if k.Ask() {
- t.Error("invalid ask key")
- }
- store.SetString("LOCKBOX_CREDENTIALS_PASSWORD_MODE", "ask")
- store.SetArray("LOCKBOX_CREDENTIALS_PASSWORD", []string{})
- store.SetBool("LOCKBOX_INTERACTIVE", false)
- k, _ = config.NewKey(config.IgnoreKeyMode)
- if k.Ask() {
- t.Error("invalid ask key")
- }
- store.SetString("LOCKBOX_CREDENTIALS_PASSWORD_MODE", "ask")
- store.SetBool("LOCKBOX_INTERACTIVE", true)
- k, _ = config.NewKey(config.IgnoreKeyMode)
- if !k.Ask() {
- t.Error("invalid ask key")
- }
- fxn := func() (string, error) {
- return "", errors.New("TEST")
- }
- _, err := k.Read(fxn)
- if err == nil || err.Error() != "TEST" {
- t.Errorf("invalid error: %v", err)
- }
- fxn = func() (string, error) {
- return "", nil
- }
- _, err = k.Read(fxn)
- if err == nil || err.Error() != "key is empty" {
- t.Errorf("invalid error: %v", err)
- }
- fxn = func() (string, error) {
- return "abc", nil
- }
- val, err := k.Read(fxn)
- if err != nil || val != "abc" {
- t.Errorf("invalid error: %v", err)
- }
}
func TestIgnoreKey(t *testing.T) {
@@ -119,13 +60,7 @@ func TestIgnoreKey(t *testing.T) {
func TestReadErrors(t *testing.T) {
store.Clear()
k := config.Key{}
- if _, err := k.Read(nil); err == nil || err.Error() != "invalid function given" {
- t.Errorf("invalid error: %v", err)
- }
- fxn := func() (string, error) {
- return "", nil
- }
- if _, err := k.Read(fxn); err == nil || err.Error() != "invalid key given" {
+ if _, err := k.Read(); err == nil || err.Error() != "invalid key given" {
t.Errorf("invalid error: %v", err)
}
}
@@ -138,10 +73,7 @@ func TestPlainKey(t *testing.T) {
if err != nil {
t.Errorf("invalid error: %v", err)
}
- fxn := func() (string, error) {
- return "", nil
- }
- val, err := k.Read(fxn)
+ val, err := k.Read()
if err != nil || val != "test" {
t.Errorf("invalid error: %v", err)
}
@@ -155,10 +87,7 @@ func TestReadIgnoreOrNoKey(t *testing.T) {
if err != nil {
t.Errorf("invalid error: %v", err)
}
- fxn := func() (string, error) {
- return "", nil
- }
- val, err := k.Read(fxn)
+ val, err := k.Read()
if err != nil || val != "" {
t.Errorf("invalid error: %v", err)
}
@@ -168,7 +97,7 @@ func TestReadIgnoreOrNoKey(t *testing.T) {
if err != nil {
t.Errorf("invalid error: %v", err)
}
- val, err = k.Read(fxn)
+ val, err = k.Read()
if err != nil || val != "" {
t.Errorf("invalid error: %v", err)
}
@@ -177,7 +106,7 @@ func TestReadIgnoreOrNoKey(t *testing.T) {
if err != nil {
t.Errorf("invalid error: %v", err)
}
- val, err = k.Read(fxn)
+ val, err = k.Read()
if err != nil || val != "" {
t.Errorf("invalid error: %v", err)
}
@@ -191,10 +120,7 @@ func TestCommandKey(t *testing.T) {
if err != nil {
t.Errorf("invalid error: %v", err)
}
- fxn := func() (string, error) {
- return "", nil
- }
- _, err = k.Read(fxn)
+ _, err = k.Read()
if err == nil || !strings.HasPrefix(err.Error(), "key command failed:") {
t.Errorf("invalid error: %v", err)
}
diff --git a/internal/config/vars.go b/internal/config/vars.go
@@ -199,7 +199,7 @@ must be a list of one (or more) rules where a '%s' delimits the start and end se
description: fmt.Sprintf(`How to retrieve the database store password. Set to '%s' when only using a key file.
Set to '%s' to ignore the set key value`, noKeyMode, IgnoreKeyMode),
}),
- allowed: []string{string(AskKeyMode), string(commandKeyMode), string(IgnoreKeyMode), string(noKeyMode), string(plainKeyMode)},
+ allowed: []string{string(commandKeyMode), string(IgnoreKeyMode), string(noKeyMode), string(plainKeyMode)},
flags: []stringsFlags{canDefaultFlag},
},
})
diff --git a/internal/kdbx/actions.go b/internal/kdbx/actions.go
@@ -9,7 +9,6 @@ import (
"time"
"git.sr.ht/~enckse/lockbox/internal/config"
- "git.sr.ht/~enckse/lockbox/internal/platform"
"github.com/tobischo/gokeepasslib/v3"
)
@@ -25,7 +24,7 @@ func (t *Transaction) act(cb action) error {
if err != nil {
return err
}
- k, err := key.Read(platform.ReadInteractivePassword)
+ k, err := key.Read()
if err != nil {
return err
}