View Source Guardian.Permissions (Guardian v2.3.2)
An optional plugin to Guardian to provide permissions for your tokens.
These can be used for any token types since they only work on the claims
.
Permissions are set on a per implementation module basis. Each implementation module can have their own sets. Permissions are similar in concept to OAuth2 scopes. They're encoded into a token and the permissions granted last as long as the token does. This makes it unsuitable for highly dynamic permission schemes. They're best left to an application to implement.
For example. (at the time of writing) some of the Facebook permissions are:
- public_profile
- user_about_me
- user_actions.books
- user_actions.fitness
- user_actions.music
To create permissions for your application similar to these:
defmodule MyApp.Auth.Token do
use Guardian, otp_app: :my_app,
permissions: %{
default: [:public_profile, :user_about_me]
user_actions: %{
books: 0b1,
fitness: 0b100,
music: 0b1000,
}
}
use Guardian.Permissions, encoding: Guardian.Permissions.BitwiseEncoding
# Per default permissions will be encoded Bitwise, but other encoders also exist
# * Guardian.Permissions.TextEncoding
# * Guardian.Permissions.AtomEncoding
# It is even possible to supply your own encoding module
# snip
def build_claims(claims, _resource, opts) do
claims =
claims
|> encode_permissions_into_claims!(Keyword.get(opts, :permissions))
{:ok, claims}
end
end
This will take the permission set in the opts
at :permissions
and
put it into the "pems"
key of the claims as a map of %{set_name => integer}
.
The permissions can be defined as a list (positional value based on index) or a map where the value for each permission is manually provided.
They can be provided either as options to use Guardian
or in the config for
your implementation module.
Once you have a token, you can interact with it.
# Get the encoded permissions from the claims
found_perms = MyApp.Auth.Token.decode_permissions_from_claims(claims)
# Check if all permissions are present
has_all_these_things? =
claims
|> MyApp.Auth.Token.decode_permissions_from_claims
|> MyApp.Auth.Token.all_permissions?(%{default: [:user_about_me, :public_profile]})
# Checks if any permissions are present
show_any_media_things? =
claims
|> MyApp.Auth.Token.decode_permissions_from_claims
|> MyApp.Auth.Token.any_permissions?(%{user_actions: [:books, :fitness, :music]})
using-with-plug
Using with Plug
To use a plug for ensuring permissions you can use the Guardian.Permissions
module as part of a
Guardian pipeline.
# After a pipeline has setup the implementation module and error handler
# Ensure that both the `public_profile` and `user_actions.books` permissions
# are present in the token
plug Guardian.Permissions, ensure: %{default: [:public_profile], user_actions: [:books]}
# Allow the request to continue when the token contains any of the permission sets specified
plug Guardian.Permissions, one_of: [
%{default: [:public_profile], user_actions: [:books]},
%{default: [:public_profile], user_actions: [:music]},
]
# Look for permissions for a token in a different location
plug Guardian.Permissions, key: :impersonate, ensure: %{default: [:public_profile]}
If the token satisfies either the permissions listed in ensure
or one of
the sets in the one_of
key the request will continue. If not, then
auth_error
callback will be called on the error handler with
auth_error(conn, {:unauthorized, reason}, options)
.
Link to this section Summary
Functions
See Guardian.Permissions.Plug.call/2
.
See Guardian.Permissions.Plug.init/1
.
Provides an encoded version of all permissions, and all possible future permissions for a permission set.
Link to this section Types
@type input_label() :: permission_label()
@type input_permissions() :: %{optional(input_label()) => input_set()}
@type input_set() :: permission_set() | permission()
@type label() :: atom()
@type permission() :: pos_integer()
@type permission_set() :: [permission_label(), ...] | %{optional(label()) => permission()}
@type plug_option() :: {:ensure, permission_set()} | {:one_of, [permission_set(), ...]} | {:key, atom()} | {:module, module()} | {:error_handler, module()}
@type t() :: %{optional(label()) => permission_set()}
Link to this section Functions
See Guardian.Permissions.Plug.call/2
.
See Guardian.Permissions.Plug.init/1
.
Provides an encoded version of all permissions, and all possible future permissions for a permission set.