require "test_helper" class BitwardenSecretsManagerAdapterTest < SecretAdapterTestCase test "fetch with no parameters" do stub_ticks.with("bws --version 2> /dev/null") stub_login error = assert_raises RuntimeError do (shellunescape(run_command("fetch"))) end assert_equal("You must specify what to retrieve from Bitwarden Secrets Manager", error.message) end test "fetch all" do stub_ticks.with("bws --version 2> /dev/null") stub_login stub_ticks .with("bws secret list") .returns(<<~JSON) [ { "key": "KAMAL_REGISTRY_PASSWORD", "value": "some_password" }, { "key": "MY_OTHER_SECRET", "value": "my=wierd\\"secret" } ] JSON json = JSON.parse(shellunescape(run_command("fetch", "all"))) expected_json = { "KAMAL_REGISTRY_PASSWORD"=>"some_password", "MY_OTHER_SECRET"=>"my=wierd\"secret" } assert_equal expected_json, json end test "fetch all with from" do stub_ticks.with("bws --version 2> /dev/null") stub_login stub_ticks .with("bws secret list 82aeb5bd-6958-4a89-8197-eacab758acce") .returns(<<~JSON) [ { "key": "KAMAL_REGISTRY_PASSWORD", "value": "some_password" }, { "key": "MY_OTHER_SECRET", "value": "my=wierd\\"secret" } ] JSON json = JSON.parse(shellunescape(run_command("fetch", "all", "--from", "82aeb5bd-6958-4a89-8197-eacab758acce"))) expected_json = { "KAMAL_REGISTRY_PASSWORD"=>"some_password", "MY_OTHER_SECRET"=>"my=wierd\"secret" } assert_equal expected_json, json end test "fetch item" do stub_ticks.with("bws --version 2> /dev/null") stub_login stub_ticks .with("bws secret get 82aeb5bd-6958-4a89-8197-eacab758acce") .returns(<<~JSON) { "key": "KAMAL_REGISTRY_PASSWORD", "value": "some_password" } JSON json = JSON.parse(shellunescape(run_command("fetch", "82aeb5bd-6958-4a89-8197-eacab758acce"))) expected_json = { "KAMAL_REGISTRY_PASSWORD"=>"some_password" } assert_equal expected_json, json end test "fetch with multiple items" do stub_ticks.with("bws --version 2> /dev/null") stub_login stub_ticks .with("bws secret get 82aeb5bd-6958-4a89-8197-eacab758acce") .returns(<<~JSON) { "key": "KAMAL_REGISTRY_PASSWORD", "value": "some_password" } JSON stub_ticks .with("bws secret get 6f8cdf27-de2b-4c77-a35d-07df8050e332") .returns(<<~JSON) { "key": "MY_OTHER_SECRET", "value": "my=wierd\\"secret" } JSON json = JSON.parse(shellunescape(run_command("fetch", "82aeb5bd-6958-4a89-8197-eacab758acce", "6f8cdf27-de2b-4c77-a35d-07df8050e332"))) expected_json = { "KAMAL_REGISTRY_PASSWORD"=>"some_password", "MY_OTHER_SECRET"=>"my=wierd\"secret" } assert_equal expected_json, json end test "fetch all empty" do stub_ticks.with("bws --version 2> /dev/null") stub_login stub_ticks_with("bws secret list", succeed: false).returns("Error:\n0: Received error message from server") error = assert_raises RuntimeError do (shellunescape(run_command("fetch", "all"))) end assert_equal("Could not read secrets from Bitwarden Secrets Manager", error.message) end test "fetch nonexistent item" do stub_ticks.with("bws --version 2> /dev/null") stub_login stub_ticks_with("bws secret get 82aeb5bd-6958-4a89-8197-eacab758acce", succeed: false) .returns("Error:\n0: Received error message from server") error = assert_raises RuntimeError do (shellunescape(run_command("fetch", "82aeb5bd-6958-4a89-8197-eacab758acce"))) end assert_equal("Could not read 82aeb5bd-6958-4a89-8197-eacab758acce from Bitwarden Secrets Manager", error.message) end test "fetch item with linebreak in value" do stub_ticks.with("bws --version 2> /dev/null") stub_login stub_ticks .with("bws secret get 82aeb5bd-6958-4a89-8197-eacab758acce") .returns(<<~JSON) { "key": "SSH_PRIVATE_KEY", "value": "some_key\\nwith_linebreak" } JSON json = JSON.parse(shellunescape(run_command("fetch", "82aeb5bd-6958-4a89-8197-eacab758acce"))) expected_json = { "SSH_PRIVATE_KEY"=>"some_key\nwith_linebreak" } assert_equal expected_json, json end test "fetch with no access token" do stub_ticks.with("bws --version 2> /dev/null") stub_ticks_with("bws project list", succeed: false) error = assert_raises RuntimeError do (shellunescape(run_command("fetch", "all"))) end assert_equal("Could not authenticate to Bitwarden Secrets Manager. Did you set a valid access token?", error.message) end test "fetch without CLI installed" do stub_ticks_with("bws --version 2> /dev/null", succeed: false) error = assert_raises RuntimeError do shellunescape(run_command("fetch")) end assert_equal "Bitwarden Secrets Manager CLI is not installed", error.message end private def stub_login stub_ticks.with("bws project list").returns("OK") end def run_command(*command) stdouted do Kamal::Cli::Secrets.start \ [ *command, "--adapter", "bitwarden-sm" ] end end end