View Source Rolex.Permission (Rolex v0.5.2)

Permissions are the basic units of role assignments.

A permission is an intersection of four pieces of information:

  • verb - either "grant" or "deny"
  • role - the role being granted or denied
  • subject - the entity (or entities) being granted or denied the role
  • object - the entity (or entities) on which the subject is being granted the role

For example, a permission that "grants admin to user 42 on all tasks" would look like this:

%Permission{verb: :grant, role: :admin, subject_type: User, subject_id: 42, object_type: Task, object_id: :all}

A permission "applies" to any arbitrary subject and/or object if the corresponding _type and _id fields are either :all or a perfect match. This particular permission applies only if the subject is specifically %User{id: 42} and the object is a task; e.g. %Task{id: 123}.

Rolex inspects the full set of applicable permissions to make a final determination about each role. If this were the only permission, with subject %User{id: 42} and object %Task{id: _}, the :admin role is granted.

We can make exceptions by creating "deny" permissions. Continuing our example, suppose we now wanted to "deny admin to all subjects on task 99".

%Permission{verb: :deny, role: :admin, subject_type: :all, subject_id: :all, object_type: Task, object_id: 99}

This permission applies to all subjects (regardless of type or id!), but only if the object is specifically %Task{id: 99}.

Given these two permissions, with subject %User{id: 42} and object %Task{id: 123}, the :admin role is granted. In object %Task{id: 99}'s case, however, the "deny" permission takes precedence, and the :admin role will never be granted.

Summary

Functions

Returns an initialized %Ecto.Query{} to be used for permission queries.

Narrows a list of permissions to grant permissions that are not overridden by a deny permission.

Narrows a permission query to those that match the passed parameters.

Narrows a permission query to grant permissions that are not overridden by a deny permission.

Types

@type action() :: :grant | :deny | :revoke
@type changeset() :: Ecto.Changeset.t(t())
@type params() :: %{
  optional(:verb) => verb(),
  optional(:role) => role(),
  optional(:subject_type) => scope_type(),
  optional(:subject_id) => scope_id(),
  optional(:object_type) => scope_type(),
  optional(:object_id) => scope_id()
}
@opaque t()

Functions

@spec base_query() :: Ecto.Query.t()

Returns an initialized %Ecto.Query{} to be used for permission queries.

Link to this function

filter_granted(list, params \\ %{})

View Source
@spec filter_granted([t()], params()) :: [t()]

Narrows a list of permissions to grant permissions that are not overridden by a deny permission.

Link to this function

preloader_query(parent_ids, has)

View Source
Link to this function

where_equal(query, params \\ %{})

View Source
@spec where_equal(Ecto.Query.t(), params()) :: Ecto.Query.t()

Narrows a permission query to those that match the passed parameters.

Used to target specific records, as when revoking permissions.

Link to this function

where_granted(query, params \\ %{})

View Source
@spec where_granted(Ecto.Query.t(), params()) :: Ecto.Query.t()

Narrows a permission query to grant permissions that are not overridden by a deny permission.