Gate registration to ALLOWED_REGISTRATION_EMAIL

This commit is contained in:
Willem van den Ende
2026-04-01 21:39:15 +00:00
parent df20c478f4
commit 86f7ffbe94
5 changed files with 62 additions and 16 deletions
+2
View File
@@ -20,6 +20,8 @@ if System.get_env("PHX_SERVER") do
config :firehose, FirehoseWeb.Endpoint, server: true
end
config :firehose, :allowed_registration_email, System.get_env("ALLOWED_REGISTRATION_EMAIL")
if config_env() == :prod do
database_url =
System.get_env("DATABASE_URL") ||
+2
View File
@@ -38,3 +38,5 @@ config :phoenix, :plug_init_mode, :runtime
# Enable helpful, but potentially expensive runtime checks
config :phoenix_live_view,
enable_expensive_runtime_checks: true
config :firehose, :allowed_registration_email, nil
@@ -10,23 +10,35 @@ defmodule FirehoseWeb.UserRegistrationController do
end
def create(conn, %{"user" => user_params}) do
case Accounts.register_user(user_params) do
{:ok, user} ->
{:ok, _} =
Accounts.deliver_login_instructions(
user,
&url(~p"/users/log-in/#{&1}")
allowed_email = Application.get_env(:firehose, :allowed_registration_email)
if allowed_email == nil or user_params["email"] != allowed_email do
changeset =
%User{}
|> Accounts.change_user_email(user_params)
|> Ecto.Changeset.add_error(:email, "registration is invite only.")
|> Map.put(:action, :validate)
render(conn, :new, changeset: changeset)
else
case Accounts.register_user(user_params) do
{:ok, user} ->
{:ok, _} =
Accounts.deliver_login_instructions(
user,
&url(~p"/users/log-in/#{&1}")
)
conn
|> put_flash(
:info,
"An email was sent to #{user.email}, please access it to confirm your account."
)
|> redirect(to: ~p"/users/log-in")
conn
|> put_flash(
:info,
"An email was sent to #{user.email}, please access it to confirm your account."
)
|> redirect(to: ~p"/users/log-in")
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, :new, changeset: changeset)
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, :new, changeset: changeset)
end
end
end
end
@@ -23,6 +23,8 @@ defmodule FirehoseWeb.UserRegistrationControllerTest do
@tag :capture_log
test "creates account but does not log in", %{conn: conn} do
email = unique_user_email()
Application.put_env(:firehose, :allowed_registration_email, email)
on_exit(fn -> Application.delete_env(:firehose, :allowed_registration_email) end)
conn =
post(conn, ~p"/users/register", %{
@@ -37,6 +39,9 @@ defmodule FirehoseWeb.UserRegistrationControllerTest do
end
test "render errors for invalid data", %{conn: conn} do
Application.put_env(:firehose, :allowed_registration_email, "with spaces")
on_exit(fn -> Application.delete_env(:firehose, :allowed_registration_email) end)
conn =
post(conn, ~p"/users/register", %{
"user" => %{"email" => "with spaces"}
@@ -47,4 +52,29 @@ defmodule FirehoseWeb.UserRegistrationControllerTest do
assert response =~ "must have the @ sign and no spaces"
end
end
describe "POST /users/register with email gating" do
test "succeeds when email matches ALLOWED_REGISTRATION_EMAIL", %{conn: conn} do
Application.put_env(:firehose, :allowed_registration_email, "allowed@example.com")
on_exit(fn -> Application.delete_env(:firehose, :allowed_registration_email) end)
conn = post(conn, ~p"/users/register", %{"user" => %{"email" => "allowed@example.com"}})
assert Phoenix.Flash.get(conn.assigns.flash, :info) =~ "email was sent"
end
test "fails with invite-only message when email doesn't match", %{conn: conn} do
Application.put_env(:firehose, :allowed_registration_email, "allowed@example.com")
on_exit(fn -> Application.delete_env(:firehose, :allowed_registration_email) end)
conn = post(conn, ~p"/users/register", %{"user" => %{"email" => "other@example.com"}})
assert html_response(conn, 200) =~ "registration is invite only"
end
test "fails with invite-only message when env var is unset", %{conn: conn} do
Application.delete_env(:firehose, :allowed_registration_email)
conn = post(conn, ~p"/users/register", %{"user" => %{"email" => "anyone@example.com"}})
assert html_response(conn, 200) =~ "registration is invite only"
end
end
end