lockbox

password manager
Log | Files | Refs | README | LICENSE

commit b127accafdcdd13d580c68415f5610fbcbd4e16d
parent 9642f556697e9ac56800d0685c2ff1cee6daf28a
Author: Sean Enck <sean@ttypty.com>
Date:   Sun, 11 Aug 2024 14:04:26 -0400

define a struct of JSON types for output modes and rekey flags

Diffstat:
Minternal/app/core.go | 4++--
Minternal/backend/query.go | 8++++----
Minternal/config/core.go | 23+++++++++++++++++------
Minternal/config/vars.go | 45++++++++++++++++++++++++---------------------
Minternal/config/vars_test.go | 8++++----
5 files changed, 51 insertions(+), 37 deletions(-)

diff --git a/internal/app/core.go b/internal/app/core.go @@ -238,8 +238,8 @@ func Usage(verbose bool, exe string) ([]string, error) { CompletionsCommand: CompletionsCommand, CompletionsEnv: config.EnvDefaultCompletionKey, } - document.ReKey.KeyFile = setDocFlag(config.ReKeyKeyFileFlag) - document.ReKey.NoKey = config.ReKeyNoKeyFlag + document.ReKey.KeyFile = setDocFlag(config.ReKeyFlags.KeyFile) + document.ReKey.NoKey = config.ReKeyFlags.NoKey files, err := docs.ReadDir(docDir) if err != nil { return nil, err diff --git a/internal/backend/query.go b/internal/backend/query.go @@ -159,7 +159,7 @@ func (t *Transaction) QueryCallback(args QueryOptions) ([]QueryEntity, error) { if isSort { sort.Strings(keys) } - jsonMode := config.JSONDataOutputBlank + jsonMode := config.JSONOutputs.Blank if args.Values == JSONValue { m, err := config.ParseJSONOutput() if err != nil { @@ -168,7 +168,7 @@ func (t *Transaction) QueryCallback(args QueryOptions) ([]QueryEntity, error) { jsonMode = m } var hashLength int - if jsonMode == config.JSONDataOutputHash { + if jsonMode == config.JSONOutputs.Hash { hashLength, err = config.EnvHashLength.Get() if err != nil { return nil, err @@ -190,9 +190,9 @@ func (t *Transaction) QueryCallback(args QueryOptions) ([]QueryEntity, error) { case JSONValue: data := "" switch jsonMode { - case config.JSONDataOutputRaw: + case config.JSONOutputs.Raw: data = val - case config.JSONDataOutputHash: + case config.JSONOutputs.Hash: data = fmt.Sprintf("%x", sha512.Sum512([]byte(val))) if hashLength > 0 && len(data) > hashLength { data = data[0:hashLength] diff --git a/internal/config/core.go b/internal/config/core.go @@ -26,10 +26,6 @@ const ( noEnvironment = "none" envFile = "lockbox.env" unknownPlatform = "" - // ReKeyKeyFileFlag is the flag used for rekey to set the keyfile - ReKeyKeyFileFlag = "keyfile" - // ReKeyNoKeyFlag indicates no key is used for rekeying (e.g. keyfile only) - ReKeyNoKeyFlag = "nokey" // sub categories clipCategory keyCategory = "CLIP_" totpCategory keyCategory = "TOTP_" @@ -116,6 +112,12 @@ type ( LinuxXPlatform SystemPlatform WindowsLinuxPlatform SystemPlatform } + // JSONOutputTypes indicate how JSON data can be exported for values + JSONOutputTypes struct { + Hash JSONOutputMode + Blank JSONOutputMode + Raw JSONOutputMode + } ) func shlex(in string) ([]string, error) { @@ -486,12 +488,21 @@ func environmentRegister[T printer](obj T) T { return obj } -// List will get the displayable list of platforms +// List will list the platform types on the struct func (p PlatformTypes) List() []string { + return listFields[SystemPlatform](p) +} + +// List will list the output modes on the struct +func (p JSONOutputTypes) List() []string { + return listFields[JSONOutputMode](p) +} + +func listFields[T SystemPlatform | JSONOutputMode](p any) []string { v := reflect.ValueOf(p) var vals []string for i := 0; i < v.NumField(); i++ { - vals = append(vals, string(v.Field(i).Interface().(SystemPlatform))) + vals = append(vals, fmt.Sprintf("%v", v.Field(i).Interface().(T))) } sort.Strings(vals) return vals diff --git a/internal/config/vars.go b/internal/config/vars.go @@ -23,12 +23,8 @@ const ( noClipProfile = "noclip" // ModTimeFormat is the expected modtime format ModTimeFormat = time.RFC3339 - // JSONDataOutputHash means output data is hashed - JSONDataOutputHash JSONOutputMode = "hash" - // JSONDataOutputBlank means an empty entry is set - JSONDataOutputBlank JSONOutputMode = "empty" - // JSONDataOutputRaw means the RAW (unencrypted) value is displayed - JSONDataOutputRaw JSONOutputMode = "plaintext" + /* + */ ) var ( @@ -39,6 +35,17 @@ var ( LinuxXPlatform: "linux-x", WindowsLinuxPlatform: "wsl", } + // ReKeyFlags are the CLI argument flags for rekey handling + ReKeyFlags = struct { + KeyFile string + NoKey string + }{"keyfile", "nokey"} + // JSONOutputs are the JSON data output types for exporting/output of values + JSONOutputs = JSONOutputTypes{ + Hash: "hash", + Blank: "empty", + Raw: "plaintext", + } // TOTPDefaultColorWindow is the default coloring rules for totp TOTPDefaultColorWindow = []ColorWindow{{Start: 0, End: 5}, {Start: 30, End: 35}} // TOTPDefaultBetween is the default color window as a string @@ -67,7 +74,7 @@ var ( environmentDefault: newDefaultedEnvironment(0, environmentBase{ subKey: EnvJSONDataOutput.subKey + "_HASH_LENGTH", - desc: fmt.Sprintf("Maximum hash string length the JSON output should contain when '%s' mode is set for JSON output.", JSONDataOutputHash), + desc: fmt.Sprintf("Maximum hash string length the JSON output should contain when '%s' mode is set for JSON output.", JSONOutputs.Hash), }), shortDesc: "hash length", allowZero: true, @@ -254,13 +261,13 @@ and '%s' allows for multiple windows.`, colorWindowSpan, colorWindowDelimiter), // EnvJSONDataOutput controls how JSON is output in the 'data' field EnvJSONDataOutput = environmentRegister( EnvironmentString{ - environmentDefault: newDefaultedEnvironment(string(JSONDataOutputHash), + environmentDefault: newDefaultedEnvironment(string(JSONOutputs.Hash), environmentBase{ subKey: "JSON_DATA", - desc: fmt.Sprintf("Changes what the data field in JSON outputs will contain.\n\nUse '%s' with CAUTION.", JSONDataOutputRaw), + desc: fmt.Sprintf("Changes what the data field in JSON outputs will contain.\n\nUse '%s' with CAUTION.", JSONOutputs.Raw), }), canDefault: true, - allowed: []string{string(JSONDataOutputRaw), string(JSONDataOutputHash), string(JSONDataOutputBlank)}, + allowed: JSONOutputs.List(), }) // EnvFormatTOTP supports formatting the TOTP tokens for generation of tokens EnvFormatTOTP = environmentRegister(EnvironmentFormatter{environmentBase: environmentBase{ @@ -325,8 +332,8 @@ This value can NOT be an expansion itself.`, // GetReKey will get the rekey environment settings func GetReKey(args []string) (ReKeyArgs, error) { set := flag.NewFlagSet("rekey", flag.ExitOnError) - keyFile := set.String(ReKeyKeyFileFlag, "", "new keyfile") - noKey := set.Bool(ReKeyNoKeyFlag, false, "disable password/key credential") + keyFile := set.String(ReKeyFlags.KeyFile, "", "new keyfile") + noKey := set.Bool(ReKeyFlags.NoKey, false, "disable password/key credential") if err := set.Parse(args); err != nil { return ReKeyArgs{}, err } @@ -389,16 +396,12 @@ func formatterTOTP(key, value string) string { // ParseJSONOutput handles detecting the JSON output mode func ParseJSONOutput() (JSONOutputMode, error) { - val := strings.ToLower(strings.TrimSpace(EnvJSONDataOutput.Get())) - switch JSONOutputMode(val) { - case JSONDataOutputHash: - return JSONDataOutputHash, nil - case JSONDataOutputBlank: - return JSONDataOutputBlank, nil - case JSONDataOutputRaw: - return JSONDataOutputRaw, nil + val := JSONOutputMode(strings.ToLower(strings.TrimSpace(EnvJSONDataOutput.Get()))) + switch val { + case JSONOutputs.Hash, JSONOutputs.Blank, JSONOutputs.Raw: + return val, nil } - return JSONDataOutputBlank, fmt.Errorf("invalid JSON output mode: %s", val) + return JSONOutputs.Blank, fmt.Errorf("invalid JSON output mode: %s", val) } func exportProfileKeyValue(e environmentBase, val string) string { diff --git a/internal/config/vars_test.go b/internal/config/vars_test.go @@ -146,22 +146,22 @@ func TestFormatTOTP(t *testing.T) { func TestParseJSONMode(t *testing.T) { defer os.Clearenv() m, err := config.ParseJSONOutput() - if m != config.JSONDataOutputHash || err != nil { + if m != config.JSONOutputs.Hash || err != nil { t.Error("invalid mode read") } os.Setenv("LOCKBOX_JSON_DATA", "hAsH ") m, err = config.ParseJSONOutput() - if m != config.JSONDataOutputHash || err != nil { + if m != config.JSONOutputs.Hash || err != nil { t.Error("invalid mode read") } os.Setenv("LOCKBOX_JSON_DATA", "EMPTY") m, err = config.ParseJSONOutput() - if m != config.JSONDataOutputBlank || err != nil { + if m != config.JSONOutputs.Blank || err != nil { t.Error("invalid mode read") } os.Setenv("LOCKBOX_JSON_DATA", " PLAINtext ") m, err = config.ParseJSONOutput() - if m != config.JSONDataOutputRaw || err != nil { + if m != config.JSONOutputs.Raw || err != nil { t.Error("invalid mode read") } os.Setenv("LOCKBOX_JSON_DATA", "a")