View Source Permit.Actions behaviour (permit v0.2.0)
Overview
The Permit.Actions
behaviour defines an exhaustive set of actions that can be performed on resources in the business domain.
Actions can be grouped using the grouping_schema/0
callback, which is useful when the developer intends to define permissions that imply that multiple actions will be authorized. For instance, in the Permit.Phoenix
library, granting the :read
permission results in the :index
and :show
actions being authorized.
Permit includes a predefined Permit.Actions.CrudActions
module that defines four basic CRUD actions: create
, read
, update
and delete
.
Permit.Permissions
generates functions for each of defined CRUD action names, as shorthands to define permissions to perform them - as well as an all
function to permit all possible actions.
Moreover, the singular_actions/0
callback can be implemented to declare which actions are of singular nature, and which are of plural nature - for instance, an :index
action is typically plural and a :show
action is typically singular. This means that if automatic preloading mechanisms are in place, :index
will load many records, and :show
will load a single record.
Example
For instance, to make an :index
action separate from a :read
action, you may define an additional :open
action and define :index
as requiring only :read
, and :show
as requiring both :open
and :read
.
defmodule MyApp.Actions do
use Permit.Actions
@impl Permit.Actions
def grouping_schema do
crud_grouping() # Includes :create, :read, :update and :delete
|> Map.merge(%{
index: [:read],
# This is a 'plain' action not dependent on any other one, i.e. permission to these can be assigned directly
open: []
# This indicates that for the :show action to be performed, the :read AND open permissions must be granted.
show: [:read, :open]
})
end
end
Declaring permissions basing on defined actions:
defmodule MyApp.Permissions do
use Permit.Permissions, actions_module: MyApp.Actions
# An admin will be able to perform all actions on Note
def can(%User{role: :admin} = _user) do
permit()
|> all(Note)
end
# A user will be able
def can(%User{id: user_id} = _user) do
permit()
|> read(Note)
|> open(Note, user_id: user_id)
end
def can(_), do: permit()
end
Summary
Callbacks
Used for mapping business domain actions to conjunctions of permissions required to perform them.
Declares which actions are singular, and which are plural.
Callbacks
@callback grouping_schema() :: %{ required(Permit.Types.action_group()) => [Permit.Types.action_group()] }
Used for mapping business domain actions to conjunctions of permissions required to perform them.
In the example below, granting :read
and :open
means that :show
action can be performed. Note, though, that this is a one-way implication - :show
permission can be granted, but it does not imply that :read
or :open
are granted.
Example
@impl Permit.Actions
def grouping_schema do
crud_grouping() # Includes :create, :read, :update and :delete
|> Map.merge(%{
index: [:read],
# This is a 'plain' action not dependent on any other one, i.e. permission to these can be assigned directly
open: []
# This indicates that for the :show action to be performed, the :read AND :open permissions must be granted.
show: [:read, :open]
})
end
@callback singular_actions() :: [Permit.Types.action_group()]
Declares which actions are singular, and which are plural.
For instance, an :index
action is typically plural and a :show
action is typically singular. This means that if automatic preloading mechanisms are in place, :index
will load many records, and :show
will load a single record.
Example
@impl Permit.Actions
def singular_actions do
crud_singular() ++ [:show, :open]
end