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], 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"],

View file

@ -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 """

View file

@ -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
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,8 +3,10 @@ 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
if Features.enabled?(:register_account) do
~H""" ~H"""
<div class="mx-auto max-w-sm"> <div class="mx-auto max-w-sm">
<.header class="text-center"> <.header class="text-center">
@ -40,6 +42,18 @@ defmodule FreediveWeb.UserRegistrationLive do
</.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,6 +68,7 @@ defmodule FreediveWeb.UserRegistrationLive do
end end
def handle_event("save", %{"user" => user_params}, socket) do def handle_event("save", %{"user" => user_params}, socket) do
if Features.enabled?(:register_account) do
case Accounts.register_user(user_params) do case Accounts.register_user(user_params) do
{:ok, user} -> {:ok, user} ->
{:ok, _} = {:ok, _} =
@ -68,6 +83,9 @@ defmodule FreediveWeb.UserRegistrationLive do
{: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 end
else
{:noreply, socket}
end
end end
def handle_event("validate", %{"user" => user_params}, socket) do def handle_event("validate", %{"user" => user_params}, socket) do

View file

@ -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")