Skip to content

Commit

Permalink
make --account optional and pass Enpass vault in --from
Browse files Browse the repository at this point in the history
  • Loading branch information
egze committed Nov 7, 2024
1 parent a56d107 commit 327d716
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 38 deletions.
2 changes: 1 addition & 1 deletion lib/kamal/cli/secrets.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class Kamal::Cli::Secrets < Kamal::Cli::Base
desc "fetch [SECRETS...]", "Fetch secrets from a vault"
option :adapter, type: :string, aliases: "-a", required: true, desc: "Which vault adapter to use"
option :account, type: :string, required: true, desc: "The account identifier or username"
option :account, type: :string, required: false, desc: "The account identifier or username"
option :from, type: :string, required: false, desc: "A vault or folder to fetch the secrets from"
option :inline, type: :boolean, required: false, hidden: true
def fetch(*secrets)
Expand Down
25 changes: 15 additions & 10 deletions lib/kamal/secrets/adapters/enpass.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
##
# Enpass is different from most password managers, in a way that it's offline. A path to a vault is treated as account.
# Enpass is different from most password managers, in a way that it's offline and doesn't need an account.
#
# Pass it like so: `kamal secrets fetch --adapter enpass --account /Users/YOUR_USERNAME/Library/Containers/in.sinew.Enpass-Desktop/Data/Documents/Vaults/primary --from MY_PROD_SERVER`
# Usage
#
# Fetch all password from FooBar item
# `kamal secrets fetch --adapter enpass --from /Users/YOUR_USERNAME/Library/Containers/in.sinew.Enpass-Desktop/Data/Documents/Vaults/primary FooBar`
#
# Fetch only DB_PASSWORD from FooBar item
# `kamal secrets fetch --adapter enpass --from /Users/YOUR_USERNAME/Library/Containers/in.sinew.Enpass-Desktop/Data/Documents/Vaults/primary FooBar/DB_PASSWORD`
class Kamal::Secrets::Adapters::Enpass < Kamal::Secrets::Adapters::Base
private
def login(account)
# There is no concept of session in enpass-cli
true
end
def fetch(secrets, account: nil, from:)
check_dependencies!
fetch_secrets(secrets, from)
end

def fetch_secrets(secrets, account:, session:)
private
def fetch_secrets(secrets, vault)
secrets_titles = fetch_secret_titles(secrets)

# Enpass outputs result as stderr, I did not find a way to stub backticks and output to stderr. Open3 did the job.
result = `enpass-cli -json -vault #{account.shellescape} show #{secrets.map(&:shellescape).join(" ")}`.strip
result = `enpass-cli -json -vault #{vault.shellescape} show #{secrets_titles.map(&:shellescape).join(" ")}`.strip

parse_result_and_take_secrets(result, secrets)
end
Expand Down
30 changes: 3 additions & 27 deletions test/secrets/enpass_adapter_test.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
require "test_helper"

class EnpassAdapterTest < SecretAdapterTestCase
setup do
`true` # Ensure $? is 0
end

test "fetch without CLI installed" do
stub_ticks_with("enpass-cli version 2> /dev/null", succeed: false)

Expand All @@ -19,7 +15,7 @@ class EnpassAdapterTest < SecretAdapterTestCase
stub_ticks_with("enpass-cli version 2> /dev/null")

stub_ticks
.with("enpass-cli -json -vault vault-path show FooBar/SECRET_1")
.with("enpass-cli -json -vault vault-path show FooBar")
.returns(<<~JSON)
[{"category":"computer","label":"SECRET_1","login":"","password":"my-password-1","title":"FooBar","type":"password"}]
JSON
Expand All @@ -35,7 +31,7 @@ class EnpassAdapterTest < SecretAdapterTestCase
stub_ticks_with("enpass-cli version 2> /dev/null")

stub_ticks
.with("enpass-cli -json -vault vault-path show FooBar/SECRET_1 FooBar/SECRET_2")
.with("enpass-cli -json -vault vault-path show FooBar")
.returns(<<~JSON)
[
{"category":"computer","label":"SECRET_1","login":"","password":"my-password-1","title":"FooBar","type":"password"},
Expand All @@ -51,26 +47,6 @@ class EnpassAdapterTest < SecretAdapterTestCase
assert_equal expected_json, json
end

test "fetch multiple items with from" do
stub_ticks_with("enpass-cli version 2> /dev/null")

stub_ticks
.with("enpass-cli -json -vault vault-path show FooBar/SECRET_1 FooBar/SECRET_2")
.returns(<<~JSON)
[
{"category":"computer","label":"SECRET_1","login":"","password":"my-password-1","title":"FooBar","type":"password"},
{"category":"computer","label":"SECRET_2","login":"","password":"my-password-2","title":"FooBar","type":"password"},
{"category":"computer","label":"SECRET_3","login":"","password":"my-password-1","title":"Hello","type":"password"}
]
JSON

json = JSON.parse(shellunescape(run_command("fetch", "--from", "FooBar", "SECRET_1", "SECRET_2")))

expected_json = { "FooBar/SECRET_1" => "my-password-1", "FooBar/SECRET_2" => "my-password-2" }

assert_equal expected_json, json
end

test "fetch all with from" do
stub_ticks_with("enpass-cli version 2> /dev/null")

Expand Down Expand Up @@ -99,7 +75,7 @@ def run_command(*command)
[ *command,
"-c", "test/fixtures/deploy_with_accessories.yml",
"--adapter", "enpass",
"--account", "vault-path" ]
"--from", "vault-path" ]
end
end
end

0 comments on commit 327d716

Please sign in to comment.