Skip to content

Commit

Permalink
don't require totp vault key in ce
Browse files Browse the repository at this point in the history
  • Loading branch information
ruslandoga committed Jul 7, 2024
1 parent 35596e8 commit d8ed09f
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file.
- Make TCP connections try IPv6 first with IPv4 fallback in CE plausible/analytics#4245
- `is` and `is not` filters in dashboard no longer support wildcards. Use contains/does not contain filter instead.
- `bounce_rate` metric now returns 0 instead of null for event:page breakdown when page has never been entry page.
- Make `TOTP_VAULT_KEY` optional plausible/analytics#4317

### Fixed

Expand Down
35 changes: 22 additions & 13 deletions config/runtime.exs
Original file line number Diff line number Diff line change
Expand Up @@ -153,19 +153,30 @@ end

# Can be generated with `Base.encode64(:crypto.strong_rand_bytes(32))` from
# iex shell or `openssl rand -base64 32` from command line.
totp_vault_key = get_var_from_path_or_env(config_dir, "TOTP_VAULT_KEY", nil)

case totp_vault_key do
nil ->
raise "TOTP_VAULT_KEY configuration option is required. See https://github.com/plausible/community-edition/tree/v2.1.0?tab=readme-ov-file#quick-start"

key ->
if byte_size(Base.decode64!(key)) != 32 do
raise "TOTP_VAULT_KEY must exactly 32 bytes long. See https://github.com/plausible/community-edition/tree/v2.1.0?tab=readme-ov-file#quick-start"
totp_vault_key =
if totp_vault_key_base64 = get_var_from_path_or_env(config_dir, "TOTP_VAULT_KEY") do
case Base.decode64(totp_vault_key_base64) do
{:ok, totp_vault_key} ->
if byte_size(totp_vault_key) == 32 do
totp_vault_key
else
raise ArgumentError, """
TOTP_VAULT_KEY must be exactly 32 bytes long, e.g. Got #{byte_size(totp_vault_key)} bytes.
See https://github.com/plausible/community-edition/tree/v2.1.1#quick-start
"""
end

:error ->
raise ArgumentError, """
TOTP_VAULT_KEY must be Base64 encoded, e.g. `openssl rand -base64 32`
See https://github.com/plausible/community-edition/tree/v2.1.1#quick-start
"""
end
end
else
Plug.Crypto.KeyGenerator.generate(secret_key_base, "totp", length: 32, iterations: 310_000)
end

### Mandatory params End
config :plausible, Plausible.Auth.TOTP, vault_key: totp_vault_key

build_metadata_raw = get_var_from_path_or_env(config_dir, "BUILD_METADATA", "{}")

Expand Down Expand Up @@ -197,8 +208,6 @@ runtime_metadata = [

config :plausible, :runtime_metadata, runtime_metadata

config :plausible, Plausible.Auth.TOTP, vault_key: totp_vault_key

sentry_dsn = get_var_from_path_or_env(config_dir, "SENTRY_DSN")
honeycomb_api_key = get_var_from_path_or_env(config_dir, "HONEYCOMB_API_KEY")
honeycomb_dataset = get_var_from_path_or_env(config_dir, "HONEYCOMB_DATASET")
Expand Down
1 change: 0 additions & 1 deletion lib/plausible/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ defmodule Plausible.Application do
:plausible
|> Application.fetch_env!(Plausible.Auth.TOTP)
|> Keyword.fetch!(:vault_key)
|> Base.decode64!()
end

defp finch_pool_config() do
Expand Down
62 changes: 62 additions & 0 deletions test/plausible/config_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,68 @@ defmodule Plausible.ConfigTest do
end
end

describe "totp" do
test "pbkdf2 if not set" do
env = [
{"TOTP_VAULT_KEY", nil}
]

config = runtime_config(env)

assert [vault_key: vault_key] = get_in(config, [:plausible, Plausible.Auth.TOTP])
assert byte_size(vault_key) == 32

assert vault_key ==
<<11, 246, 172, 65, 214, 208, 149, 122, 53, 80, 12, 12, 15, 71, 109, 13, 83, 0, 26,
77, 252, 92, 238, 26, 76, 25, 57, 105, 221, 96, 245, 127>>
end

test "can be Base64-encoded 32 bytes (with padding)" do
# $ openssl rand -base64 32
# dx2W6PNd/QIC6IyYVWMEaG2fI8/5WVylryM3mRaOpAo=
env = [
{"TOTP_VAULT_KEY", "dx2W6PNd/QIC6IyYVWMEaG2fI8/5WVylryM3mRaOpAo="}
]

config = runtime_config(env)

assert [vault_key: vault_key] = get_in(config, [:plausible, Plausible.Auth.TOTP])
assert byte_size(vault_key) == 32
assert vault_key == Base.decode64!("dx2W6PNd/QIC6IyYVWMEaG2fI8/5WVylryM3mRaOpAo=")
end

test "fails on invalid key length" do
assert_raise ArgumentError,
~r/TOTP_VAULT_KEY must be exactly 32 bytes long, e.g. Got 31 bytes./,
fn ->
runtime_config(
_env = [{"TOTP_VAULT_KEY", Base.encode64(:crypto.strong_rand_bytes(31))}]
)
end

assert_raise ArgumentError,
~r/TOTP_VAULT_KEY must be exactly 32 bytes long, e.g. Got 33 bytes./,
fn ->
runtime_config(
_env = [{"TOTP_VAULT_KEY", Base.encode64(:crypto.strong_rand_bytes(33))}]
)
end
end

test "fails on invalid encoding" do
assert_raise ArgumentError,
~r/TOTP_VAULT_KEY must be Base64 encoded/,
fn ->
runtime_config(
_env = [
{"TOTP_VAULT_KEY",
"openssl" <> Base.encode64(:crypto.strong_rand_bytes(32))}
]
)
end
end
end

defp runtime_config(env) do
put_system_env_undo(env)
Config.Reader.read!("config/runtime.exs", env: :prod)
Expand Down

0 comments on commit d8ed09f

Please sign in to comment.