From 7d7c3995d758e613f25b8e34e7d16ddf766038c5 Mon Sep 17 00:00:00 2001 From: bakito Date: Tue, 7 Jan 2025 16:28:25 +0100 Subject: [PATCH] fix: Correct nested groups for keepassxc builtin mode Signed-off-by: bakito --- internal/cmd/keepassxctemplatefuncs.go | 3 + internal/cmd/keepassxctemplatefuncs_test.go | 108 +++++++++++++++----- 2 files changed, 85 insertions(+), 26 deletions(-) diff --git a/internal/cmd/keepassxctemplatefuncs.go b/internal/cmd/keepassxctemplatefuncs.go index 96165983028..499f4c0f851 100644 --- a/internal/cmd/keepassxctemplatefuncs.go +++ b/internal/cmd/keepassxctemplatefuncs.go @@ -425,6 +425,9 @@ func keepassxcBuiltinBuildCache( entry, mapper, ) + if len(mapData) > 0 { + return mapData + } } } return map[string]string{} diff --git a/internal/cmd/keepassxctemplatefuncs_test.go b/internal/cmd/keepassxctemplatefuncs_test.go index 4af8fb02c65..b262d087aaf 100644 --- a/internal/cmd/keepassxctemplatefuncs_test.go +++ b/internal/cmd/keepassxctemplatefuncs_test.go @@ -74,6 +74,13 @@ func TestKeepassxcTemplateFuncs(t *testing.T) { attachmentName := "test / attachment name" attachmentData := "test / attachment data" + nestedGroupName := "some/nested/group" + nestedEntryName := nestedGroupName + "/nested entry" + nestedEntryUsername := "nested / username" + nestedEntryPassword := "nested / password" + nestedAttachmentName := "nested / attachment name" + nestedAttachmentData := "nested / attachment data" + // Create a KeePassXC database. dbCreateCmd := exec.Command(command, "db-create", "--set-password", database) dbCreateCmd.Stdin = strings.NewReader(chezmoitest.JoinLines( @@ -84,35 +91,32 @@ func TestKeepassxcTemplateFuncs(t *testing.T) { dbCreateCmd.Stderr = os.Stderr assert.NoError(t, dbCreateCmd.Run()) - // Create a group in the database. - mkdirCmd := exec.Command(command, "mkdir", database, groupName) - mkdirCmd.Stdin = strings.NewReader(chezmoitest.JoinLines( - databasePassword, - )) - mkdirCmd.Stdout = os.Stdout - mkdirCmd.Stderr = os.Stderr - assert.NoError(t, mkdirCmd.Run()) - - // Create an entry in the database. - addCmd := exec.Command(command, "add", database, entryName, "--username", entryUsername, "--password-prompt") - addCmd.Stdin = strings.NewReader(chezmoitest.JoinLines( + setupKeepassEntry( + t, + command, + tempDir, + database, databasePassword, + groupName, + entryName, + entryUsername, entryPassword, - )) - addCmd.Stdout = os.Stdout - addCmd.Stderr = os.Stderr - assert.NoError(t, addCmd.Run()) - - // Import an attachment to the entry in the database. - importFile := filepath.Join(tempDir, "import file") - assert.NoError(t, os.WriteFile(importFile, []byte(attachmentData), 0o666)) - attachmentImportCmd := exec.Command(command, "attachment-import", database, entryName, attachmentName, importFile) - attachmentImportCmd.Stdin = strings.NewReader(chezmoitest.JoinLines( + attachmentName, + attachmentData, + ) + setupKeepassEntry( + t, + command, + tempDir, + database, databasePassword, - )) - attachmentImportCmd.Stdout = os.Stdout - attachmentImportCmd.Stderr = os.Stderr - assert.NoError(t, attachmentImportCmd.Run()) + nestedGroupName, + nestedEntryName, + nestedEntryUsername, + nestedEntryPassword, + nestedAttachmentName, + nestedAttachmentData, + ) for _, mode := range []keepassxcMode{ keepassxcModeCachePassword, @@ -130,6 +134,14 @@ func TestKeepassxcTemplateFuncs(t *testing.T) { assert.Equal(t, entryPassword, config.keepassxcTemplateFunc(entryName)["Password"]) assert.Equal(t, entryUsername, config.keepassxcAttributeTemplateFunc(entryName, "UserName")) assert.Equal(t, attachmentData, config.keepassxcAttachmentTemplateFunc(entryName, attachmentName)) + + assert.Equal(t, nestedEntryPassword, config.keepassxcTemplateFunc(nestedEntryName)["Password"]) + assert.Equal(t, nestedEntryUsername, config.keepassxcAttributeTemplateFunc(nestedEntryName, "UserName")) + assert.Equal( + t, + nestedAttachmentData, + config.keepassxcAttachmentTemplateFunc(nestedEntryName, nestedAttachmentName), + ) }) t.Run("incorrect_password", func(t *testing.T) { @@ -170,3 +182,47 @@ func TestKeepassxcTemplateFuncs(t *testing.T) { }) } } + +func setupKeepassEntry( + t *testing.T, + command, tempDir, database, databasePassword, groupName, entryName, entryUsername, entryPassword, attachmentName, attachmentData string, +) { + t.Helper() + // Create nested groups in the database. + groupPath := strings.Split(groupName, "/") + for i := range groupPath { + var name string + if i == 0 { + name = groupPath[i] + } else { + name = strings.Join(groupPath[0:i+1], "/") + } + mkdirCmd := exec.Command(command, "mkdir", database, name) + mkdirCmd.Stdin = strings.NewReader(chezmoitest.JoinLines( + databasePassword, + )) + mkdirCmd.Stdout = os.Stdout + mkdirCmd.Stderr = os.Stderr + assert.NoError(t, mkdirCmd.Run()) + } + // Create an entry in the database. + addCmd := exec.Command(command, "add", database, entryName, "--username", entryUsername, "--password-prompt") + addCmd.Stdin = strings.NewReader(chezmoitest.JoinLines( + databasePassword, + entryPassword, + )) + addCmd.Stdout = os.Stdout + addCmd.Stderr = os.Stderr + assert.NoError(t, addCmd.Run()) + + // Import an attachment to the entry in the database. + importFile := filepath.Join(tempDir, "import file") + assert.NoError(t, os.WriteFile(importFile, []byte(attachmentData), 0o666)) + attachmentImportCmd := exec.Command(command, "attachment-import", database, entryName, attachmentName, importFile) + attachmentImportCmd.Stdin = strings.NewReader(chezmoitest.JoinLines( + databasePassword, + )) + attachmentImportCmd.Stdout = os.Stdout + attachmentImportCmd.Stderr = os.Stderr + assert.NoError(t, attachmentImportCmd.Run()) +}