Permit.Phoenix.Actions (permit_phoenix v0.4.0)
View SourceDefines action names for your permissions schema, so that convenience functions are generated for them.
Recommended usage
defmodule MyApp.Actions do
# Merge the actions from the router into the default grouping schema
use Permit.Phoenix.Actions, router: MyApp.Router
# Additional singular actions throughout the app
def singular_actions, do: [:view]
endOverview
Default action grouping for Phoenix includes:
:create, implying permission to:newand:createactions:read, implying permission to:indexand:showactions:update, implying permission to:editand:updateactions:delete, implying permission to:deleteaction
By granting a permission to :read, you also allow :index and :show. You can
also grant permissions to individual actions specifically - if you only grant
:index, :show will not be authorized.
This is coded as:
%{
create: [],
read: [],
update: [],
delete: [],
new: [:create],
index: [:read],
show: [:read],
edit: [:update]
}If you want to declare an action that requires more than one permission, you can define a grouping:
%{
access: [],
view: [],
open: [:accsess, :view] # if both are granted, :open will be authorized
}Singular vs plural actions
Singular actions are those that operate on a single resource, such as :show or :update.
Plural actions operate on a collection of resources, such as :index. Depending on the arity,
queries generated by Permit.Ecto will be executed as LIMIT 1 (for singular actions) or with
any limit given in the base_query (for plural actions).
Each action in Permit is assumed to be plural by default. To declare an action as singular,
you can implement the singular_actions/0 callback. This can be implemented in your actions module
and overridden in your controller or LiveView module.
Default singular actions are :show, :edit, :new, :delete, :update and those
inferred from the router - see section below. The singular_actions/0 callback can be used to add more
- it does not require calling
super.
Example
defmodule MyApp.Actions do
use Permit.Phoenix.Actions
# In addition to the default singular actions. If `:view` always deals with a single record
# throughout the app, it can be declared as singular in this module.
@impl true
def singular_actions, do: [:view]
endActions can also be configured as singular or plural in the controller or LiveView module itself, which takes precedence over the actions module.
If a controller or LiveView contains a :view action that deals with an index of records,
it can be overridden as plural in the controller or LiveView module. super() will contain
the actions module's configuration.
defmodule MyApp.ArticleController do
use Permit.Phoenix.Controller
@impl true
def singular_actions, do: super() -- [:view]
endRouter
It is recommended to read action names from the router, so that all controller
action and :live_action names are automatically included and convenience functions
for them are generated. Moreover, actions are automatically inferred to be singular or plural based on the route definition.
An action is singular by default if:
- it's one of:
:show,:edit,:new,:delete,:update,:create, or - it is a POST request, or
- it's a route with an
:id,:uuidor:slugparameter, e.g./items/:id/viewor/items/:uuid/view, or - the route's last segment is a parameter, e.g.
/items/:name,/items/:identifier.
defmodule MyApp.Router do
# ...
get("/items/:id", MyApp.ItemController, :view)
end
defmodule MyApp.Actions do
# Merge the actions from the router into the default grouping schema.
use Permit.Phoenix.Actions, router: MyApp.Router
# This doesn't need to be used - Permit automatically infers that the :view action is
# singular.
# You can use it if an explicit declaration is needed, e.g. if you use a different ID
# parameter than `:id`, `:uuid` or `:slug`.
@impl true
def singular_actions, do: [:view]
end
defmodule MyApp.Permissions do
# Use the actions module to define permissions.
use Permit.Permissions, actions_module: MyApp.Actions
def can(%User{role: :admin} = _user) do
permit()
|> all(Item)
end
# The `view` action is automatically added to the grouping schema
# and hence available as a `view/2`function when defining permissions.
def can(%User{role: :owner} = _user) do
permit()
|> view(Item)
|> all(Item, fn user, item -> item.owner_id == user.id end)
end
end
Summary
Functions
Convenience function defining the basic CRUD (create, read, update, delete) actions.
Convenience function returning actions that are singular in the most basic CRUD setup, in which case
all of: :create, :read, :update and :delete are singular.
Returns the default action grouping schema for Phoenix applications.
Returns the list of actions that operate on a single resource.
Functions
Convenience function defining the basic CRUD (create, read, update, delete) actions.
Convenience function returning actions that are singular in the most basic CRUD setup, in which case
all of: :create, :read, :update and :delete are singular.
Returns the default action grouping schema for Phoenix applications.
Returns the list of actions that operate on a single resource.