View Source Permit.Permissions behaviour (permit v0.2.0)

Defines the application's permission set. When used with Permit.Ecto, one should use Permit.Ecto.Permissions instead of Permit.Permissions.

The behaviour defines the can/1 callback, which must be implemented for defining permissions for a given subject.

The module's __using__/1 macro creates functions for each action defined in the module specified as the macro's option, defaulting to Permit.Actions.CrudActions.

Usage

A very simple usage example:

defmodule MyApp.Permissions do
  use Permit.Permissions, actions_module: Permit.Actions.CrudActions

  @impl true
  def can(%MyApp.User{role: :admin}) do
    permit()
    |> all(Article)
  end

  def can(%MyApp.User{id: user_id}) do
    permit()
    |> read(Article)
    |> all(Article, author_id: user_id)
  end

  def can(_), do: permit()
end

Named action functions

Each action defined in the :actions_module results in a 2-, 3-, and 4-arity function being generated.

For instance, if a :read action is defined, there are the following calls available to grant the :read permission on a given resource type:

  • read/2 function - grants permission without additional conditions
  • read/3 function - with conditions defined using keywords and operators (see below),
  • read/4 macro - with conditions defined using keywords, operators and bindings (see below).

Example

def can(%User{id: user_id}) do
  permit()
  |> read(Article, author_id: user_id)
  |> vote(Article, vote_count: {:<=, 100})
  |> review(Article, [user, article], user.level >= article.level)
end

permission_to functions

Instead of action names, if more convenient, permission_to can be used, and the action name passed as an argument.

Example

def can(%User{id: user_id}) do
  permit()
  |> permission_to(:read, Article, author_id: user_id)
  |> permission_to(:vote, Article, vote_count: {:<=, 100})
  |> permission_to(:review, Article, [user, article], user.level >= article.level)
end

all functions

In order to grant the user permission to all defined actions, use the all functions.

Example

def can(%User{id: user_id}) do
  permit()
  |> all(Article, author_id: user_id)
  |> all(Article, vote_count: {:<=, 100})
  |> all(Article, [user, article], user.level >= article.level)
end

Summary

Types

Link to this type

conditions_by_action_and_resource()

View Source
@type conditions_by_action_and_resource() :: %{
  required({Permit.Types.action_group(), Permit.Types.resource_module()}) =>
    Permit.Permissions.DisjunctiveNormalForm.t()
}
@type t() :: %Permit.Permissions{conditions_map: conditions_by_action_and_resource()}

Callbacks

Functions

Link to this function

parse_conditions(bindings, condition, condition_parser)

View Source