make --account optional and pass Enpass vault in --from

This commit is contained in:
Aleksandr Lossenko
2024-11-07 18:13:37 +01:00
parent c9dec8c79a
commit 79bc7584ca
3 changed files with 19 additions and 38 deletions

View File

@@ -1,7 +1,7 @@
class Kamal::Cli::Secrets < Kamal::Cli::Base class Kamal::Cli::Secrets < Kamal::Cli::Base
desc "fetch [SECRETS...]", "Fetch secrets from a vault" desc "fetch [SECRETS...]", "Fetch secrets from a vault"
option :adapter, type: :string, aliases: "-a", required: true, desc: "Which vault adapter to use" 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 :from, type: :string, required: false, desc: "A vault or folder to fetch the secrets from"
option :inline, type: :boolean, required: false, hidden: true option :inline, type: :boolean, required: false, hidden: true
def fetch(*secrets) def fetch(*secrets)

View File

@@ -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 class Kamal::Secrets::Adapters::Enpass < Kamal::Secrets::Adapters::Base
private def fetch(secrets, account: nil, from:)
def login(account) check_dependencies!
# There is no concept of session in enpass-cli fetch_secrets(secrets, from)
true end
end
def fetch_secrets(secrets, account:, session:) private
def fetch_secrets(secrets, vault)
secrets_titles = fetch_secret_titles(secrets) 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 #{vault.shellescape} show #{secrets_titles.map(&:shellescape).join(" ")}`.strip
result = `enpass-cli -json -vault #{account.shellescape} show #{secrets.map(&:shellescape).join(" ")}`.strip
parse_result_and_take_secrets(result, secrets) parse_result_and_take_secrets(result, secrets)
end end

View File

@@ -1,10 +1,6 @@
require "test_helper" require "test_helper"
class EnpassAdapterTest < SecretAdapterTestCase class EnpassAdapterTest < SecretAdapterTestCase
setup do
`true` # Ensure $? is 0
end
test "fetch without CLI installed" do test "fetch without CLI installed" do
stub_ticks_with("enpass-cli version 2> /dev/null", succeed: false) stub_ticks_with("enpass-cli version 2> /dev/null", succeed: false)
@@ -19,7 +15,7 @@ class EnpassAdapterTest < SecretAdapterTestCase
stub_ticks_with("enpass-cli version 2> /dev/null") stub_ticks_with("enpass-cli version 2> /dev/null")
stub_ticks stub_ticks
.with("enpass-cli -json -vault vault-path show FooBar/SECRET_1") .with("enpass-cli -json -vault vault-path show FooBar")
.returns(<<~JSON) .returns(<<~JSON)
[{"category":"computer","label":"SECRET_1","login":"","password":"my-password-1","title":"FooBar","type":"password"}] [{"category":"computer","label":"SECRET_1","login":"","password":"my-password-1","title":"FooBar","type":"password"}]
JSON JSON
@@ -35,7 +31,7 @@ class EnpassAdapterTest < SecretAdapterTestCase
stub_ticks_with("enpass-cli version 2> /dev/null") stub_ticks_with("enpass-cli version 2> /dev/null")
stub_ticks 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) .returns(<<~JSON)
[ [
{"category":"computer","label":"SECRET_1","login":"","password":"my-password-1","title":"FooBar","type":"password"}, {"category":"computer","label":"SECRET_1","login":"","password":"my-password-1","title":"FooBar","type":"password"},
@@ -51,26 +47,6 @@ class EnpassAdapterTest < SecretAdapterTestCase
assert_equal expected_json, json assert_equal expected_json, json
end 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 test "fetch all with from" do
stub_ticks_with("enpass-cli version 2> /dev/null") stub_ticks_with("enpass-cli version 2> /dev/null")
@@ -99,7 +75,7 @@ class EnpassAdapterTest < SecretAdapterTestCase
[ *command, [ *command,
"-c", "test/fixtures/deploy_with_accessories.yml", "-c", "test/fixtures/deploy_with_accessories.yml",
"--adapter", "enpass", "--adapter", "enpass",
"--account", "vault-path" ] "--from", "vault-path" ]
end end
end end
end end