twpayne / chezmoi

Manage your dotfiles across multiple diverse machines, securely.
https://www.chezmoi.io/
MIT License
12.9k stars 478 forks source link

How to source information from a password manager or fallback to prompt user to type it in if not present #2981

Closed stefaniuk closed 1 year ago

stefaniuk commented 1 year ago

What exactly are you trying to do?

While installing dotfiles I would like to source configuration settings like User Name, User Email and Git Signing Key from a password manager i.e. Bitwarden. However, if Bitwarden is not installed a user needs to be prompted to type these in.

Some of my code snippets that work independently

[data]
  dotfiles.name = "{{ (bitwarden "item" "dotfiles").identity.firstName }} {{ (bitwarden "item" "dotfiles").identity.lastName }}"
  dotfiles.email = "{{ (bitwarden "item" "dotfiles").identity.email }}"
  dotfiles.git_signingkey = "{{ (bitwardenFields "item" "dotfiles").git_signingkey.value }}"
#   {{- $name := promptString "Git user name for the author/committer" }}
#   {{- $email := promptString "Git user email for the author/committer" }}
#   {{- $signingkey := promptString "Git user signing key for the author/committer" }}

But I wasn't able to construct an if statement as no matter how it is implemented it throws an error.

What have you tried so far?

I have tried a number of things within the .chezmoi.toml.tmpl file but nothing seems to work.

The main problem is that there seems to be no way to implement an if statement to make a decision depending on the presence of a key in the .chezmoi. data configuration. The pseudo-code I'm after is

# {{ if .chezmoi.config.bitwarden.command is installed }}
#   get name using "{{ (bitwarden "item" "dotfiles").identity.firstName }} {{ (bitwarden "item" "dotfiles").identity.lastName }}"
# {{ end }}
#   {{- $name := promptString "Git user name for the author/committer" }}
# {{ end }}

Where else have you checked for solutions?

Output of any commands you've tried

➜  chezmoi git:(main) ✗ echo '{{ .chezmoi.config.bitwarden | toJson }}' | chezmoi execute-template | jq
chezmoi: template: stdin:1:17: executing "stdin" at <.chezmoi.config.bitwarden>: map has no entry for key "bitwardend"
halostatue commented 1 year ago

I’ve been considering this myself as I use 1Password.

I think that you would want to do something like this:

{{- $name := "" -}}
{{- $email := "" -}}
{{- $signingKey := "" -}}
{{- if lookPath "bw" -}}
{{-   $dotfiles := (bitwarden "item" "dotfiles") -}}
{{-   $name = $dotfiles.identity.firstName + " " + $identity.lastName -}}
{{-   $email = $dotfiles.identity.email }}
{{-   $signingKey = $dotfiles.git_signingkey_value -}}
{{- else - }}
{{-   $name = promptStringOnce . "dotfiles.name" "Git user name for the author/committer" -}}
{{-   $email = promptStringOnce . "dotfiles.email" "Git user email for the author/committer" -}}
{{-   $signingKey = promptStringOnce . "dotfiles.git_signingkey" "Git user signing key for the author/committer" -}}

[data]
  dotfiles.name = {{ $name | quote }}
  dotfiles.email = {{ $email | quote }}
  dotfiles.git_signingkey = {{ $signingKey | quote }}

This is untested, but it should work.

stefaniuk commented 1 year ago

Thanks @halostatue for so prompt response. That worked really well. Here is a version of the template that I tested:

{{- $email := "" -}}
{{- $signingKey := "" -}}
{{- if lookPath "bw" -}}
{{-   $dotfiles := (bitwarden "item" "dotfiles") -}}
{{-   $name = (print $dotfiles.identity.firstName " " $dotfiles.identity.lastName) -}}
{{-   $email = $dotfiles.identity.email }}
{{-   $signingKey = (bitwardenFields "item" "dotfiles").git_signingkey.value -}}
{{- else -}}
{{-   $name = promptStringOnce . "dotfiles.name" "Git user name for the author/committer" -}}
{{-   $email = promptStringOnce . "dotfiles.email" "Git user email for the author/committer" -}}
{{-   $signingKey = promptStringOnce . "dotfiles.git_signingkey" "Git user signing key for the author/committer" -}}
{{- end -}}

[data]
  dotfiles.name = {{ $name | quote }}
  dotfiles.email = {{ $email | quote }}
  dotfiles.git_signingkey = {{ $signingKey | quote }}