From 8f807c2ebc77ce89d2b2b4e62ebe46c78b01b471 Mon Sep 17 00:00:00 2001 From: shibao Date: Wed, 16 Feb 2022 22:17:26 -0500 Subject: [PATCH] prevent unconfirmed users from logging in --- lib/cannery/accounts.ex | 5 +++-- lib/cannery_web/controllers/user_auth.ex | 16 +++++++++++++--- test/support/conn_case.ex | 9 +++++++-- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/lib/cannery/accounts.ex b/lib/cannery/accounts.ex index e703d029..454ef4a2 100644 --- a/lib/cannery/accounts.ex +++ b/lib/cannery/accounts.ex @@ -111,7 +111,8 @@ defmodule Cannery.Accounts do # if no registered users, make first user an admin role = if Repo.one!(from u in User, select: count(u.id), distinct: true) == 0, - do: "admin", else: "user" + do: "admin", + else: "user" %User{} |> User.registration_changeset(attrs |> Map.put("role", role)) |> Repo.insert() end @@ -376,7 +377,7 @@ defmodule Cannery.Accounts do end @spec confirm_user_multi(User.t()) :: Multi.t() - defp confirm_user_multi(user) do + def confirm_user_multi(user) do Multi.new() |> Multi.update(:user, User.confirm_changeset(user)) |> Multi.delete_all(:tokens, UserToken.user_and_contexts_query(user, ["confirm"])) diff --git a/lib/cannery_web/controllers/user_auth.ex b/lib/cannery_web/controllers/user_auth.ex index 3c362ccd..03394897 100644 --- a/lib/cannery_web/controllers/user_auth.ex +++ b/lib/cannery_web/controllers/user_auth.ex @@ -6,7 +6,7 @@ defmodule CanneryWeb.UserAuth do import Plug.Conn import Phoenix.Controller import CanneryWeb.Gettext - alias Cannery.Accounts + alias Cannery.{Accounts, Accounts.User} alias CanneryWeb.HomeLive alias CanneryWeb.Router.Helpers, as: Routes @@ -29,7 +29,17 @@ defmodule CanneryWeb.UserAuth do disconnected on log out. The line can be safely removed if you are not using LiveView. """ - def log_in_user(conn, user, params \\ %{}) do + def log_in_user(conn, user, params \\ %{}) + + def log_in_user(conn, %User{confirmed_at: nil}, params) do + conn + |> put_flash(:error, dgettext("errors", "You must confirm your account and log in to access this page.")) + |> maybe_store_return_to() + |> redirect(to: Routes.user_session_path(conn, :new)) + |> halt() + end + + def log_in_user(conn, user, params) do token = Accounts.generate_user_session_token(user) user_return_to = get_session(conn, :user_return_to) @@ -142,7 +152,7 @@ defmodule CanneryWeb.UserAuth do conn else conn - |> put_flash(:error, dgettext("errors", "You must log in to access this page.")) + |> put_flash(:error, dgettext("errors", "You must confirm your account and log in to access this page.")) |> maybe_store_return_to() |> redirect(to: Routes.user_session_path(conn, :new)) |> halt() diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex index 1d87d4d5..2515d60e 100644 --- a/test/support/conn_case.ex +++ b/test/support/conn_case.ex @@ -17,6 +17,7 @@ defmodule CanneryWeb.ConnCase do use ExUnit.CaseTemplate import Cannery.Fixtures + alias Cannery.{Accounts, Repo} alias Ecto.Adapters.SQL.Sandbox using do @@ -49,8 +50,12 @@ defmodule CanneryWeb.ConnCase do test context. """ def register_and_log_in_user(%{conn: conn}) do - user = user_fixture() - %{conn: log_in_user(conn, user), user: user} + current_user = user_fixture() + + {:ok, %{user: current_user}} = + current_user |> Accounts.confirm_user_multi() |> Repo.transaction() + + %{conn: log_in_user(conn, current_user), current_user: current_user} end @doc """