forked from hiway/freedive
Add feature flag to disable registration in prod by default.
This commit is contained in:
parent
41887672ea
commit
8b9088797a
6 changed files with 132 additions and 44 deletions
|
@ -11,6 +11,11 @@ config :freedive,
|
||||||
ecto_repos: [Freedive.Repo],
|
ecto_repos: [Freedive.Repo],
|
||||||
generators: [timestamp_type: :utc_datetime]
|
generators: [timestamp_type: :utc_datetime]
|
||||||
|
|
||||||
|
config :freedive,
|
||||||
|
features: [
|
||||||
|
register_account: true
|
||||||
|
]
|
||||||
|
|
||||||
# Configures the endpoint
|
# Configures the endpoint
|
||||||
config :freedive, FreediveWeb.Endpoint,
|
config :freedive, FreediveWeb.Endpoint,
|
||||||
url: [host: "localhost"],
|
url: [host: "localhost"],
|
||||||
|
|
|
@ -21,6 +21,12 @@ if System.get_env("PHX_SERVER") do
|
||||||
end
|
end
|
||||||
|
|
||||||
if config_env() == :prod do
|
if config_env() == :prod do
|
||||||
|
# Account registration in production is disabled by default.
|
||||||
|
# To enable, set the REGISTER_ACCOUNT_ENABLE environment variable to "true".
|
||||||
|
if System.get_env("REGISTER_ACCOUNT_ENABLE") != "true" do
|
||||||
|
config :freedive, :features, register_account: false
|
||||||
|
end
|
||||||
|
|
||||||
database_path =
|
database_path =
|
||||||
System.get_env("DATABASE_PATH") ||
|
System.get_env("DATABASE_PATH") ||
|
||||||
raise """
|
raise """
|
||||||
|
|
|
@ -25,7 +25,8 @@ defmodule Freedive.Application do
|
||||||
# Start a worker by calling: Freedive.Worker.start_link(arg)
|
# Start a worker by calling: Freedive.Worker.start_link(arg)
|
||||||
# {Freedive.Worker, arg},
|
# {Freedive.Worker, arg},
|
||||||
# Start to serve requests, typically the last entry
|
# Start to serve requests, typically the last entry
|
||||||
FreediveWeb.Endpoint
|
FreediveWeb.Endpoint,
|
||||||
|
Freedive.Features
|
||||||
]
|
]
|
||||||
|
|
||||||
children = if minimal, do: app_minimal, else: app_minimal ++ app_features
|
children = if minimal, do: app_minimal, else: app_minimal ++ app_features
|
||||||
|
|
45
lib/freedive/features.ex
Normal file
45
lib/freedive/features.ex
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
defmodule Freedive.Features do
|
||||||
|
use GenServer
|
||||||
|
require Logger
|
||||||
|
|
||||||
|
def start_link(_args) do
|
||||||
|
GenServer.start_link(__MODULE__, nil, name: __MODULE__)
|
||||||
|
end
|
||||||
|
|
||||||
|
def enable(feature) do
|
||||||
|
GenServer.cast(__MODULE__, {:enable, feature})
|
||||||
|
end
|
||||||
|
|
||||||
|
def disable(feature) do
|
||||||
|
GenServer.cast(__MODULE__, {:disable, feature})
|
||||||
|
end
|
||||||
|
|
||||||
|
def enabled?(feature) do
|
||||||
|
GenServer.call(__MODULE__, {:enabled?, feature})
|
||||||
|
end
|
||||||
|
|
||||||
|
def init(nil) do
|
||||||
|
state = feature_flags_from_config()
|
||||||
|
Logger.info("Feature flags: #{inspect(state)}")
|
||||||
|
{:ok, state}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp feature_flags_from_config() do
|
||||||
|
Application.get_env(:freedive, :features)
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_cast({:enable, feature}, state) do
|
||||||
|
Logger.info("Enabling feature: #{feature}")
|
||||||
|
{:noreply, Keyword.put(state, feature, true)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_cast({:disable, feature}, state) do
|
||||||
|
Logger.info("Disabling feature: #{feature}")
|
||||||
|
{:noreply, Keyword.put(state, feature, false)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_call({:enabled?, feature}, _from, state) do
|
||||||
|
enabled = Keyword.get(state, feature, false)
|
||||||
|
{:reply, enabled, state}
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,43 +3,57 @@ defmodule FreediveWeb.UserRegistrationLive do
|
||||||
|
|
||||||
alias Freedive.Accounts
|
alias Freedive.Accounts
|
||||||
alias Freedive.Accounts.User
|
alias Freedive.Accounts.User
|
||||||
|
alias Freedive.Features
|
||||||
|
|
||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
~H"""
|
if Features.enabled?(:register_account) do
|
||||||
<div class="mx-auto max-w-sm">
|
~H"""
|
||||||
<.header class="text-center">
|
<div class="mx-auto max-w-sm">
|
||||||
Register for an account
|
<.header class="text-center">
|
||||||
<:subtitle>
|
Register for an account
|
||||||
Already registered?
|
<:subtitle>
|
||||||
<.link navigate={~p"/users/log_in"} class="font-semibold text-brand hover:underline">
|
Already registered?
|
||||||
Log in
|
<.link navigate={~p"/users/log_in"} class="font-semibold text-brand hover:underline">
|
||||||
</.link>
|
Log in
|
||||||
to your account now.
|
</.link>
|
||||||
</:subtitle>
|
to your account now.
|
||||||
</.header>
|
</:subtitle>
|
||||||
|
</.header>
|
||||||
|
|
||||||
<.simple_form
|
<.simple_form
|
||||||
for={@form}
|
for={@form}
|
||||||
id="registration_form"
|
id="registration_form"
|
||||||
phx-submit="save"
|
phx-submit="save"
|
||||||
phx-change="validate"
|
phx-change="validate"
|
||||||
phx-trigger-action={@trigger_submit}
|
phx-trigger-action={@trigger_submit}
|
||||||
action={~p"/users/log_in?_action=registered"}
|
action={~p"/users/log_in?_action=registered"}
|
||||||
method="post"
|
method="post"
|
||||||
>
|
>
|
||||||
<.error :if={@check_errors}>
|
<.error :if={@check_errors}>
|
||||||
Oops, something went wrong! Please check the errors below.
|
Oops, something went wrong! Please check the errors below.
|
||||||
</.error>
|
</.error>
|
||||||
|
|
||||||
<.input field={@form[:email]} type="email" label="Email" required />
|
<.input field={@form[:email]} type="email" label="Email" required />
|
||||||
<.input field={@form[:password]} type="password" label="Password" required />
|
<.input field={@form[:password]} type="password" label="Password" required />
|
||||||
|
|
||||||
<:actions>
|
<:actions>
|
||||||
<.button phx-disable-with="Creating account..." class="w-full">Create an account</.button>
|
<.button phx-disable-with="Creating account..." class="w-full">Create an account</.button>
|
||||||
</:actions>
|
</:actions>
|
||||||
</.simple_form>
|
</.simple_form>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
|
else
|
||||||
|
~H"""
|
||||||
|
<.section>
|
||||||
|
<.title>
|
||||||
|
Sorry!
|
||||||
|
</.title>
|
||||||
|
<.subtitle>
|
||||||
|
Registration is closed.
|
||||||
|
</.subtitle>
|
||||||
|
</.section>
|
||||||
|
"""
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def mount(_params, _session, socket) do
|
def mount(_params, _session, socket) do
|
||||||
|
@ -54,19 +68,23 @@ defmodule FreediveWeb.UserRegistrationLive do
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_event("save", %{"user" => user_params}, socket) do
|
def handle_event("save", %{"user" => user_params}, socket) do
|
||||||
case Accounts.register_user(user_params) do
|
if Features.enabled?(:register_account) do
|
||||||
{:ok, user} ->
|
case Accounts.register_user(user_params) do
|
||||||
{:ok, _} =
|
{:ok, user} ->
|
||||||
Accounts.deliver_user_confirmation_instructions(
|
{:ok, _} =
|
||||||
user,
|
Accounts.deliver_user_confirmation_instructions(
|
||||||
&url(~p"/users/confirm/#{&1}")
|
user,
|
||||||
)
|
&url(~p"/users/confirm/#{&1}")
|
||||||
|
)
|
||||||
|
|
||||||
changeset = Accounts.change_user_registration(user)
|
changeset = Accounts.change_user_registration(user)
|
||||||
{:noreply, socket |> assign(trigger_submit: true) |> assign_form(changeset)}
|
{:noreply, socket |> assign(trigger_submit: true) |> assign_form(changeset)}
|
||||||
|
|
||||||
{:error, %Ecto.Changeset{} = changeset} ->
|
{:error, %Ecto.Changeset{} = changeset} ->
|
||||||
{:noreply, socket |> assign(check_errors: true) |> assign_form(changeset)}
|
{:noreply, socket |> assign(check_errors: true) |> assign_form(changeset)}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{:noreply, socket}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,22 @@
|
||||||
defmodule FreediveWeb.UserRegistrationLiveTest do
|
defmodule FreediveWeb.UserRegistrationLiveTest do
|
||||||
use FreediveWeb.ConnCase
|
use FreediveWeb.ConnCase
|
||||||
|
alias Freedive.Features
|
||||||
|
|
||||||
import Phoenix.LiveViewTest
|
import Phoenix.LiveViewTest
|
||||||
import Freedive.AccountsFixtures
|
import Freedive.AccountsFixtures
|
||||||
|
|
||||||
|
describe "Registration closed" do
|
||||||
|
test "shows registrations closed message", %{conn: conn} do
|
||||||
|
Features.disable(:register_account)
|
||||||
|
|
||||||
|
{:ok, _lv, html} = live(conn, ~p"/users/register")
|
||||||
|
|
||||||
|
assert html =~ "Registration is closed"
|
||||||
|
|
||||||
|
Features.enable(:register_account)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "Registration page" do
|
describe "Registration page" do
|
||||||
test "renders registration page", %{conn: conn} do
|
test "renders registration page", %{conn: conn} do
|
||||||
{:ok, _lv, html} = live(conn, ~p"/users/register")
|
{:ok, _lv, html} = live(conn, ~p"/users/register")
|
||||||
|
|
Loading…
Reference in a new issue