commit 2919ef4dd392cc53ca965fba04d0c93adbed4348
parent fc0c6c317501548ecb60f69796f626693d96c981
Author: Sean Enck <sean@ttypty.com>
Date: Sat, 31 Dec 2022 18:42:34 -0500
allow overriding modtime
Diffstat:
6 files changed, 68 insertions(+), 4 deletions(-)
diff --git a/cmd/vers.txt b/cmd/vers.txt
@@ -1 +1 @@
-v22.12.05
-\ No newline at end of file
+v22.12.06
+\ No newline at end of file
diff --git a/internal/backend/actions.go b/internal/backend/actions.go
@@ -225,6 +225,15 @@ func (t *Transaction) Move(src QueryEntity, dst string) error {
if strings.TrimSpace(src.Value) == "" {
return errors.New("empty secret not allowed")
}
+ mod := inputs.EnvOrDefault(inputs.ModTimeEnv, "")
+ modTime := time.Now()
+ if mod != "" {
+ p, err := time.Parse(inputs.ModTimeFormat, mod)
+ if err != nil {
+ return err
+ }
+ modTime = p
+ }
dOffset, dTitle, err := splitComponents(dst)
if err != nil {
return err
@@ -269,7 +278,7 @@ func (t *Transaction) Move(src QueryEntity, dst string) error {
e.Values = append(e.Values, protectedValue("otp", v))
}
e.Values = append(e.Values, protectedValue(field, v))
- e.Values = append(e.Values, value(modTimeKey, time.Now().Format(time.RFC3339)))
+ e.Values = append(e.Values, value(modTimeKey, modTime.Format(time.RFC3339)))
c.insertEntity(dOffset, dTitle, e)
return nil
})
diff --git a/internal/backend/actions_test.go b/internal/backend/actions_test.go
@@ -21,6 +21,7 @@ func fullSetup(t *testing.T, keep bool) *backend.Transaction {
os.Setenv("LOCKBOX_KEYMODE", "plaintext")
os.Setenv("LOCKBOX_TOTP", "totp")
os.Setenv("LOCKBOX_HOOKDIR", "")
+ os.Setenv("LOCKBOX_SET_MODTIME", "")
tr, err := backend.NewTransaction()
if err != nil {
t.Errorf("failed: %v", err)
@@ -38,6 +39,7 @@ func TestKeyFile(t *testing.T) {
os.Setenv("LOCKBOX_KEYMODE", "plaintext")
os.Setenv("LOCKBOX_TOTP", "totp")
os.Setenv("LOCKBOX_HOOKDIR", "")
+ os.Setenv("LOCKBOX_SET_MODTIME", "")
os.WriteFile("file.key.kdbx", []byte("test"), 0644)
tr, err := backend.NewTransaction()
if err != nil {
diff --git a/internal/backend/query_test.go b/internal/backend/query_test.go
@@ -1,6 +1,8 @@
package backend_test
import (
+ "fmt"
+ "os"
"strings"
"testing"
@@ -188,3 +190,48 @@ func TestNewPath(t *testing.T) {
t.Error("invalid new path")
}
}
+
+func TestSetModTime(t *testing.T) {
+ testDateTime := "2022-12-30T12:34:56-05:00"
+ tr := fullSetup(t, false)
+ os.Setenv("LOCKBOX_SET_MODTIME", testDateTime)
+ tr.Insert("test/xyz", "test")
+ q, err := fullSetup(t, true).Get("test/xyz", backend.HashedValue)
+ if err != nil {
+ t.Errorf("no error: %v", err)
+ }
+ hash := strings.TrimSpace(q.Value)
+ parts := strings.Split(hash, "\n")
+ if len(parts) != 2 {
+ t.Errorf("invalid hash output: %v", parts)
+ }
+ dt := parts[0]
+ if dt != fmt.Sprintf("modtime: %s", testDateTime) {
+ t.Errorf("invalid date/time: %s", dt)
+ }
+
+ tr = fullSetup(t, false)
+ os.Setenv("LOCKBOX_SET_MODTIME", "")
+ tr.Insert("test/xyz", "test")
+ q, err = fullSetup(t, true).Get("test/xyz", backend.HashedValue)
+ if err != nil {
+ t.Errorf("no error: %v", err)
+ }
+ hash = strings.TrimSpace(q.Value)
+ parts = strings.Split(hash, "\n")
+ if len(parts) != 2 {
+ t.Errorf("invalid hash output: %v", parts)
+ }
+ dt = parts[0]
+ if dt == fmt.Sprintf("modtime: %s", testDateTime) {
+ t.Errorf("invalid date/time: %s", dt)
+ }
+
+ tr = fullSetup(t, false)
+ os.Setenv("LOCKBOX_SET_MODTIME", "garbage")
+ err = tr.Insert("test/xyz", "test")
+ if err == nil || !strings.Contains(err.Error(), "parsing time") {
+ t.Errorf("invalid error: %v", err)
+ }
+
+}
diff --git a/internal/inputs/env.go b/internal/inputs/env.go
@@ -9,6 +9,7 @@ import (
"os/exec"
"strconv"
"strings"
+ "time"
"github.com/google/shlex"
)
@@ -61,6 +62,10 @@ const (
noTOTPEnv = prefixKey + "NOTOTP"
// HookDirEnv represents a stored location for user hooks
HookDirEnv = prefixKey + "HOOKDIR"
+ // ModTimeEnv is modtime override ability for entries
+ ModTimeEnv = prefixKey + "SET_MODTIME"
+ // ModTimeFormat is the expected modtime format
+ ModTimeFormat = time.RFC3339
)
var (
@@ -295,5 +300,6 @@ func ListEnvironmentVariables(showValues bool) []string {
results = append(results, e.formatEnvironmentVariable(false, HookDirEnv, "", "the path to hooks to execute on actions against the database", []string{"directory"}))
results = append(results, e.formatEnvironmentVariable(false, clipOSC52Env, isNo, "enable OSC52 clipboard mode", isYesNoArgs))
results = append(results, e.formatEnvironmentVariable(false, KeyFileEnv, "", "additional keyfile to access/protect the database", []string{"keyfile"}))
+ results = append(results, e.formatEnvironmentVariable(false, ModTimeEnv, ModTimeFormat, "input mod time to set for the entry", []string{"modtime"}))
return results
}
diff --git a/internal/inputs/env_test.go b/internal/inputs/env_test.go
@@ -166,7 +166,7 @@ func TestListVariables(t *testing.T) {
known[trim] = struct{}{}
}
l := len(known)
- if l != 18 {
+ if l != 19 {
t.Errorf("invalid env count, outdated? %d", l)
}
}