Add feature flag to disable registration in prod by default.

This commit is contained in:
Harshad Sharma 2024-05-13 19:22:50 +05:30
parent 41887672ea
commit 8b9088797a
6 changed files with 132 additions and 44 deletions

View file

@ -11,6 +11,11 @@ config :freedive,
ecto_repos: [Freedive.Repo],
generators: [timestamp_type: :utc_datetime]
config :freedive,
features: [
register_account: true
]
# Configures the endpoint
config :freedive, FreediveWeb.Endpoint,
url: [host: "localhost"],

View file

@ -21,6 +21,12 @@ if System.get_env("PHX_SERVER") do
end
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 =
System.get_env("DATABASE_PATH") ||
raise """

View file

@ -25,7 +25,8 @@ defmodule Freedive.Application do
# Start a worker by calling: Freedive.Worker.start_link(arg)
# {Freedive.Worker, arg},
# 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

45
lib/freedive/features.ex Normal file
View 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

View file

@ -3,43 +3,57 @@ defmodule FreediveWeb.UserRegistrationLive do
alias Freedive.Accounts
alias Freedive.Accounts.User
alias Freedive.Features
def render(assigns) do
~H"""
<div class="mx-auto max-w-sm">
<.header class="text-center">
Register for an account
<:subtitle>
Already registered?
<.link navigate={~p"/users/log_in"} class="font-semibold text-brand hover:underline">
Log in
</.link>
to your account now.
</:subtitle>
</.header>
if Features.enabled?(:register_account) do
~H"""
<div class="mx-auto max-w-sm">
<.header class="text-center">
Register for an account
<:subtitle>
Already registered?
<.link navigate={~p"/users/log_in"} class="font-semibold text-brand hover:underline">
Log in
</.link>
to your account now.
</:subtitle>
</.header>
<.simple_form
for={@form}
id="registration_form"
phx-submit="save"
phx-change="validate"
phx-trigger-action={@trigger_submit}
action={~p"/users/log_in?_action=registered"}
method="post"
>
<.error :if={@check_errors}>
Oops, something went wrong! Please check the errors below.
</.error>
<.simple_form
for={@form}
id="registration_form"
phx-submit="save"
phx-change="validate"
phx-trigger-action={@trigger_submit}
action={~p"/users/log_in?_action=registered"}
method="post"
>
<.error :if={@check_errors}>
Oops, something went wrong! Please check the errors below.
</.error>
<.input field={@form[:email]} type="email" label="Email" required />
<.input field={@form[:password]} type="password" label="Password" required />
<.input field={@form[:email]} type="email" label="Email" required />
<.input field={@form[:password]} type="password" label="Password" required />
<:actions>
<.button phx-disable-with="Creating account..." class="w-full">Create an account</.button>
</:actions>
</.simple_form>
</div>
"""
<:actions>
<.button phx-disable-with="Creating account..." class="w-full">Create an account</.button>
</:actions>
</.simple_form>
</div>
"""
else
~H"""
<.section>
<.title>
Sorry!
</.title>
<.subtitle>
Registration is closed.
</.subtitle>
</.section>
"""
end
end
def mount(_params, _session, socket) do
@ -54,19 +68,23 @@ defmodule FreediveWeb.UserRegistrationLive do
end
def handle_event("save", %{"user" => user_params}, socket) do
case Accounts.register_user(user_params) do
{:ok, user} ->
{:ok, _} =
Accounts.deliver_user_confirmation_instructions(
user,
&url(~p"/users/confirm/#{&1}")
)
if Features.enabled?(:register_account) do
case Accounts.register_user(user_params) do
{:ok, user} ->
{:ok, _} =
Accounts.deliver_user_confirmation_instructions(
user,
&url(~p"/users/confirm/#{&1}")
)
changeset = Accounts.change_user_registration(user)
{:noreply, socket |> assign(trigger_submit: true) |> assign_form(changeset)}
changeset = Accounts.change_user_registration(user)
{:noreply, socket |> assign(trigger_submit: true) |> assign_form(changeset)}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, socket |> assign(check_errors: true) |> assign_form(changeset)}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, socket |> assign(check_errors: true) |> assign_form(changeset)}
end
else
{:noreply, socket}
end
end

View file

@ -1,9 +1,22 @@
defmodule FreediveWeb.UserRegistrationLiveTest do
use FreediveWeb.ConnCase
alias Freedive.Features
import Phoenix.LiveViewTest
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
test "renders registration page", %{conn: conn} do
{:ok, _lv, html} = live(conn, ~p"/users/register")