update controllers and auth

This commit is contained in:
2022-02-25 21:53:04 -05:00
committed by oliviasculley
parent 41090c46d0
commit 74bcec6cfe
13 changed files with 256 additions and 63 deletions

View File

@ -0,0 +1,23 @@
defmodule LokalWeb.EmailController do
@moduledoc """
A dev controller used to develop on emails
"""
use LokalWeb, :controller
alias Lokal.Accounts.User
plug :put_layout, {LokalWeb.LayoutView, :email}
@sample_assigns %{
email: %{subject: "Example subject"},
url: "https://lokal.bubbletea.dev/sample_url",
user: %User{email: "sample@email.com"}
}
@doc """
Debug route used to preview emails
"""
def preview(conn, %{"id" => template}) do
render(conn, "#{template |> to_string()}.html", @sample_assigns)
end
end

View File

@ -1,12 +1,13 @@
defmodule LokalWeb.UserAuth do
@moduledoc """
Module for any user authentication functions
Functions for user session and authentication
"""
import Plug.Conn
import Phoenix.Controller
import LokalWeb.Gettext
alias Lokal.{Accounts, Accounts.User}
alias LokalWeb.PageLive
alias LokalWeb.Router.Helpers, as: Routes
# Make the remember me cookie valid for 60 days.
@ -32,6 +33,7 @@ defmodule LokalWeb.UserAuth do
def log_in_user(conn, %User{confirmed_at: nil}, _params) do
conn
|> fetch_flash()
|> put_flash(
:error,
dgettext("errors", "You must confirm your account and log in to access this page.")
@ -53,6 +55,11 @@ defmodule LokalWeb.UserAuth do
|> redirect(to: user_return_to || signed_in_path(conn))
end
@spec maybe_write_remember_me_cookie(
Plug.Conn.t(),
String.t() | any(),
%{required(String.t()) => String.t()} | any()
) :: Plug.Conn.t()
defp maybe_write_remember_me_cookie(conn, token, %{"remember_me" => "true"}) do
put_resp_cookie(conn, @remember_me_cookie, token, @remember_me_options)
end
@ -149,13 +156,31 @@ defmodule LokalWeb.UserAuth do
conn
else
conn
|> put_flash(:error, "You must confirm your account and 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()
end
end
@doc """
Used for routes that require the user to be an admin.
"""
def require_role(conn, role: role_atom) do
if conn.assigns[:current_user] && conn.assigns.current_user.role == role_atom do
conn
else
conn
|> put_flash(:error, dgettext("errors", "You are not authorized to view this page."))
|> maybe_store_return_to()
|> redirect(to: Routes.live_path(conn, PageLive))
|> halt()
end
end
defp maybe_store_return_to(%{method: "GET"} = conn) do
put_session(conn, :user_return_to, current_path(conn))
end

View File

@ -1,10 +1,11 @@
defmodule LokalWeb.UserConfirmationController do
use LokalWeb, :controller
import LokalWeb.Gettext
alias Lokal.Accounts
def new(conn, _params) do
render(conn, "new.html")
render(conn, "new.html", page_title: gettext("Confirm your account"))
end
def create(conn, %{"user" => %{"email" => email}}) do
@ -19,8 +20,11 @@ defmodule LokalWeb.UserConfirmationController do
conn
|> put_flash(
:info,
"If your email is in our system and it has not been confirmed yet, " <>
"you will receive an email with instructions shortly."
dgettext(
"prompts",
"If your email is in our system and it has not been confirmed yet, " <>
"you will receive an email with instructions shortly."
)
)
|> redirect(to: "/")
end
@ -29,9 +33,9 @@ defmodule LokalWeb.UserConfirmationController do
# leaked token giving the user access to the account.
def confirm(conn, %{"token" => token}) do
case Accounts.confirm_user(token) do
{:ok, _} ->
{:ok, %{email: email}} ->
conn
|> put_flash(:info, "User confirmed successfully.")
|> put_flash(:info, dgettext("prompts", "%{email} confirmed successfully.", email: email))
|> redirect(to: "/")
:error ->
@ -45,7 +49,10 @@ defmodule LokalWeb.UserConfirmationController do
%{} ->
conn
|> put_flash(:error, "User confirmation link is invalid or it has expired.")
|> put_flash(
:error,
dgettext("errors", "User confirmation link is invalid or it has expired.")
)
|> redirect(to: "/")
end
end

View File

@ -1,30 +1,81 @@
defmodule LokalWeb.UserRegistrationController do
use LokalWeb, :controller
alias Lokal.Accounts
import LokalWeb.Gettext
alias Lokal.{Accounts, Invites}
alias Lokal.Accounts.User
alias LokalWeb.UserAuth
alias LokalWeb.{Endpoint, PageLive}
def new(conn, _params) do
changeset = Accounts.change_user_registration(%User{})
render(conn, "new.html", changeset: changeset)
def new(conn, %{"invite" => invite_token}) do
invite = Invites.get_invite_by_token(invite_token)
if invite do
conn |> render_new(invite)
else
conn
|> put_flash(:error, dgettext("errors", "Sorry, this invite was not found or expired"))
|> redirect(to: Routes.live_path(Endpoint, PageLive))
end
end
def create(conn, %{"user" => user_params}) do
def new(conn, _params) do
if Accounts.allow_registration?() do
conn |> render_new()
else
conn
|> put_flash(:error, dgettext("errors", "Sorry, public registration is disabled"))
|> redirect(to: Routes.live_path(Endpoint, PageLive))
end
end
# renders new user registration page
defp render_new(conn, invite \\ nil) do
render(conn, "new.html",
changeset: Accounts.change_user_registration(%User{}),
invite: invite,
page_title: gettext("Register")
)
end
def create(conn, %{"user" => %{"invite_token" => invite_token}} = attrs) do
invite = Invites.get_invite_by_token(invite_token)
if invite do
conn |> create_user(attrs, invite)
else
conn
|> put_flash(:error, dgettext("errors", "Sorry, this invite was not found or expired"))
|> redirect(to: Routes.live_path(Endpoint, PageLive))
end
end
def create(conn, attrs) do
if Accounts.allow_registration?() do
conn |> create_user(attrs)
else
conn
|> put_flash(:error, dgettext("errors", "Sorry, public registration is disabled"))
|> redirect(to: Routes.live_path(Endpoint, PageLive))
end
end
defp create_user(conn, %{"user" => user_params}, invite \\ nil) do
case Accounts.register_user(user_params) do
{:ok, user} ->
{:ok, _} =
Accounts.deliver_user_confirmation_instructions(
user,
&Routes.user_confirmation_url(conn, :confirm, &1)
)
unless invite |> is_nil() do
invite |> Invites.use_invite!()
end
Accounts.deliver_user_confirmation_instructions(
user,
&Routes.user_confirmation_url(conn, :confirm, &1)
)
conn
|> put_flash(:info, "User created successfully.")
|> UserAuth.log_in_user(user)
|> put_flash(:info, dgettext("prompts", "Please check your email to verify your account"))
|> redirect(to: Routes.user_session_path(Endpoint, :new))
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, "new.html", changeset: changeset)
conn |> render("new.html", changeset: changeset, invite: invite)
end
end
end

View File

@ -6,7 +6,7 @@ defmodule LokalWeb.UserResetPasswordController do
plug :get_user_by_reset_password_token when action in [:edit, :update]
def new(conn, _params) do
render(conn, "new.html")
render(conn, "new.html", page_title: gettext("Forgot your password?"))
end
def create(conn, %{"user" => %{"email" => email}}) do
@ -21,13 +21,20 @@ defmodule LokalWeb.UserResetPasswordController do
conn
|> put_flash(
:info,
"If your email is in our system, you will receive instructions to reset your password shortly."
dgettext(
"prompts",
"If your email is in our system, you will receive instructions to " <>
"reset your password shortly."
)
)
|> redirect(to: "/")
end
def edit(conn, _params) do
render(conn, "edit.html", changeset: Accounts.change_user_password(conn.assigns.user))
render(conn, "edit.html",
changeset: Accounts.change_user_password(conn.assigns.user),
page_title: gettext("Reset your password")
)
end
# Do not log in the user after reset password to avoid a
@ -36,7 +43,7 @@ defmodule LokalWeb.UserResetPasswordController do
case Accounts.reset_user_password(conn.assigns.user, user_params) do
{:ok, _} ->
conn
|> put_flash(:info, "Password reset successfully.")
|> put_flash(:info, dgettext("prompts", "Password reset successfully."))
|> redirect(to: Routes.user_session_path(conn, :new))
{:error, changeset} ->
@ -51,7 +58,10 @@ defmodule LokalWeb.UserResetPasswordController do
conn |> assign(:user, user) |> assign(:token, token)
else
conn
|> put_flash(:error, "Reset password link is invalid or it has expired.")
|> put_flash(
:error,
dgettext("errors", "Reset password link is invalid or it has expired.")
)
|> redirect(to: "/")
|> halt()
end

View File

@ -5,7 +5,7 @@ defmodule LokalWeb.UserSessionController do
alias LokalWeb.UserAuth
def new(conn, _params) do
render(conn, "new.html", error_message: nil)
render(conn, "new.html", error_message: nil, page_title: gettext("Log in"))
end
def create(conn, %{"user" => user_params}) do
@ -14,13 +14,13 @@ defmodule LokalWeb.UserSessionController do
if user = Accounts.get_user_by_email_and_password(email, password) do
UserAuth.log_in_user(conn, user, user_params)
else
render(conn, "new.html", error_message: "Invalid email or password")
render(conn, "new.html", error_message: dgettext("errors", "Invalid email or password"))
end
end
def delete(conn, _params) do
conn
|> put_flash(:info, "Logged out successfully.")
|> put_flash(:info, dgettext("prompts", "Logged out successfully."))
|> UserAuth.log_out_user()
end
end

View File

@ -1,13 +1,13 @@
defmodule LokalWeb.UserSettingsController do
use LokalWeb, :controller
import LokalWeb.Gettext
alias Lokal.Accounts
alias LokalWeb.UserAuth
alias LokalWeb.{PageLive, UserAuth}
plug :assign_email_and_password_changesets
def edit(conn, _params) do
render(conn, "edit.html")
render(conn, "edit.html", page_title: gettext("Settings"))
end
def update(conn, %{"action" => "update_email"} = params) do
@ -25,7 +25,10 @@ defmodule LokalWeb.UserSettingsController do
conn
|> put_flash(
:info,
"A link to confirm your email change has been sent to the new address."
dgettext(
"prompts",
"A link to confirm your email change has been sent to the new address."
)
)
|> redirect(to: Routes.user_settings_path(conn, :edit))
@ -41,7 +44,7 @@ defmodule LokalWeb.UserSettingsController do
case Accounts.update_user_password(user, password, user_params) do
{:ok, user} ->
conn
|> put_flash(:info, "Password updated successfully.")
|> put_flash(:info, dgettext("prompts", "Password updated successfully."))
|> put_session(:user_return_to, Routes.user_settings_path(conn, :edit))
|> UserAuth.log_in_user(user)
@ -54,16 +57,33 @@ defmodule LokalWeb.UserSettingsController do
case Accounts.update_user_email(conn.assigns.current_user, token) do
:ok ->
conn
|> put_flash(:info, "Email changed successfully.")
|> put_flash(:info, dgettext("prompts", "Email changed successfully."))
|> redirect(to: Routes.user_settings_path(conn, :edit))
:error ->
conn
|> put_flash(:error, "Email change link is invalid or it has expired.")
|> put_flash(
:error,
dgettext("errors", "Email change link is invalid or it has expired.")
)
|> redirect(to: Routes.user_settings_path(conn, :edit))
end
end
def delete(%{assigns: %{current_user: current_user}} = conn, %{"id" => user_id}) do
if user_id == current_user.id do
current_user |> Accounts.delete_user!(current_user)
conn
|> put_flash(:error, dgettext("prompts", "Your account has been deleted"))
|> redirect(to: Routes.live_path(conn, PageLive))
else
conn
|> put_flash(:error, dgettext("errors", "Unable to delete user"))
|> redirect(to: Routes.user_settings_path(conn, :edit))
end
end
defp assign_email_and_password_changesets(conn, _opts) do
user = conn.assigns.current_user