Preserve single-root KDBX group trees

This commit is contained in:
Joe Julian
2026-03-29 22:17:40 -07:00
parent 47d0ccc7ce
commit caf4ec6266
2 changed files with 161 additions and 7 deletions
+74
View File
@@ -175,6 +175,80 @@ func TestSavePersistsEditsBackToCurrentPath(t *testing.T) {
}
}
func TestSaveReparentsMixedPathsUnderSingleVaultRoot(t *testing.T) {
t.Parallel()
key := vault.MasterKey{Password: "correct horse battery staple"}
path := filepath.Join(t.TempDir(), "hidden-root.kdbx")
var initial bytes.Buffer
if err := vault.SaveKDBX(&initial, vault.Model{
Entries: []vault.Entry{
{
ID: "entry-1",
Title: "Vault Console",
Username: "dannyocean",
Password: "token-1",
URL: "https://vault.crew.example.invalid",
Path: []string{"keepass", "Crew", "Internet"},
},
{
ID: "entry-2",
Title: "Mail",
Username: "dannyocean",
Password: "token-2",
URL: "https://dispatch.crew.example.invalid",
Path: []string{"keepass", "Crew", "eMail"},
},
},
}, key.Password); err != nil {
t.Fatalf("SaveKDBX() error = %v", err)
}
if err := os.WriteFile(path, initial.Bytes(), 0o600); err != nil {
t.Fatalf("WriteFile(hidden-root.kdbx) error = %v", err)
}
var sess Manager
if err := sess.Open(path, key); err != nil {
t.Fatalf("Open() error = %v", err)
}
current, err := sess.Current()
if err != nil {
t.Fatalf("Current() error = %v", err)
}
current.Entries[0].Path = []string{"Crew", "Internet"}
current.Groups = append(current.Groups, []string{"Crew"}, []string{"Crew", "Internet"}, []string{"Crew", "eMail"})
sess.Replace(current)
if err := sess.Save(); err != nil {
t.Fatalf("Save() error = %v", err)
}
reopened, err := os.Open(path)
if err != nil {
t.Fatalf("Open(saved path) error = %v", err)
}
defer reopened.Close()
db := gokeepasslib.NewDatabase()
db.Credentials = gokeepasslib.NewPasswordCredentials(key.Password)
if err := gokeepasslib.NewDecoder(reopened).Decode(db); err != nil {
t.Fatalf("Decode(saved path) error = %v", err)
}
if err := db.UnlockProtectedEntries(); err != nil {
t.Fatalf("UnlockProtectedEntries() error = %v", err)
}
if len(db.Content.Root.Groups) != 1 || db.Content.Root.Groups[0].Name != "keepass" {
t.Fatalf("top-level groups = %#v, want single keepass root", db.Content.Root.Groups)
}
rootGroups := db.Content.Root.Groups[0].Groups
if len(rootGroups) != 1 || rootGroups[0].Name != "Crew" {
t.Fatalf("keepass child groups = %#v, want single Crew group", rootGroups)
}
}
func TestSaveWithoutPathFails(t *testing.T) {
t.Parallel()