Packages
guardian
0.5.2
2.4.0
2.3.2
2.3.1
2.3.0
2.2.4
2.2.3
2.2.2
2.2.1
2.2.0
2.1.2
2.1.1
2.0.0
1.2.1
1.2.0
retired
1.1.1
1.1.0
1.0.1
1.0.0
1.0.0-beta.1
1.0.0-beta.0
0.14.6
0.14.5
0.14.4
0.14.3
retired
0.14.2
0.14.1
0.14.0
0.13.0
0.12.0
0.11.1
0.10.1
0.10.0
0.9.1
0.9.0
0.8.1
0.8.0
0.7.4
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.0
0.4.1
0.4.0
0.3.1
0.3.0
0.2.0
0.1.1
0.1.0
Elixir Authentication framework
Current section
Files
Jump to
Current section
Files
lib/guardian/plug/ensure_permissions.ex
defmodule Guardian.Plug.EnsurePermissions do
@moduledoc """
Use this plug to ensure that there are the correct permissions set in the claims found on the connection.
### Example
plug Guardian.Plug.EnsurePermissions, admin: [:read, :write], on_failure: { SomeMod, :some_func } # read and write permissions for the admin set
plug Guardian.Plug.EnsurePermissions, admin: [:read, :write], default: [:profile], on_failure: { SomeMod, :some_func } # read AND write permissions for the admin set AND :profile for the default set
plug Guardian.Plug.EnsurePermissions, key: :secret, admin: [:read, :write], on_failure: { SomeMod, :some_func } # admin :read AND :write for the claims located in the :secret location
On failure will be handed the connection with the conn, and params where reason: :forbidden
"""
def init(opts) do
opts = Enum.into(opts, %{})
on_failure = Dict.get(opts, :on_failure)
key = Dict.get(opts, :key, :default)
perms = Dict.delete(opts, :on_failure) |> Dict.delete(:key)
case on_failure do
{ _mod, _meth } ->
%{
on_failure: on_failure,
key: key,
perm_keys: Dict.keys(perms),
perms: perms,
}
_ -> raise "Requires an on_failure function { Mod, :function_name }"
end
end
@doc false
def call(conn, opts) do
key = Dict.get(opts, :key)
case Guardian.Plug.claims(conn, key) do
{ :ok, claims } ->
perms = Dict.get(opts, :perms, %{})
result = Enum.all?(Dict.get(opts, :perm_keys), fn(perm_key) ->
found_perms = Guardian.Permissions.from_claims(claims, perm_key)
Guardian.Permissions.all?(found_perms, Dict.get(perms, perm_key), perm_key)
end)
if result, do: conn, else: handle_error(conn, opts)
{ :error, _ } -> handle_error(conn, opts)
end
end
defp handle_error(conn, opts) do
{ mod, meth } = Dict.get(opts, :on_failure)
apply(mod, meth, [conn, Dict.merge(conn.params, %{ reason: :forbidden })])
end
end