commit 802341a8fb8d398e72d847c910a2cbf296e28ed7
parent ce4291fca88b2fc4b58dbbb41dc2fe774f7f0b1f
Author: Sean Enck <sean@ttypty.com>
Date: Wed, 26 Jul 2023 20:24:18 -0400
formatter moved
Diffstat:
6 files changed, 43 insertions(+), 37 deletions(-)
diff --git a/internal/app/totp.go b/internal/app/totp.go
@@ -117,7 +117,7 @@ func (args *TOTPArguments) display(opts TOTPOptions) error {
return errors.New("object does not exist")
}
totpToken := string(entity.Value)
- k, err := coreotp.NewKeyFromURL(inputs.FormatTOTP(totpToken))
+ k, err := coreotp.NewKeyFromURL(inputs.EnvFormatTOTP.Get(totpToken))
if err != nil {
return err
}
diff --git a/internal/backend/actions.go b/internal/backend/actions.go
@@ -212,7 +212,7 @@ func (t *Transaction) Move(src QueryEntity, dst string) error {
if multi {
return errors.New("totp tokens can NOT be multi-line")
}
- otp := inputs.FormatTOTP(v)
+ otp := inputs.EnvFormatTOTP.Get(v)
e.Values = append(e.Values, protectedValue("otp", otp))
}
e.Values = append(e.Values, protectedValue(field, v))
diff --git a/internal/inputs/env.go b/internal/inputs/env.go
@@ -56,6 +56,11 @@ type (
EnvironmentCommand struct {
environmentBase
}
+ // EnvironmentFormatter allows for sending a string into a get request
+ EnvironmentFormatter struct {
+ environmentBase
+ fxn func(string, string) string
+ }
)
func shlex(in string) ([]string, error) {
@@ -72,8 +77,7 @@ func PlatformSet() []string {
}
}
-// EnvironOrDefault will get the environment value OR default if env is not set.
-func EnvironOrDefault(envKey, defaultValue string) string {
+func environOrDefault(envKey, defaultValue string) string {
val := os.Getenv(envKey)
if strings.TrimSpace(val) == "" {
return defaultValue
@@ -129,12 +133,12 @@ func (e EnvironmentString) Get() string {
if !e.canDefault {
return os.Getenv(e.key)
}
- return EnvironOrDefault(e.key, e.defaultValue)
+ return environOrDefault(e.key, e.defaultValue)
}
// Get will read (and shlex) the value if set
func (e EnvironmentCommand) Get() ([]string, error) {
- value := EnvironOrDefault(e.key, "")
+ value := environOrDefault(e.key, "")
if strings.TrimSpace(value) == "" {
return nil, nil
}
@@ -150,3 +154,8 @@ func (e environmentBase) KeyValue(value string) string {
func (e environmentBase) Set(value string) {
os.Setenv(e.key, value)
}
+
+// Get will retrieve the value with the formatted input included
+func (e EnvironmentFormatter) Get(value string) string {
+ return e.fxn(e.key, value)
+}
diff --git a/internal/inputs/env_test.go b/internal/inputs/env_test.go
@@ -7,26 +7,24 @@ import (
"github.com/enckse/lockbox/internal/inputs"
)
-func TestEnvDefault(t *testing.T) {
- os.Clearenv()
- val := inputs.EnvironOrDefault("TEST", "value")
- if val != "value" {
- t.Error("invalid read")
- }
- os.Setenv("TEST", " ")
- val = inputs.EnvironOrDefault("TEST", "value")
- if val != "value" {
- t.Error("invalid read")
+func TestPlatformSet(t *testing.T) {
+ if len(inputs.PlatformSet()) != 4 {
+ t.Error("invalid platform set")
}
- os.Setenv("TEST", " a")
- val = inputs.EnvironOrDefault("TEST", "value")
- if val != " a" {
- t.Error("invalid read")
+}
+
+func TestSet(t *testing.T) {
+ os.Clearenv()
+ defer os.Clearenv()
+ inputs.EnvStore.Set("TEST")
+ if inputs.EnvStore.Get() != "TEST" {
+ t.Errorf("invalid set/get")
}
}
-func TestPlatformSet(t *testing.T) {
- if len(inputs.PlatformSet()) != 4 {
- t.Error("invalid platform set")
+func TestKeyValue(t *testing.T) {
+ val := inputs.EnvStore.KeyValue("TEST")
+ if val != "LOCKBOX_STORE=TEST" {
+ t.Errorf("invalid keyvalue")
}
}
diff --git a/internal/inputs/vars.go b/internal/inputs/vars.go
@@ -15,9 +15,7 @@ import (
const (
prefixKey = "LOCKBOX_"
- fieldTOTPEnv = prefixKey + "TOTP"
clipBaseEnv = prefixKey + "CLIP_"
- formatTOTPEnv = fieldTOTPEnv + "_FORMAT"
plainKeyMode = "plaintext"
commandKeyMode = "command"
defaultTOTPField = "totp"
@@ -51,9 +49,9 @@ var (
// EnvInteractive indicates if operating in interactive mode
EnvInteractive = EnvironmentBool{environmentBase: environmentBase{key: prefixKey + "INTERACTIVE"}, defaultValue: true}
// EnvMaxTOTP is the max TOTP time to run (default)
- EnvMaxTOTP = EnvironmentInt{environmentBase: environmentBase{key: fieldTOTPEnv + "_MAX"}, shortDesc: "max totp time", allowZero: false, defaultValue: 120}
+ EnvMaxTOTP = EnvironmentInt{environmentBase: environmentBase{key: EnvTOTPToken.key + "_MAX"}, shortDesc: "max totp time", allowZero: false, defaultValue: 120}
// EnvTOTPToken is the leaf token to use to store TOTP tokens
- EnvTOTPToken = EnvironmentString{environmentBase: environmentBase{key: fieldTOTPEnv}, canDefault: true, defaultValue: "totp"}
+ EnvTOTPToken = EnvironmentString{environmentBase: environmentBase{key: prefixKey + "TOTP"}, canDefault: true, defaultValue: "totp"}
// EnvPlatform is the platform that the application is running on
EnvPlatform = EnvironmentString{environmentBase: environmentBase{key: prefixKey + "PLATFORM"}, canDefault: false}
// EnvStore is the location of the keepass file/store
@@ -65,7 +63,7 @@ var (
// EnvClipPaste allows overriding the clipboard paste command
EnvClipPaste = EnvironmentCommand{environmentBase: environmentBase{key: clipBaseEnv + "PASTE"}}
// EnvColorBetween handles terminal coloring for TOTP windows (seconds)
- EnvColorBetween = EnvironmentString{environmentBase: environmentBase{key: fieldTOTPEnv + "_BETWEEN"}, canDefault: true, defaultValue: TOTPDefaultBetween}
+ EnvColorBetween = EnvironmentString{environmentBase: environmentBase{key: EnvTOTPToken.key + "_BETWEEN"}, canDefault: true, defaultValue: TOTPDefaultBetween}
// EnvKeyFile is an OPTIONAL keyfile for the database
EnvKeyFile = EnvironmentString{environmentBase: environmentBase{key: prefixKey + "KEYFILE"}, canDefault: true, defaultValue: ""}
envKeyMode = EnvironmentString{environmentBase: environmentBase{key: prefixKey + "KEYMODE"}, canDefault: true, defaultValue: commandKeyMode}
@@ -74,6 +72,8 @@ var (
EnvModTime = EnvironmentString{environmentBase: environmentBase{key: prefixKey + "SET_MODTIME"}, canDefault: true, defaultValue: ""}
// EnvJSONDataOutput controls how JSON is output in the 'data' field
EnvJSONDataOutput = EnvironmentString{environmentBase: environmentBase{key: prefixKey + "JSON_DATA_OUTPUT"}, canDefault: true, defaultValue: string(JSONDataOutputHash)}
+ // EnvFormatTOTP supports formatting the TOTP tokens for generation of tokens
+ EnvFormatTOTP = EnvironmentFormatter{environmentBase: environmentBase{key: EnvTOTPToken.key + "_FORMAT"}, fxn: formatterTOTP}
)
type (
@@ -179,8 +179,8 @@ func ListEnvironmentVariables(showValues bool) []string {
results = append(results, e.formatEnvironmentVariable(false, EnvNoColor.key, no, "disable terminal colors", isYesNoArgs))
results = append(results, e.formatEnvironmentVariable(false, EnvInteractive.key, yes, "enable interactive mode", isYesNoArgs))
results = append(results, e.formatEnvironmentVariable(false, EnvReadOnly.key, no, "operate in readonly mode", isYesNoArgs))
- results = append(results, e.formatEnvironmentVariable(false, fieldTOTPEnv, defaultTOTPField, "attribute name to store TOTP tokens within the database", []string{"string"}))
- results = append(results, e.formatEnvironmentVariable(false, formatTOTPEnv, strings.ReplaceAll(strings.ReplaceAll(FormatTOTP("%s"), "%25s", "%s"), "&", " \\\n &"), "override the otpauth url used to store totp tokens. It must have ONE format\nstring ('%s') to insert the totp base code", []string{"otpauth//url/%s/args..."}))
+ results = append(results, e.formatEnvironmentVariable(false, EnvTOTPToken.key, defaultTOTPField, "attribute name to store TOTP tokens within the database", []string{"string"}))
+ results = append(results, e.formatEnvironmentVariable(false, EnvFormatTOTP.key, strings.ReplaceAll(strings.ReplaceAll(EnvFormatTOTP.Get("%s"), "%25s", "%s"), "&", " \\\n &"), "override the otpauth url used to store totp tokens. It must have ONE format\nstring ('%s') to insert the totp base code", []string{"otpauth//url/%s/args..."}))
results = append(results, e.formatEnvironmentVariable(false, EnvMaxTOTP.key, fmt.Sprintf("%d", EnvMaxTOTP.defaultValue), "time, in seconds, in which to show a TOTP token before automatically exiting", intArgs))
results = append(results, e.formatEnvironmentVariable(false, EnvColorBetween.key, TOTPDefaultBetween, "override when to set totp generated outputs to different colors, must be a\nlist of one (or more) rules where a semicolon delimits the start and end\nsecond (0-60 for each)", []string{"start:end,start:end,start:end..."}))
results = append(results, e.formatEnvironmentVariable(false, EnvClipPaste.key, detectedValue, "override the detected platform paste command", []string{commandArgsExample}))
@@ -197,8 +197,7 @@ func ListEnvironmentVariables(showValues bool) []string {
return results
}
-// FormatTOTP will format a totp otpauth url
-func FormatTOTP(value string) string {
+func formatterTOTP(key, value string) string {
const (
otpAuth = "otpauth"
otpIssuer = "lbissuer"
@@ -206,7 +205,7 @@ func FormatTOTP(value string) string {
if strings.HasPrefix(value, otpAuth) {
return value
}
- override := EnvironOrDefault(formatTOTPEnv, "")
+ override := environOrDefault(key, "")
if override != "" {
return fmt.Sprintf(override, value)
}
diff --git a/internal/inputs/vars_test.go b/internal/inputs/vars_test.go
@@ -147,21 +147,21 @@ func TestReKey(t *testing.T) {
}
func TestFormatTOTP(t *testing.T) {
- otp := inputs.FormatTOTP("otpauth://abc")
+ otp := inputs.EnvFormatTOTP.Get("otpauth://abc")
if otp != "otpauth://abc" {
t.Errorf("invalid totp token: %s", otp)
}
- otp = inputs.FormatTOTP("abc")
+ otp = inputs.EnvFormatTOTP.Get("abc")
if otp != "otpauth://totp/lbissuer:lbaccount?algorithm=SHA1&digits=6&issuer=lbissuer&period=30&secret=abc" {
t.Errorf("invalid totp token: %s", otp)
}
os.Setenv("LOCKBOX_TOTP_FORMAT", "test/%s")
- otp = inputs.FormatTOTP("abc")
+ otp = inputs.EnvFormatTOTP.Get("abc")
if otp != "test/abc" {
t.Errorf("invalid totp token: %s", otp)
}
os.Setenv("LOCKBOX_TOTP_FORMAT", "")
- otp = inputs.FormatTOTP("abc")
+ otp = inputs.EnvFormatTOTP.Get("abc")
if otp != "otpauth://totp/lbissuer:lbaccount?algorithm=SHA1&digits=6&issuer=lbissuer&period=30&secret=abc" {
t.Errorf("invalid totp token: %s", otp)
}