Current section
Files
Jump to
Current section
Files
lib/ingot_web/plugs/require_auth.ex
defmodule IngotWeb.Plugs.RequireAuth do
@moduledoc """
Plug to require authentication for routes.
Validates the session and assigns current_user to conn.
Redirects to login page if authentication fails.
## Usage
# In router
pipeline :authenticated do
plug IngotWeb.Plugs.RequireAuth
end
# With custom redirect
pipeline :authenticated do
plug IngotWeb.Plugs.RequireAuth, redirect_to: "/login"
end
## Assigns
On successful authentication, assigns the following to conn:
* `:current_user` - Map containing user_id, email, and roles
"""
import Plug.Conn
import Phoenix.Controller, only: [redirect: 2, put_flash: 3]
alias Ingot.Auth
@type options :: keyword()
@doc false
@spec init(options()) :: options()
def init(opts), do: opts
@doc false
@spec call(Plug.Conn.t(), options()) :: Plug.Conn.t()
def call(conn, opts) do
redirect_path = Keyword.get(opts, :redirect_to, "/")
session_data = %{
user_id: get_session(conn, :user_id),
user_email: get_session(conn, :user_email),
roles: get_session(conn, :roles),
expires_at: get_session(conn, :expires_at)
}
case Auth.validate_session(session_data) do
{:ok, session} ->
current_user = %{
id: session.user_id,
email: session.user_email,
roles: session.roles
}
assign(conn, :current_user, current_user)
{:error, :expired} ->
conn
|> clear_session()
|> put_flash(:error, "Your session has expired. Please log in again.")
|> redirect(to: redirect_path)
|> halt()
{:error, :invalid_session} ->
conn
|> put_flash(:error, "You must be logged in to access this page.")
|> redirect(to: redirect_path)
|> halt()
end
end
end