Packages
Provides a full user authentication experience for an API. Includes login,logout,register,forgot password, forgot username, confirmation email and all that other good stuff. Includes plug for checking for authenticated users and macro for generating the required routes.
Current section
Files
Jump to
Current section
Files
lib/access_pass/plug.ex
defmodule AccessPass.Auth do
@moduledoc """
Plug that checks for access_token in header and then checks if its expired or revoked.
If it's not expired/revoked it adds the stored data from the token in meta.
If it is then it returns 401 unauthorized and halts the plug.
You can pass confirmed: true on the plug to only auth if the users email has been confirmed.
"""
import Plug.Conn
def init(opts \\ %{}) do
opts
end
def call(conn, confirmed: true) do
token = conn |> getHeaderValue("access_token")
case AccessPass.logged?(token) do
{:ok, data} -> email_confirmation_check(conn, data)
{:error, _} -> conn |> send_resp(401, "unauthorized") |> halt()
end
end
def call(conn, _) do
token = conn |> getHeaderValue("access_token")
case AccessPass.logged?(token) do
{:ok, data} -> conn |> assign(:data, data)
{:error, _} -> conn |> send_resp(401, "unauthorized") |> halt()
end
end
defp email_confirmation_check(conn, %{email_confirmed: false}) do
conn |> send_resp(401, "email address not confirmed") |> halt()
end
defp email_confirmation_check(conn, %{email_confirmed: true} = data) do
conn |> assign(:data, data)
end
defp email_confirmation_check(conn, _), do: conn |> send_resp(401, "unauthorized") |> halt()
defp getHeaderValue(conn, val) do
case conn |> get_req_header(val) do
[val] -> val
_ -> nil
end
end
end
defmodule AccessPass.AuthExtended do
@moduledoc """
Plug that checks for access_token in header and then checks if its expired or revoked.
If it's not expired/revoked it adds the stored data from the token in meta.
If it is then it returns 401 unauthorized and halts the plug.
You can pass any number of arguments in keyword list format to match against the users
meta obj that is stored on registration. An example use case is for role based auth.
"""
import Plug.Conn
def init(opts \\ %{}) do
opts
end
def call(conn, keyword_list) do
token = conn |> getHeaderValue("access_token")
case AccessPass.logged?(token) do
{:ok, data} -> extended_auth(conn, data, keyword_list)
{:error, _} -> conn |> send_resp(401, "unauthorized") |> halt()
end
end
defp extended_auth(conn, data, keyword_list) do
case Enum.all?(keyword_list, fn {key, val} ->
get_in(data, [:meta, Atom.to_string(key)]) == val
end) do
true -> conn |> assign(:data, data)
false -> conn |> send_resp(401, "unauthorized") |> halt()
end
end
defp getHeaderValue(conn, val) do
case conn |> get_req_header(val) do
[val] -> val
_ -> nil
end
end
end