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 conditionsread/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
@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
@callback can(Permit.Types.subject()) :: Permit.Types.permissions()