Packages
guardian
2.3.0
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/permissions/plug.ex
defmodule Guardian.Permissions.Plug do
@moduledoc false
alias Guardian.Plug.Pipeline
@doc false
@spec init([Guardian.Permissions.plug_option()]) :: [Guardian.Permissions.plug_option()]
def init(opts) do
ensure = Keyword.has_key?(opts, :ensure)
one_of = Keyword.has_key?(opts, :one_of)
if ensure and one_of do
raise "`:ensure` and `:one_of` cannot both be specified for plug #{to_string(__MODULE__)}."
end
if ensure do
ensure_map =
opts
|> Keyword.get(:ensure, [])
|> Enum.into(%{})
Keyword.put(opts, :ensure, ensure_map)
else
opts
end
end
@doc false
@spec call(conn :: Plug.Conn.t(), opts :: Keyword.t()) :: Plug.Conn.t()
def call(conn, opts) do
context = %{
claims: Guardian.Plug.current_claims(conn, opts),
ensure: Keyword.get(opts, :ensure),
handler: Pipeline.fetch_error_handler!(conn, opts),
impl: Pipeline.fetch_module!(conn, opts),
one_of: Keyword.get(opts, :one_of)
}
check_permissions(conn, context, opts)
end
defp check_permissions(conn, %{ensure: nil, one_of: nil}, _), do: conn
defp check_permissions(conn, %{claims: nil, handler: handler}, opts) do
handle_response(false, conn, :missing_claims, handler, opts)
end
# Ensure permissions
defp check_permissions(conn, %{claims: claims, ensure: ensure, handler: handler, impl: impl, one_of: nil}, opts) do
has_perms = apply(impl, :decode_permissions_from_claims, [claims])
impl
|> apply(:all_permissions?, [has_perms, ensure])
|> handle_response(conn, :insufficient_permission, handler, opts)
end
# One_of permissions
defp check_permissions(conn, %{claims: claims, ensure: nil, handler: handler, impl: impl, one_of: one_of}, opts) do
has_perms = apply(impl, :decode_permissions_from_claims, [claims])
one_of
|> Enum.any?(&apply(impl, :all_permissions?, [has_perms, &1]))
|> handle_response(conn, :insufficient_permission, handler, opts)
end
defp handle_response(true, conn, _reason, _handler, _opts),
do: conn
defp handle_response(false, conn, reason, handler, opts),
do: apply(handler, :auth_error, [conn, {:unauthorized, reason}, opts])
end