Permit.Ecto
Integrates Permit with Ecto, providing means to convert permissions to Ecto queries, automatically constructing Ecto.Query scopes to preload records that meet authorization criteria.
Dependencies and related libraries
Permit.Ecto depends on Permit. It can be used to build custom integrations or in conjunction with Permit.Phoenix, which uses the generated accessible_by/4 functions to automatically preload, authorize and inject records loaded via Ecto into controller assigns (see more in Permit.Phoenix documentation).
Configuration
defmodule MyApp.Authorization do
use Permit.Ecto,
permissions_module: MyApp.Permissions,
repo: MyApp.Repo
end
defmodule MyApp.Permissions do
use Permit.Ecto.Permissions, actions_module: Permit.Actions.CrudActions
def can(%{role: :admin} = user) do
permit()
|> all(MyApp.Blog.Article)
end
def can(%{id: user_id} = user) do
# Checks can be performed directly for record columns as well as associated
# record values in has_one, has_many and belongs_to associations.
#
# For has_one and belongs_to relationships, given condition must be satisfied
# for the associated record. For has_many relationships, at least one associated
# record must satisfy the condition - as seen in example below.
permit()
|> all(MyApp.Blog.Article, author_id: user_id)
|> read(MyApp.Blog.Article, reviews: [approved: true])
end
def can(user), do: permit()
end
iex> MyApp.Repo.all(MyApp.Blog.Article)
[
%MyApp.Blog.Article{id: 1, author_id: 1},
%MyApp.Blog.Article{id: 2, author_id: 1},
%MyApp.Blog.Article{id: 3, author_id: 2}
]
# The `accessible_by!/3` function also has a `accessible_by/3` variant which returns `{:ok, ...}` tuples.
iex> MyApp.Permissions.accessible_by!(%MyApp.Users.User{id: 1}, :update, MyApp.Blog.Article) |> MyApp.Repo.all()
[%MyApp.Blog.Article{id: 1, ...}, %MyApp.Blog.Article{id: 2, ...}]
iex> MyApp.Permissions.accessible_by!(%MyApp.Users.User{id: 1}, :read, MyApp.Blog.Article) |> MyApp.Repo.all()
[%MyApp.Blog.Article{id: 1, ...}, %MyApp.Blog.Article{id: 2, ...}, %MyApp.Blog.Article{id: 3, ...}]
iex> MyApp.Permissions.accessible_by!(%MyApp.Users.User{id: 3, role: :admin}, :update, MyApp.Blog.Article) |> MyApp.Repo.all()
[%MyApp.Blog.Article{id: 1, ...}, %MyApp.Blog.Article{id: 2, ...}, %MyApp.Blog.Article{id: 3, ...}]Installation
The package can be installed by adding permit_ecto to your list of dependencies in mix.exs:
def deps do
[
{:permit_ecto, "~> 0.2.4"}
]
endThe docs can be found at https://hexdocs.pm/permit_ecto.