Don't require TOTP vault key in CE (#4317)

This commit is contained in:
ruslandoga 2024-07-15 17:02:31 +07:00 committed by GitHub
parent 530951780c
commit 14d5a8028f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 77 additions and 13 deletions

View File

@ -21,6 +21,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

View File

@ -153,19 +153,31 @@ 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)
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 Base64 encoded 32 bytes, e.g. `openssl rand -base64 32`.
Got Base64 encoded #{byte_size(totp_vault_key)} bytes.
More info: https://github.com/plausible/community-edition/tree/v2.1.1#quick-start
"""
end
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"
:error ->
raise ArgumentError, """
TOTP_VAULT_KEY must be Base64 encoded 32 bytes, e.g. `openssl rand -base64 32`
More info: 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: 100_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", "{}")
@ -197,8 +209,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")

View File

@ -131,7 +131,6 @@ defmodule Plausible.Application do
:plausible
|> Application.fetch_env!(Plausible.Auth.TOTP)
|> Keyword.fetch!(:vault_key)
|> Base.decode64!()
end
defp finch_pool_config() do

View File

@ -385,6 +385,60 @@ 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
# make sure it doesn't change between releases
assert vault_key ==
"\x95\x9C\x05\x9A\xCD\xE4\xEF\xDDH\xFB\xCA\xD5o\xD1z\xCC\xBC\"J\xF8:\xFAs\xCA\x0Fo\x10\x9B\x84"
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/Got Base64 encoded 31 bytes/, fn ->
runtime_config(_env = [{"TOTP_VAULT_KEY", Base.encode64(:crypto.strong_rand_bytes(31))}])
end
assert_raise ArgumentError, ~r/Got Base64 encoded 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)