Add authorisation plug
This commit is contained in:
parent
626063ee76
commit
37985ac1cf
1 changed files with 52 additions and 0 deletions
52
lib/real_estate_web/plugs/ensure_role_plug.ex
Normal file
52
lib/real_estate_web/plugs/ensure_role_plug.ex
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
defmodule RealEstateWeb.EnsureRolePlug do
|
||||||
|
@moduledoc """
|
||||||
|
This plug ensures that a user has a particular role before accessing a given route.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
Let's suppose we have three roles: :admin, :manager and :user.
|
||||||
|
|
||||||
|
If you want a user to have at least manager role, so admins and managers are authorised to access a given route
|
||||||
|
plug RealEstateWeb.EnsureRolePlug, [:admin, :manager]
|
||||||
|
|
||||||
|
If you want to give access only to an admin:
|
||||||
|
plug RealEstateWeb.EnsureRolePlug, :admin
|
||||||
|
"""
|
||||||
|
import Plug.Conn
|
||||||
|
|
||||||
|
alias RealEstate.Accounts
|
||||||
|
alias RealEstate.Accounts.User
|
||||||
|
alias Phoenix.Controller
|
||||||
|
alias Plug.Conn
|
||||||
|
|
||||||
|
@doc false
|
||||||
|
@spec init(any()) :: any()
|
||||||
|
def init(config), do: config
|
||||||
|
|
||||||
|
@doc false
|
||||||
|
@spec call(Conn.t(), atom() | [atom()]) :: Conn.t()
|
||||||
|
def call(conn, roles) do
|
||||||
|
user_token = get_session(conn, :user_token)
|
||||||
|
|
||||||
|
(user_token &&
|
||||||
|
Accounts.get_user_by_session_token(user_token))
|
||||||
|
|> has_role?(roles)
|
||||||
|
|> maybe_halt(conn)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp has_role?(%User{} = user, roles) when is_list(roles),
|
||||||
|
do: Enum.any?(roles, &has_role?(user, &1))
|
||||||
|
|
||||||
|
defp has_role?(%User{role: role}, role), do: true
|
||||||
|
defp has_role?(_user, _role), do: false
|
||||||
|
|
||||||
|
defp maybe_halt(true, conn), do: conn
|
||||||
|
|
||||||
|
defp maybe_halt(_any, conn) do
|
||||||
|
conn
|
||||||
|
|> Controller.put_flash(:error, "Unauthorised")
|
||||||
|
|> Controller.redirect(to: signed_in_path(conn))
|
||||||
|
|> halt()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp signed_in_path(_conn), do: "/"
|
||||||
|
end
|
Loading…
Reference in a new issue