Guardian v1.2.1 Guardian.Permissions.Bitwise View Source

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.Bitwise

  # 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

To use a plug for ensuring permissions you can use the Guardian.Permissions.Bitwise 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.Bitwise, 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.Bitwise, 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.Bitwise, 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

Provides an encoded version of all permissions, and all possible future permissions for a permission set

Link to this section Types

Link to this type

input_label() View Source
input_label() :: String.t() | atom()

Link to this type

input_permissions() View Source
input_permissions() :: %{optional(input_label()) => input_set()}

Link to this type

input_set() View Source
input_set() :: [input_label(), ...] | pos_integer()

Link to this type

permission_set() View Source
permission_set() :: %{optional(label()) => pos_integer()}

Link to this type

plug_option() View Source
plug_option() ::
  {:ensure, permission_set()}
  | {:one_of, [permission_set(), ...]}
  | {:key, atom()}
  | {:module, module()}
  | {:error_handler, module()}

Link to this section Functions

Provides an encoded version of all permissions, and all possible future permissions for a permission set