Skip to content

Commit

Permalink
Support MFA for :password in :sentinel option (#257)
Browse files Browse the repository at this point in the history
Co-authored-by: Andrea Leopardi <[email protected]>
  • Loading branch information
ahovgaard and whatyouhide authored Oct 18, 2023
1 parent 3a91307 commit e97ef94
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/redix/start_options.ex
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,8 @@ defmodule Redix.StartOptions do
"""
],
password: [
type: :string,
type: {:or, [:string, :mfa]},
type_doc: "`String.t/0` or `{mod, fun, args}`",
doc: """
if you don't want to specify a password for each sentinel you
list, you can use this option to specify a password that will be used to authenticate
Expand Down
39 changes: 39 additions & 0 deletions test/redix/sentinel_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,45 @@ defmodule Redix.SentinelTest do
assert Redix.command!(pid, ["PING"]) == "PONG"
end

test "sentinel supports password mfa in sentinels list", %{sentinel_config: sentinel_config} do
System.put_env("REDIX_SENTINEL_MFA_PASSWORD", "sentinel-password")

password_mfa = {System, :get_env, ["REDIX_SENTINEL_MFA_PASSWORD"]}

sentinel_config =
Keyword.merge(sentinel_config,
sentinels: [[host: "localhost", port: 26383, password: password_mfa]]
)

pid =
start_supervised!(
{Redix, sentinel: sentinel_config, password: "main-password", sync_connect: true}
)

assert Redix.command!(pid, ["PING"]) == "PONG"
after
System.delete_env("REDIX_SENTINEL_MFA_PASSWORD")
end

test "sentinel supports global password mfa", %{sentinel_config: sentinel_config} do
System.put_env("REDIX_SENTINEL_MFA_PASSWORD", "sentinel-password")

sentinel_config =
Keyword.merge(sentinel_config,
password: {System, :get_env, ["REDIX_SENTINEL_MFA_PASSWORD"]},
sentinels: ["redis://localhost:26383"]
)

pid =
start_supervised!(
{Redix, sentinel: sentinel_config, password: "main-password", sync_connect: true}
)

assert Redix.command!(pid, ["PING"]) == "PONG"
after
System.delete_env("REDIX_SENTINEL_MFA_PASSWORD")
end

test "failed sentinel connection" do
{test_name, _arity} = __ENV__.function

Expand Down
43 changes: 43 additions & 0 deletions test/redix/start_options_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,49 @@ defmodule Redix.StartOptionsTest do
end
end

test "sentinel password string" do
opts =
StartOptions.sanitize(
sentinel: [
sentinels: [
[host: "host1", port: 26379, password: "secret1"],
[host: "host2", port: 26379]
],
group: "mygroup",
password: "secret2"
]
)

sentinels = opts[:sentinel][:sentinels]

assert Enum.count(sentinels) == 2
assert Enum.find(sentinels, &(&1[:host] == 'host1'))[:password] == "secret1"
assert Enum.find(sentinels, &(&1[:host] == 'host2'))[:password] == "secret2"
end

test "sentinel password mfa" do
mfa1 = {System, :fetch_env!, ["REDIS_PASS1"]}
mfa2 = {System, :fetch_env!, ["REDIS_PASS2"]}

opts =
StartOptions.sanitize(
sentinel: [
sentinels: [
[host: "host1", port: 26379, password: mfa1],
[host: "host2", port: 26379]
],
group: "mygroup",
password: mfa2
]
)

sentinels = opts[:sentinel][:sentinels]

assert Enum.count(sentinels) == 2
assert Enum.find(sentinels, &(&1[:host] == 'host1'))[:password] == mfa1
assert Enum.find(sentinels, &(&1[:host] == 'host2'))[:password] == mfa2
end

test "gen_statem options are allowed" do
opts =
StartOptions.sanitize(hibernate_after: 1000, debug: [], spawn_opt: [fullsweep_after: 0])
Expand Down

0 comments on commit e97ef94

Please sign in to comment.