diff --git a/.check.exs b/.check.exs new file mode 100644 index 0000000..24dfa4c --- /dev/null +++ b/.check.exs @@ -0,0 +1,34 @@ +[ + ## don't run tools concurrently + # parallel: false, + + ## don't print info about skipped tools + # skipped: false, + + ## always run tools in fix mode (put it in ~/.check.exs locally, not in project config) + # fix: true, + + ## don't retry automatically even if last run resulted in failures + # retry: false, + + ## list of tools (see `mix check` docs for a list of default curated tools) + tools: [ + ## curated tools may be disabled (e.g. the check for compilation warnings) + # {:compiler, false}, + + ## ...or have command & args adjusted (e.g. enable skip comments for sobelow) + {:sobelow, "mix sobelow --exit --skip -i Config.HTTPS,Config.Headers --threshold medium"}, + + ## ...or reordered (e.g. to see output from dialyzer before others) + # {:dialyzer, order: -1}, + {:dialyzer, false}, + + ## ...or reconfigured (e.g. disable parallel execution of ex_unit in umbrella) + {:ex_unit, false}, + + ## custom new tools may be added (Mix tasks or arbitrary commands) + # {:my_task, "mix my_task", env: %{"MIX_ENV" => "prod"}}, + # {:my_tool, ["my_tool", "arg with spaces"]} + {:doctor, false} + ] +] diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 464c82b..5ab88a3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,6 +2,7 @@ on: push env: OTP_VERSION: 24.0 ELIXIR_VERSION: 1.13.3 + MIX_ENV: test jobs: test: @@ -14,6 +15,7 @@ jobs: elixir-version: ${{ env.ELIXIR_VERSION }} - run: echo 'JAVA=SCRIPT\nER=LANG' > .env - run: mix deps.get + - run: mix check - run: mix test - name: Elixir Hex, mix build Cache diff --git a/config/.credo.exs b/config/.credo.exs new file mode 100644 index 0000000..2dbb32e --- /dev/null +++ b/config/.credo.exs @@ -0,0 +1,19 @@ +%{ + configs: [ + %{ + name: "default", + files: %{ + included: ["lib/"], + excluded: [] + }, + plugins: [], + requires: [], + strict: false, + parse_timeout: 5000, + color: true, + checks: [ + {Credo.Check.Readability.WithSingleClause, false} + ] + } + ] +} diff --git a/lib/cache.ex b/lib/cache.ex index b2897dd..cba185d 100644 --- a/lib/cache.ex +++ b/lib/cache.ex @@ -1,4 +1,7 @@ defmodule ExSecrets.Cache do + @moduledoc """ + Cache module provides helper functions for caching secrets. + """ use GenServer @store_name :ex_secrets_cache_store diff --git a/lib/ex_secrets.ex b/lib/ex_secrets.ex index 88404a7..1ba2b4a 100644 --- a/lib/ex_secrets.ex +++ b/lib/ex_secrets.ex @@ -7,46 +7,107 @@ defmodule ExSecrets do alias ExSecrets.Utils.Resolver alias ExSecrets.Utils.SecretFetchLimiter + require Logger + @doc """ - Get secret value + Get secret value. + You can pass two options: + - provider: Name of the provider to use. Default is :system_env + - default_value: Default value to return if secret is not found. Default is nil ## Examples - iex(1)> ExSecrets.get("FOO") + iex> ExSecrets.get("FOO") nil - iex(2)> Application.put_env(:ex_secrets, :default_provider, :dot_env) + iex> Application.put_env(:ex_secrets, :default_provider, :dot_env) :ok - iex(3)> ExSecrets.get("FOO") + iex> ExSecrets.get("FOO") nil - iex(4)> System.put_env "FOO", "BAR" + iex> System.put_env "FOO", "BAR" + :ok + iex> ExSecrets.get("FOO") + "BAR" + iex> System.delete_env "FOO" :ok - iex(5)> ExSecrets.get("FOO") + iex> ExSecrets.get("FOO") "BAR" - iex(6)> System.delete_env "FOO" + iex> ExSecrets.reset() + :ok + iex> ExSecrets.get("FOO") + nil + iex> Application.delete_env(:ex_secrets, :default_provider) + :ok + iex> Application.put_env(:ex_secrets, :providers, %{dot_env: %{path: "test/support/fixtures/dot_env_test.env"}}) + :ok + iex> ExSecrets.get("ERL", provider: :dot_env) + nil + iex> ExSecrets.get("ERL", provider: :dot_env, default_value: "ANG") + "ANG" + iex> Application.delete_env(:ex_secrets, :providers) :ok - iex(7)> Application.delete_env(:ex_secrets, :default_provider) + iex> Application.put_env(:ex_secrets, :providers, %{dot_env: %{path: "test/support/fixtures/dot_env_test.env"}}) + :ok + iex> ExSecrets.get("DEVS", provider: :dot_env) + "ROCKS" + iex> Application.delete_env(:ex_secrets, :providers) :ok """ - def get(key) do - case get_any_provider() do - provider when is_atom(provider) -> get(key, provider) + def get(key, opts \\ []) + + def get(key, []) do + with provider when is_atom(provider) <- get_any_provider(), + value when not is_nil(value) <- get(key, provider: provider) do + value + else _ -> get_default(key) end end - @doc """ - Get secret value with provider name. + def get(key, provider: provider, default_value: default_value) do + with value when is_nil(value) <- Cache.get(key), + fetch <- SecretFetchLimiter.allow(key, ExSecrets, :get_using_provider, [key, provider]), + value when not is_nil(value) <- Cache.pass_by(key, fetch) do + value + else + nil -> default_value + value -> value + end + end + + def get(key, provider: provider) do + with value when is_nil(value) <- Cache.get(key), + fetch <- SecretFetchLimiter.allow(key, ExSecrets, :get_using_provider, [key, provider]), + value when not is_nil(value) <- Cache.pass_by(key, fetch) do + value + else + nil -> get_default(key) + value -> value + end + end + + def get(key, default_value: default_value) do + with value when is_nil(value) <- Cache.get(key), + provider <- get_any_provider(), + fetch <- SecretFetchLimiter.allow(key, ExSecrets, :get_using_provider, [key, provider]), + value when not is_nil(value) <- Cache.pass_by(key, fetch) do + value + else + nil -> default_value + value -> value + end + end - ## Examples - iex(1)> Application.put_env(:ex_secrets, :providers, %{dot_env: %{path: "test/support/fixtures/dot_env_test.env"}}) - :ok - iex(2)> ExSecrets.get("DEVS", :dot_env) - "ROCKS" - iex(4)> Application.delete_env(:ex_secrets, :providers) - :ok - """ def get(key, provider) do - with value when not is_nil(value) <- Cache.get(key) do + m = "ExSecrets.get(key, provider) is deprecated. Use ExSecrets.get/2 with options." + + cond do + has_fun?(Logger, :warn) -> Logger.warn(m) + has_fun?(Logger, :warning) -> Logger.warning(m) + true -> :ok + end + + with true <- is_atom(provider), + value when not is_nil(value) <- Cache.get(key) do value else nil -> @@ -59,19 +120,11 @@ defmodule ExSecrets do @doc """ Get secret value with provider name and default value - - ## Examples - iex(1)> Application.put_env(:ex_secrets, :providers, %{dot_env: %{path: "test/support/fixtures/dot_env_test.env"}}) - :ok - iex(2)> ExSecrets.get("ERL", :dot_env) - nil - iex(3)> ExSecrets.get("ERL", :dot_env, "ANG") - "ANG" - iex(4)> Application.delete_env(:ex_secrets, :providers) - :ok """ + @deprecated "This function is deprecated. Use get/2 instead." def get(key, provider, default) do - with value when not is_nil(value) <- Cache.get(key) do + with true <- is_atom(provider), + value when not is_nil(value) <- Cache.get(key) do value else nil -> @@ -85,7 +138,6 @@ defmodule ExSecrets do end end - @doc """ Internal function for fetching secret with provide for catching and rate limiting. Do not rely on this function. @@ -101,12 +153,11 @@ defmodule ExSecrets do defp get_default(key) do with value when is_nil(value) <- Cache.get(key), - provider <- get_default_prider() do - Cache.pass_by( - key, - SecretFetchLimiter.allow(key, ExSecrets, :get_using_provider, [key, provider]) - ) + provider when provider not in [:system_env] <- get_default_prider(), + fetch <- SecretFetchLimiter.allow(key, ExSecrets, :get_using_provider, [key, provider]) do + Cache.pass_by(key, fetch) else + provider when is_atom(provider) -> get_using_provider(key, provider) value -> value end end @@ -125,12 +176,16 @@ defmodule ExSecrets do end end - @doc """ + @doc """ Resets cache and reloads all providers. """ def reset() do - n = GenServer.call(:ex_secrets_cache_store, :clear) + GenServer.call(:ex_secrets_cache_store, :clear) ExSecrets.Application.get_providers() |> Enum.each(&Kernel.apply(&1, :reset, [])) - {:ok, n} + :ok + end + + defp has_fun?(module, func) do + Keyword.has_key?(module.__info__(:functions), func) end end diff --git a/lib/http_adapter_behavior.ex b/lib/http_adapter_behavior.ex index 93bea6b..03599a3 100644 --- a/lib/http_adapter_behavior.ex +++ b/lib/http_adapter_behavior.ex @@ -1,4 +1,7 @@ defmodule ExSecrets.HTTPAdapterBehavior do + @moduledoc """ + Behaviour for HTTP adapters. + """ @callback get(binary(), map()) :: {:ok, map()} | {:error, binary()} @callback post(binary(), map(), map()) :: {:ok, map()} | {:error, binary()} end diff --git a/lib/providers/azure_key_vault.ex b/lib/providers/azure_key_vault.ex index bdd613f..18adce2 100644 --- a/lib/providers/azure_key_vault.ex +++ b/lib/providers/azure_key_vault.ex @@ -113,6 +113,10 @@ defmodule ExSecrets.Providers.AzureKeyVault do end end + def set(_name, _value) do + {:error, "Not implemented"} + end + def handle_call({:get, name}, _from, state) do case get_secret(name, state, get_current_epoch()) do {:ok, secret, state} -> {:reply, secret, state} @@ -131,7 +135,8 @@ defmodule ExSecrets.Providers.AzureKeyVault do current_time ) when issued_at + expires_in - current_time > 5 do - with {:ok, value} <- get_secret_call(name, access_token) do + with {:ok, value} <- get_secret_call(name, access_token), + true <- is_binary(value) do {:ok, value, state} else _ -> {:error, "Failed to get secret"} diff --git a/lib/providers/azure_managed_identity.ex b/lib/providers/azure_managed_identity.ex index 887ca00..5884e3e 100644 --- a/lib/providers/azure_managed_identity.ex +++ b/lib/providers/azure_managed_identity.ex @@ -50,6 +50,10 @@ defmodule ExSecrets.Providers.AzureManagedIdentity do end end + def set(_name, _value) do + {:error, "Not implemented"} + end + def handle_call({:get, name}, _from, state) do case get_secret(name, state, get_current_epoch()) do {:ok, secret, state} -> {:reply, secret, state} @@ -69,7 +73,8 @@ defmodule ExSecrets.Providers.AzureManagedIdentity do current_time ) when issued_at + expires_in - current_time > 5 do - with {:ok, value} <- get_secret_call(name, access_token) do + with {:ok, value} <- get_secret_call(name, access_token), + true <- is_binary(value) do {:ok, value, state} else _ -> {:error, "Failed to get secret"} diff --git a/lib/providers/behaviour.ex b/lib/providers/behaviour.ex index 7266e53..c7a75b0 100644 --- a/lib/providers/behaviour.ex +++ b/lib/providers/behaviour.ex @@ -12,4 +12,6 @@ defmodule ExSecrets.Providers.Behaviour do Gets a secret from the provider. """ @callback get(String.t()) :: String.t() + + @callback set(String.t(), String.t()) :: {:ok, String.t()} | {:error, term()} end diff --git a/lib/providers/dot_env.ex b/lib/providers/dot_env.ex index bbd87dc..dcddcd6 100644 --- a/lib/providers/dot_env.ex +++ b/lib/providers/dot_env.ex @@ -16,6 +16,10 @@ defmodule ExSecrets.Providers.DotEnv do end end + def set(_name, _value) do + {:error, "Not implemented"} + end + def init(_) do read_env() {:ok, %{}} diff --git a/lib/providers/google_secret_manager.ex b/lib/providers/google_secret_manager.ex index 75d3482..c99ac25 100644 --- a/lib/providers/google_secret_manager.ex +++ b/lib/providers/google_secret_manager.ex @@ -74,6 +74,10 @@ defmodule ExSecrets.Providers.GoogleSecretManager do end end + def set(_name, _value) do + {:error, "Not implemented"} + end + def handle_call({:get, name}, _from, state) do case get_secret(name, state, get_current_epoch()) do {:ok, secret, state} -> {:reply, secret, state} @@ -88,7 +92,8 @@ defmodule ExSecrets.Providers.GoogleSecretManager do current_time ) when issued_at + expires_in - current_time > 5 do - with {:ok, value} <- get_secret_call(name, access_token, state.cred) do + with {:ok, value} <- get_secret_call(name, access_token, state.cred), + true <- is_binary(value) do {:ok, value, state} else _ -> {:error, "Failed to get secret"} diff --git a/lib/providers/system_env.ex b/lib/providers/system_env.ex index d7fd2a2..7c6c1db 100644 --- a/lib/providers/system_env.ex +++ b/lib/providers/system_env.ex @@ -1,4 +1,7 @@ defmodule ExSecrets.Providers.SystemEnv do + @moduledoc """ + SystemEnv provider provides secrets from the system environment. + """ use ExSecrets.Providers.Base def init(_) do @@ -13,6 +16,11 @@ defmodule ExSecrets.Providers.SystemEnv do System.get_env(name) end + def set(name, value) do + System.put_env(name, value) + {:ok, value} + end + def process_name() do :ex_secrets_system_env end diff --git a/lib/utils/config.ex b/lib/utils/config.ex index 57b4c10..ae9a50c 100644 --- a/lib/utils/config.ex +++ b/lib/utils/config.ex @@ -1,4 +1,7 @@ defmodule ExSecrets.Utils.Config do + @moduledoc """ + Config module provides helper functions for getting configuration values. + """ def provider_config_value(provider, key) do provider |> provider_env() diff --git a/lib/utils/resolver.ex b/lib/utils/resolver.ex index 2e152d8..1887743 100644 --- a/lib/utils/resolver.ex +++ b/lib/utils/resolver.ex @@ -1,4 +1,7 @@ defmodule ExSecrets.Utils.Resolver do + @moduledoc """ + Resolver module resolves the provider name to the actual provider module. + """ def call(:system_env), do: ExSecrets.Providers.SystemEnv def call(:dot_env), do: ExSecrets.Providers.DotEnv def call(:azure_managed_identity), do: ExSecrets.Providers.AzureManagedIdentity diff --git a/lib/utils/secret_fetch_limiter.ex b/lib/utils/secret_fetch_limiter.ex index ff50b7f..f22a00f 100644 --- a/lib/utils/secret_fetch_limiter.ex +++ b/lib/utils/secret_fetch_limiter.ex @@ -1,4 +1,7 @@ defmodule ExSecrets.Utils.SecretFetchLimiter do + @moduledoc """ + Secret fetch limiter module limits the number of secret fetches in a given time. + """ require Logger use GenServer @@ -29,11 +32,14 @@ defmodule ExSecrets.Utils.SecretFetchLimiter do end def allow(key, module, function, args) do - case :ets.whereis(@table_name) do - :undefined -> + case {:ets.whereis(@table_name), args} do + {_, [_, :system_env]} -> Kernel.apply(module, function, args) - _ -> + {:undefined, _} -> + Kernel.apply(module, function, args) + + {_, _} -> now = current_time() @table_name diff --git a/mix.exs b/mix.exs index ee7b714..573e260 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule ExSecrets.MixProject do def project do [ app: :ex_secrets, - version: "0.2.1", + version: "0.3.0", elixir: "~> 1.13", build_embedded: Mix.env() == :prod, start_permanent: Mix.env() == :prod, @@ -39,7 +39,13 @@ defmodule ExSecrets.MixProject do # Testing and Documentation {:mix_test_watch, "~> 1.0", only: [:dev, :test], runtime: false}, {:mox, "~> 1.0", only: :test}, - {:ex_doc, "~> 0.14", only: :dev, runtime: false} + {:ex_doc, "~> 0.14", only: [:dev, :test], runtime: false}, + {:ex_check, "~> 0.14.0", only: [:dev, :test], runtime: false}, + {:doctor, "~> 0.21.0", only: [:dev, :test]}, + {:dialyxir, "~> 1.0", only: [:dev, :test], runtime: false}, + {:sobelow, "~> 0.11.1", only: [:dev, :test]}, + {:excoveralls, "~> 0.10", only: :test}, + {:credo, "~> 1.6", only: [:dev, :test], runtime: false} ] end diff --git a/mix.lock b/mix.lock index 020f928..2cb4ce4 100644 --- a/mix.lock +++ b/mix.lock @@ -1,13 +1,16 @@ %{ - "aws": {:hex, :aws, "0.11.0", "c5bd2099f138d3b8ce8f984b35091a4c6dca71a193614820758284ea445fce05", [:mix], [{:aws_signature, "~> 0.3", [hex: :aws_signature, repo: "hexpm", optional: false]}, {:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "424feb280f6badfe3cb7bdef53151bbb26de22b6937023011a7236a2d5974388"}, - "aws_signature": {:hex, :aws_signature, "0.3.1", "67f369094cbd55ffa2bbd8cc713ede14b195fcfb45c86665cd7c5ad010276148", [:rebar3], [], "hexpm", "50fc4dc1d1f7c2d0a8c63f455b3c66ecd74c1cf4c915c768a636f9227704a674"}, + "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, "certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"}, + "credo": {:hex, :credo, "1.7.1", "6e26bbcc9e22eefbff7e43188e69924e78818e2fe6282487d0703652bc20fd62", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "e9871c6095a4c0381c89b6aa98bc6260a8ba6addccf7f6a53da8849c748a58a2"}, + "decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"}, + "dialyxir": {:hex, :dialyxir, "1.4.2", "764a6e8e7a354f0ba95d58418178d486065ead1f69ad89782817c296d0d746a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "516603d8067b2fd585319e4b13d3674ad4f314a5902ba8130cd97dc902ce6bbd"}, + "doctor": {:hex, :doctor, "0.21.0", "20ef89355c67778e206225fe74913e96141c4d001cb04efdeba1a2a9704f1ab5", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "a227831daa79784eb24cdeedfa403c46a4cb7d0eab0e31232ec654314447e4e0"}, "earmark_parser": {:hex, :earmark_parser, "1.4.26", "f4291134583f373c7d8755566122908eb9662df4c4b63caa66a0eabe06569b0a", [:mix], [], "hexpm", "48d460899f8a0c52c5470676611c01f64f3337bad0b26ddab43648428d94aabc"}, + "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, + "ex_check": {:hex, :ex_check, "0.14.0", "d6fbe0bcc51cf38fea276f5bc2af0c9ae0a2bb059f602f8de88709421dae4f0e", [:mix], [], "hexpm", "8a602e98c66e6a4be3a639321f1f545292042f290f91fa942a285888c6868af0"}, "ex_doc": {:hex, :ex_doc, "0.28.4", "001a0ea6beac2f810f1abc3dbf4b123e9593eaa5f00dd13ded024eae7c523298", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "bf85d003dd34911d89c8ddb8bda1a958af3471a274a4c2150a9c01c78ac3f8ed"}, + "excoveralls": {:hex, :excoveralls, "0.18.0", "b92497e69465dc51bc37a6422226ee690ab437e4c06877e836f1c18daeb35da9", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "1109bb911f3cb583401760be49c02cbbd16aed66ea9509fc5479335d284da60b"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, - "google_api_secret_manager": {:hex, :google_api_secret_manager, "0.19.1", "10d3c36f62d5e8ba8f1405e3ae6b8fbd657bee7eea2d408009ccd7fbba3ced48", [:mix], [{:google_gax, "~> 0.4", [hex: :google_gax, repo: "hexpm", optional: false]}], "hexpm", "66e34e1886ca54af95e69e69ea6dff88e4e42fd0101799d7be988c7a015f966b"}, - "google_gax": {:hex, :google_gax, "0.4.1", "310105070626013712c56f8007b6ff7b4ead02ecad1efe7888350c6eaba52783", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:poison, ">= 3.0.0 and < 5.0.0", [hex: :poison, repo: "hexpm", optional: false]}, {:tesla, "~> 1.2", [hex: :tesla, repo: "hexpm", optional: false]}], "hexpm", "aef7dce7e04840c0e611f962475e3223d27d50ebd5e7d8e9e963c5e9e3b1ca79"}, - "goth": {:hex, :goth, "1.2.0", "92d6d926065a72a7e0da8818cc3a133229b56edf378022c00d9886c4125ce769", [:mix], [{:httpoison, "~> 0.11 or ~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:joken, "~> 2.0", [hex: :joken, repo: "hexpm", optional: false]}], "hexpm", "4974932ab3b782c99a6fdeb0b968ddd61436ef14de5862bd6bb0227386c63b26"}, "hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"}, "httpoison": {:hex, :httpoison, "1.8.1", "df030d96de89dad2e9983f92b0c506a642d4b1f4a819c96ff77d12796189c63e", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "35156a6d678d6d516b9229e208942c405cf21232edd632327ecfaf4fd03e79e0"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, @@ -18,14 +21,13 @@ "makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"}, "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, - "mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, "mix_test_watch": {:hex, :mix_test_watch, "1.1.0", "330bb91c8ed271fe408c42d07e0773340a7938d8a0d281d57a14243eae9dc8c3", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "52b6b1c476cbb70fd899ca5394506482f12e5f6b0d6acff9df95c7f1e0812ec3"}, "mox": {:hex, :mox, "1.0.2", "dc2057289ac478b35760ba74165b4b3f402f68803dd5aecd3bfd19c183815d64", [:mix], [], "hexpm", "f9864921b3aaf763c8741b5b8e6f908f44566f1e427b2630e89e9a73b981fef2"}, "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, "parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"}, + "sobelow": {:hex, :sobelow, "0.11.1", "23438964486f8112b41e743bbfd402da3e5b296fdc9eacab29914b79c48916dd", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9897363a7eff96f4809304a90aad819e2ad5e5d24db547af502885146746a53c"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, - "tesla": {:hex, :tesla, "1.4.4", "bb89aa0c9745190930366f6a2ac612cdf2d0e4d7fff449861baa7875afd797b2", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "d5503a49f9dec1b287567ea8712d085947e247cb11b06bc54adb05bfde466457"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, } diff --git a/test/ex_secrets_test.exs b/test/ex_secrets_test.exs index 0caf7d3..e329697 100644 --- a/test/ex_secrets_test.exs +++ b/test/ex_secrets_test.exs @@ -18,13 +18,13 @@ defmodule ExSecretsTest do test "Get with Provider FOO - BAR" do k = "FOO#{:rand.uniform(1000)}" System.put_env(k, "BARR") - assert ExSecrets.get(k, :system_env) == "BARR" + assert ExSecrets.get(k, provider: :system_env) == "BARR" System.delete_env(k) end test "Get with wring Provider FOOOZ - BARRZ" do k = "FOO#{:rand.uniform(1000)}" - assert ExSecrets.get(k, :abc) == nil + assert ExSecrets.get(k, provider: :abc) == nil System.delete_env(k) end @@ -32,7 +32,7 @@ defmodule ExSecretsTest do k = "FOO#{:rand.uniform(1000)}" Application.put_env(:ex_secrets, :providers, %{xyz: %{path: "test"}}) System.put_env(k, "BARR") - assert ExSecrets.get(k, :system_env) == "BARR" + assert ExSecrets.get(k, provider: :system_env) == "BARR" System.delete_env(k) Application.delete_env(:ex_secrets, :providers) end @@ -52,7 +52,7 @@ defmodule ExSecretsTest do }) {:ok, _} = GenServer.start(ExSecrets.Providers.DotEnv, []) - assert ExSecrets.get("JAVA", :dot_env) == "SCRIPT" + assert ExSecrets.get("JAVA", provider: :dot_env) == "SCRIPT" Application.put_env(:ex_secrets, :providers, %{ dot_env: %{path: "test/support/fixtures/dot_env_test_3.env"} @@ -60,6 +60,8 @@ defmodule ExSecretsTest do ExSecrets.reset() + assert ExSecrets.get("JAVA", provider: :dot_env) == "SCRIPTT" + assert ExSecrets.get("JAVA", :dot_env) == "SCRIPTT" Application.put_env(:ex_secrets, :providers, %{ diff --git a/test/providers/azure_key_vault_test.exs b/test/providers/azure_key_vault_test.exs index eb80796..565e2de 100644 --- a/test/providers/azure_key_vault_test.exs +++ b/test/providers/azure_key_vault_test.exs @@ -33,9 +33,9 @@ defmodule ExSecrets.Providers.AzureKeyVaultTest do |> expect(:get, &get_secret_mock/2) |> expect(:get, &get_secret_mock/2) - assert ExSecrets.get("ABC-1", :azure_key_vault) == "VAL" - assert ExSecrets.get("ABC-2", :azure_key_vault) == "VAL" - assert ExSecrets.get("ABC-2", :azure_key_vault) == "VAL" + assert ExSecrets.get("ABC-1", provider: :azure_key_vault) == "VAL" + assert ExSecrets.get("ABC-2", provider: :azure_key_vault) == "VAL" + assert ExSecrets.get("ABC-2", provider: :azure_key_vault) == "VAL" AzureKeyVaultHTTPAdapterMock # Token API Call @@ -56,31 +56,31 @@ defmodule ExSecrets.Providers.AzureKeyVaultTest do {:ok, _} = AzureKeyVault.start_link([]) # 1st call to get secret - API - assert ExSecrets.get("KEY-1", :azure_key_vault) == "VAL" + assert ExSecrets.get("KEY-1", provider: :azure_key_vault) == "VAL" # 2nd call to get secret - Cache - assert ExSecrets.get("KEY-1", :azure_key_vault) == "VAL" + assert ExSecrets.get("KEY-1", provider: :azure_key_vault) == "VAL" # 3rd call to get secret - API - assert ExSecrets.get("KEY-2", :azure_key_vault) == "VAL" + assert ExSecrets.get("KEY-2", provider: :azure_key_vault) == "VAL" # 4th call to get secret - API - assert ExSecrets.get("KEY-3", :azure_key_vault) == "VAL" + assert ExSecrets.get("KEY-3", provider: :azure_key_vault) == "VAL" # 5th call to get secret - API Application.put_env(:ex_secrets, :on_secret_fetch_limit_reached, :raise) Application.put_env(:ex_secrets, :secret_fetch_limit, 4) # 4 calls with nil - assert ExSecrets.get("NULL", :azure_key_vault) == nil - assert ExSecrets.get("NULL", :azure_key_vault) == nil - assert ExSecrets.get("NULL", :azure_key_vault) == nil - assert ExSecrets.get("NULL", :azure_key_vault) == nil - assert ExSecrets.get("NULL", :azure_key_vault) == nil + assert ExSecrets.get("NULL", provider: :azure_key_vault) == nil + assert ExSecrets.get("NULL", provider: :azure_key_vault) == nil + assert ExSecrets.get("NULL", provider: :azure_key_vault) == nil + assert ExSecrets.get("NULL", provider: :azure_key_vault) == nil + assert ExSecrets.get("NULL", provider: :azure_key_vault) == nil assert_raise RuntimeError, ~r/^Fetch secret NULL reached limit 4/, fn -> - assert ExSecrets.get("NULL", :azure_key_vault) == nil + assert ExSecrets.get("NULL", provider: :azure_key_vault) == nil end assert_raise RuntimeError, ~r/^Fetch secret NULL reached limit 4/, fn -> - assert ExSecrets.get("NULL", :azure_key_vault) == nil + assert ExSecrets.get("NULL", provider: :azure_key_vault) == nil end verify!(AzureKeyVaultHTTPAdapterMock) diff --git a/test/providers/azure_managed_identity_test.exs b/test/providers/azure_managed_identity_test.exs index 98e6072..9d43b7c 100644 --- a/test/providers/azure_managed_identity_test.exs +++ b/test/providers/azure_managed_identity_test.exs @@ -28,8 +28,8 @@ defmodule ExSecrets.Providers.AzureKeyManagedIdentityTest do # Secret API Call |> expect(:get, &get_secret_mock/2) - assert ExSecrets.get("ABCXYZ", :azure_managed_identity) == "VAL" - assert ExSecrets.get("ABCXYZ", :azure_managed_identity) == "VAL" + assert ExSecrets.get("ABCXYZ", provider: :azure_managed_identity) == "VAL" + assert ExSecrets.get("ABCXYZ", provider: :azure_managed_identity) == "VAL" verify!(HTTPAdapterMock) @@ -52,31 +52,31 @@ defmodule ExSecrets.Providers.AzureKeyManagedIdentityTest do {:ok, _} = AzureManagedIdentity.start_link([]) # 1st call to get secret - API - assert ExSecrets.get("KKEY1", :azure_managed_identity) == "VAL" + assert ExSecrets.get("KKEY1", provider: :azure_managed_identity) == "VAL" # 2nd call to get secret - Cache - assert ExSecrets.get("KKEY1", :azure_managed_identity) == "VAL" + assert ExSecrets.get("KKEY1", provider: :azure_managed_identity) == "VAL" # 3rd call to get secret - API - assert ExSecrets.get("KKEY2", :azure_managed_identity) == "VAL" + assert ExSecrets.get("KKEY2", provider: :azure_managed_identity) == "VAL" # 4th call to get secret - API - assert ExSecrets.get("KKEY3", :azure_managed_identity) == "VAL" + assert ExSecrets.get("KKEY3", provider: :azure_managed_identity) == "VAL" # 5th call to get secret - API Application.put_env(:ex_secrets, :on_secret_fetch_limit_reached, :raise) Application.put_env(:ex_secrets, :secret_fetch_limit, 4) # 9 more calls with nil - assert ExSecrets.get("NULLL", :azure_managed_identity) == nil - assert ExSecrets.get("NULLL", :azure_managed_identity) == nil - assert ExSecrets.get("NULLL", :azure_managed_identity) == nil - assert ExSecrets.get("NULLL", :azure_managed_identity) == nil - assert ExSecrets.get("NULLL", :azure_managed_identity) == nil + assert ExSecrets.get("NULLL", provider: :azure_managed_identity) == nil + assert ExSecrets.get("NULLL", provider: :azure_managed_identity) == nil + assert ExSecrets.get("NULLL", provider: :azure_managed_identity) == nil + assert ExSecrets.get("NULLL", provider: :azure_managed_identity) == nil + assert ExSecrets.get("NULLL", provider: :azure_managed_identity) == nil assert_raise RuntimeError, ~r/^Fetch secret NULLL reached limit 4/, fn -> - assert ExSecrets.get("NULLL", :azure_managed_identity) == nil + assert ExSecrets.get("NULLL", provider: :azure_managed_identity) == nil end assert_raise RuntimeError, ~r/^Fetch secret NULLL reached limit 4/, fn -> - assert ExSecrets.get("NULLL", :azure_managed_identity) == nil + assert ExSecrets.get("NULLL", provider: :azure_managed_identity) == nil end verify!(HTTPAdapterMock) diff --git a/test/providers/dot_env_test.exs b/test/providers/dot_env_test.exs index 79ca0b1..584fbe2 100644 --- a/test/providers/dot_env_test.exs +++ b/test/providers/dot_env_test.exs @@ -7,7 +7,7 @@ defmodule ExSecrets.Providers.DotEnvTest do }) {:ok, _} = GenServer.start(ExSecrets.Providers.DotEnv, []) - assert ExSecrets.get("JAVA", :dot_env) == "SCRIPT" + assert ExSecrets.get("JAVA", provider: :dot_env) == "SCRIPT" Application.delete_env(:ex_secrets, :providers) end @@ -16,7 +16,7 @@ defmodule ExSecrets.Providers.DotEnvTest do dot_env: %{path: "test/support/fixtures/dot_env_test_2.env"} }) - assert ExSecrets.get("ASD", :dot_env) == "FGH" + assert ExSecrets.get("ASD", provider: :dot_env) == "FGH" Application.delete_env(:ex_secrets, :providers) end @@ -26,7 +26,7 @@ defmodule ExSecrets.Providers.DotEnvTest do }) {:ok, _} = GenServer.start(ExSecrets.Providers.DotEnv, []) - assert ExSecrets.get("JAVA", :dot_env) == "SCRIPT" + assert ExSecrets.get("JAVA", provider: :dot_env) == "SCRIPT" Application.put_env(:ex_secrets, :providers, %{ dot_env: %{path: "test/support/fixtures/dot_env_test_3.env"} @@ -34,7 +34,7 @@ defmodule ExSecrets.Providers.DotEnvTest do ExSecrets.Providers.DotEnv.reset() - assert ExSecrets.get("JAVA", :dot_env) == "SCRIPTT" + assert ExSecrets.get("JAVA", provider: :dot_env) == "SCRIPTT" Application.put_env(:ex_secrets, :providers, %{ dot_env: %{path: "test/support/fixtures/dot_env_test.env"}