Permissions for Phoenix.
Your app has one permissions module, which lists its policies:
defmodule MyApp.Permissions do
use Sekisho,
repo: MyApp.Repo,
policies: [MyApp.Blog.PostPolicy, MyApp.Docs.DocumentPolicy, MyApp.Orgs.OrgPolicy],
sources: MyApp.Permissions.Sources,
groups: [MyApp.Teams.Team]
@impl Sekisho
def actor(%MyApp.Accounts.Scope{user: user}), do: user
def actor(nil), do: nil
endand every question goes through it, with your scope (Phoenix's
%Scope{}) first:
MyApp.Permissions.allowed?(scope, :update, post) # true | false
MyApp.Permissions.authorize(scope, :update, post) # :ok | {:error, %Sekisho.Denied{}}
MyApp.Permissions.authorize!(scope, :update, post) # raises Sekisho.Denied, a 403
Post |> MyApp.Permissions.where_allowed(scope, :read) |> Repo.all()
MyApp.Permissions.with_permissions(posts, scope, [:update, :delete])
MyApp.Permissions.allowed_fields(scope, user)
MyApp.Permissions.redact(scope, user)
MyApp.Permissions.explain(scope, :update, document)
MyApp.Permissions.grant(scope, ana, :editor, on: document)
MyApp.Permissions.grant(scope, :link, :viewer, on: document)
MyApp.Permissions.revoke(scope, ana, :editor, on: document)
MyApp.Permissions.grants(scope, document)
{:ok, support} = MyApp.Permissions.create_role(scope, org, "Support", [:"investigations.view"])
MyApp.Permissions.grant(scope, ana, "Support", on: org)The rules are in policies (Sekisho.Policy), and roles held in your own
tables in sources (Sekisho.Sources).
Options
:repo: your Ecto repo (required).:policies: your policies (required). They are read when the module is first asked, not when it compiles, so a change to one recompiles no other;validate!/0checks them together (in a test, or at boot).:sources: yourSekisho.Sourcesmodule.:groups: the schemas of groups that may be granted roles (teams); their members come fromSekisho.Sources.members/1.:pubsub: yourPhoenix.PubSub, on which grants and revocations are broadcast (topic"sekisho").:deny_as::forbidden(403, the default) or:not_found(404).
Checks of a record
A check of a record asks the database: the record as it is there, with
one query on its primary key. A rule about the actor alone (true,
false) needs none. To ask about many records at once, use
with_permissions/3.
Summary
Callbacks
The actor your scope is: a user struct, or nil for a visitor.
The link tokens your scope holds (from a link a visitor followed): [] by
default.