commit 8669ee353401e311b61fcb5aa7fb6d388e3e2acb
parent e12832693583f116597c7e7aaf3abc11580fac78
Author: Sean Enck <sean@ttypty.com>
Date: Wed, 26 Jul 2023 20:11:47 -0400
max totp is an integer
Diffstat:
3 files changed, 53 insertions(+), 61 deletions(-)
diff --git a/internal/app/totp.go b/internal/app/totp.go
@@ -6,7 +6,6 @@ import (
"fmt"
"os"
"os/exec"
- "strconv"
"strings"
"time"
@@ -156,8 +155,7 @@ func (args *TOTPArguments) display(opts TOTPOptions) error {
if err != nil {
return err
}
- runString := inputs.EnvironOrDefault(inputs.MaxTOTPTime, inputs.MaxTOTPTimeDefault)
- runFor, err := strconv.Atoi(runString)
+ runFor, err := inputs.EnvMaxTOTP.Get()
if err != nil {
return err
}
diff --git a/internal/inputs/vars.go b/internal/inputs/vars.go
@@ -30,8 +30,6 @@ const (
StoreEnv = prefixKey + "STORE"
// ColorBetweenEnv is a comma-delimited list of times to color totp outputs (e.g. 0:5,30:35 which is the default).
ColorBetweenEnv = fieldTOTPEnv + "_BETWEEN"
- // MaxTOTPTime indicate how long TOTP tokens will be shown
- MaxTOTPTime = fieldTOTPEnv + "_MAX"
// ClipPasteEnv allows overriding the clipboard paste command
ClipPasteEnv = clipBaseEnv + "PASTE"
// ClipCopyEnv allows overriding the clipboard copy command
@@ -45,8 +43,6 @@ const (
ModTimeEnv = prefixKey + "SET_MODTIME"
// ModTimeFormat is the expected modtime format
ModTimeFormat = time.RFC3339
- // MaxTOTPTimeDefault is the max TOTP time to run (default)
- MaxTOTPTimeDefault = "120"
// JSONDataOutputEnv controls how JSON is output
JSONDataOutputEnv = prefixKey + "JSON_DATA_OUTPUT"
// JSONDataOutputHash means output data is hashed
@@ -74,6 +70,8 @@ var (
EnvNoColor = EnvironmentBool{environmentBase: environmentBase{key: prefixKey + "NOCOLOR"}, defaultValue: false}
// 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}
)
type (
@@ -189,7 +187,7 @@ func ListEnvironmentVariables(showValues bool) []string {
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, MaxTOTPTime, MaxTOTPTimeDefault, "time, in seconds, in which to show a TOTP token before automatically exiting", intArgs))
+ 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, ColorBetweenEnv, 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, ClipPasteEnv, detectedValue, "override the detected platform paste command", []string{commandArgsExample}))
results = append(results, e.formatEnvironmentVariable(false, ClipCopyEnv, detectedValue, "override the detected platform copy command", []string{commandArgsExample}))
diff --git a/internal/inputs/vars_test.go b/internal/inputs/vars_test.go
@@ -146,59 +146,6 @@ func TestReKey(t *testing.T) {
os.Setenv("LOCKBOX_KEYFILE_NEW", "")
}
-func TestGetClipboardMax(t *testing.T) {
- os.Setenv("LOCKBOX_CLIP_MAX", "")
- defer os.Clearenv()
- max, err := inputs.EnvClipboardMax.Get()
- if err != nil || max != 45 {
- t.Error("invalid clipboard read")
- }
- os.Setenv("LOCKBOX_CLIP_MAX", "1")
- max, err = inputs.EnvClipboardMax.Get()
- if err != nil || max != 1 {
- t.Error("invalid clipboard read")
- }
- os.Setenv("LOCKBOX_CLIP_MAX", "-1")
- if _, err := inputs.EnvClipboardMax.Get(); err == nil || err.Error() != "clipboard max time must be > 0" {
- t.Errorf("invalid err: %v", err)
- }
- os.Setenv("LOCKBOX_CLIP_MAX", "alk;ja")
- if _, err := inputs.EnvClipboardMax.Get(); err == nil || err.Error() != "strconv.Atoi: parsing \"alk;ja\": invalid syntax" {
- t.Errorf("invalid err: %v", err)
- }
- os.Setenv("LOCKBOX_CLIP_MAX", "0")
- if _, err := inputs.EnvClipboardMax.Get(); err == nil || err.Error() != "clipboard max time must be > 0" {
- t.Errorf("invalid err: %v", err)
- }
-}
-
-func TestGetHashLength(t *testing.T) {
- os.Setenv("LOCKBOX_JSON_DATA_OUTPUT_HASH_LENGTH", "")
- defer os.Clearenv()
- val, err := inputs.EnvHashLength.Get()
- if err != nil || val != 0 {
- t.Error("invalid hash read")
- }
- os.Setenv("LOCKBOX_JSON_DATA_OUTPUT_HASH_LENGTH", "1")
- val, err = inputs.EnvHashLength.Get()
- if err != nil || val != 1 {
- t.Error("invalid hash read")
- }
- os.Setenv("LOCKBOX_JSON_DATA_OUTPUT_HASH_LENGTH", "0")
- val, err = inputs.EnvHashLength.Get()
- if err != nil || val != 0 {
- t.Error("invalid hash read")
- }
- os.Setenv("LOCKBOX_JSON_DATA_OUTPUT_HASH_LENGTH", "-1")
- if _, err := inputs.EnvHashLength.Get(); err == nil || err.Error() != "hash length must be >= 0" {
- t.Errorf("invalid err: %v", err)
- }
- os.Setenv("LOCKBOX_JSON_DATA_OUTPUT_HASH_LENGTH", "-aoaofaij;p1")
- if _, err := inputs.EnvHashLength.Get(); err == nil || err.Error() != "strconv.Atoi: parsing \"-aoaofaij;p1\": invalid syntax" {
- t.Errorf("invalid err: %v", err)
- }
-}
-
func TestFormatTOTP(t *testing.T) {
otp := inputs.FormatTOTP("otpauth://abc")
if otp != "otpauth://abc" {
@@ -246,3 +193,52 @@ func TestParseJSONMode(t *testing.T) {
t.Errorf("invalid error: %v", err)
}
}
+
+func TestClipboardMax(t *testing.T) {
+ checkInt(inputs.EnvClipboardMax, "LOCKBOX_CLIP_MAX", "clipboard max time", 45, false, t)
+}
+
+func TestHashLength(t *testing.T) {
+ checkInt(inputs.EnvHashLength, "LOCKBOX_JSON_DATA_OUTPUT_HASH_LENGTH", "hash length", 0, true, t)
+}
+
+func TestMaxTOTP(t *testing.T) {
+ checkInt(inputs.EnvMaxTOTP, "LOCKBOX_TOTP_MAX", "max totp time", 120, false, t)
+}
+
+func checkInt(e inputs.EnvironmentInt, key, text string, def int, allowZero bool, t *testing.T) {
+ os.Setenv(key, "")
+ defer os.Clearenv()
+ val, err := e.Get()
+ if err != nil || val != def {
+ t.Error("invalid read")
+ }
+ os.Setenv(key, "1")
+ val, err = e.Get()
+ if err != nil || val != 1 {
+ t.Error("invalid read")
+ }
+ os.Setenv(key, "-1")
+ zero := ""
+ if allowZero {
+ zero = "="
+ }
+ if _, err := e.Get(); err == nil || err.Error() != fmt.Sprintf("%s must be >%s 0", text, zero) {
+ t.Errorf("invalid err: %v", err)
+ }
+ os.Setenv(key, "alk;ja")
+ if _, err := e.Get(); err == nil || err.Error() != "strconv.Atoi: parsing \"alk;ja\": invalid syntax" {
+ t.Errorf("invalid err: %v", err)
+ }
+ os.Setenv(key, "0")
+ if allowZero {
+ val, err = e.Get()
+ if err != nil || val != 0 {
+ t.Error("invalid read")
+ }
+ } else {
+ if _, err := e.Get(); err == nil || err.Error() != fmt.Sprintf("%s must be > 0", text) {
+ t.Errorf("invalid err: %v", err)
+ }
+ }
+}