Skip to content

Commit

Permalink
feat: Add keepassxcAttachment template function
Browse files Browse the repository at this point in the history
  • Loading branch information
twpayne committed Mar 24, 2022
1 parent b0ea806 commit 38be385
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# `keepassxcAttachment` *entry* *name*

`keepassxcAttachment` returns the attachment with *name* of *entry* using
`keepassxc-cli`. It behaves identically to the `keepassxc` function in terms of
configuration, password prompting, password storage, and result caching.

!!! example

```
{{- keepassxcAttachment "SSH Config" "config" -}}
```
1 change: 1 addition & 0 deletions assets/chezmoi.io/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ nav:
- ioreg: reference/templates/functions/ioreg.md
- joinPath: reference/templates/functions/joinPath.md
- keepassxc: reference/templates/functions/keepassxc.md
- keepassxcAttachment: reference/templates/functions/keepassxcAttachment.md
- keepassxcAttribute: reference/templates/functions/keepassxcAttribute.md
- keyring: reference/templates/functions/keyring.md
- lastpass: reference/templates/functions/lastpass.md
Expand Down
1 change: 1 addition & 0 deletions pkg/cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ func newConfig(options ...configOption) (*Config, error) {
"ioreg": c.ioregTemplateFunc,
"joinPath": c.joinPathTemplateFunc,
"keepassxc": c.keepassxcTemplateFunc,
"keepassxcAttachment": c.keepassxcAttachmentTemplateFunc,
"keepassxcAttribute": c.keepassxcAttributeTemplateFunc,
"keyring": c.keyringTemplateFunc,
"lastpass": c.lastpassTemplateFunc,
Expand Down
44 changes: 29 additions & 15 deletions pkg/cmd/keepassxctemplatefuncs.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,41 @@ type keepassxcAttributeCacheKey struct {
}

type keepassxcConfig struct {
Command string
Database chezmoi.AbsPath
Args []string
version *semver.Version
cache map[string]map[string]string
attributeCache map[keepassxcAttributeCacheKey]string
password string
Command string
Database chezmoi.AbsPath
Args []string
version *semver.Version
cache map[string]map[string]string
attachmentCache map[string]map[string]string
attributeCache map[keepassxcAttributeCacheKey]string
password string
}

var (
keepassxcPairRx = regexp.MustCompile(`^([^:]+):\s*(.*)$`)
keepassxcNeedShowProtectedArgVersion = semver.Version{Major: 2, Minor: 5, Patch: 1}
)

func (c *Config) keepassxcTemplateFunc(entry string) map[string]string {
if data, ok := c.Keepassxc.cache[entry]; ok {
func (c *Config) keepassxcAttachmentTemplateFunc(entry, name string) string {
if data, ok := c.Keepassxc.attachmentCache[entry][name]; ok {
return data
}

if c.Keepassxc.Database.Empty() {
panic(errors.New("keepassxc.database not set"))
args := []string{"attachment-export", "--stdout"}
args = append(args, c.Keepassxc.Args...)
args = append(args, c.Keepassxc.Database.String(), entry, name)

output, err := c.keepassxcOutput(c.Keepassxc.Command, args)
if err != nil {
panic(err)
}

return string(output)
}

func (c *Config) keepassxcTemplateFunc(entry string) map[string]string {
if data, ok := c.Keepassxc.cache[entry]; ok {
return data
}

args := []string{"show"}
Expand Down Expand Up @@ -79,10 +93,6 @@ func (c *Config) keepassxcAttributeTemplateFunc(entry, attribute string) string
return data
}

if c.Keepassxc.Database.Empty() {
panic(errors.New("keepassxc.database not set"))
}

args := []string{"show", "--attributes", attribute, "--quiet"}
version, err := c.keepassxcVersion()
if err != nil {
Expand All @@ -108,6 +118,10 @@ func (c *Config) keepassxcAttributeTemplateFunc(entry, attribute string) string
}

func (c *Config) keepassxcOutput(name string, args []string) ([]byte, error) {
if c.Keepassxc.Database.Empty() {
panic(errors.New("keepassxc.database not set"))
}

if c.Keepassxc.password == "" {
password, err := c.readPassword(fmt.Sprintf("Insert password to unlock %s: ", c.Keepassxc.Database))
if err != nil {
Expand Down
10 changes: 10 additions & 0 deletions pkg/cmd/testdata/scripts/keepassxc.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
[!windows] chmod 755 bin/keepass-test
[windows] unix2dos bin/keepass-test.cmd

# test keepassxcAttachment template function
stdin $HOME/input
chezmoi execute-template --no-tty '{{ keepassxcAttachment "example.com" "attachment" }}'
stdout '# contents of attachment'

# test keepassxcAttribute template function
stdin $HOME/input
chezmoi execute-template --no-tty '{{ keepassxcAttribute "example.com" "host-name" }}'
Expand All @@ -18,6 +23,9 @@ case "$*" in
"--version")
echo "2.5.4"
;;
"attachment-export --stdout /secrets.kdbx example.com attachment")
echo "# contents of attachment"
;;
"show --show-protected /secrets.kdbx example.com")
cat <<EOF
Title: example.com
Expand All @@ -38,6 +46,8 @@ esac
@echo off
IF "%*" == "--version" (
echo 2.5.4
) ELSE IF "%*" == "attachment-export --stdout C:/secrets.kdbx example.com attachment" (
echo.# contents of attachment
) ELSE IF "%*" == "show --show-protected C:/secrets.kdbx example.com" (
echo.Title: example.com
echo.UserName: examplelogin
Expand Down

0 comments on commit 38be385

Please sign in to comment.