View Source Permit.ResolverBase behaviour (permit v0.2.0)

Provides a basis for building resolver modules. A resolver is conceptually a module containing functions answering the following questions:

  • Given current permission configuration, is a subject authorized to perform a certain action on a given resource?
  • Given current permission configuration, a certain subject, an action and a resource, as well as an execution context (e.g. including controller parameters, loader functions, etc.), load a resource (e.g. by ID) and check whether the subject is authorized to perform the action on the resource.
  • Given current permission configuration, a certain subject, an action and a resource, as well as an execution context, load all resources on which the subject can perform the action.

The Permit.ResolverBase module implements authorized?/4, authorize_and_preload_one!/5 and authorize_and_preload_all!/5 functions to check against the permissions and provide a uniform API for the outcome of the resolution.

Creating a resolver (see Permit.Ecto.Resolver as an example) requires the developer to implement the resolve/6 callback that fetches data to be authorized against.

Replacing the standard resolver (Permit.Resolver) with a more specific one (e.g. Permit.Ecto.Resolver from the permit_ecto library) is done by the usage of a different resolver module (e.g. Permit.Ecto.Resolver) instead of Permit.Resolver in the __using__/1 macro of the module which implements the Permit behaviour. The resolver_module/0 function has to be overridden to point to the new resolver (see Permit.Ecto for sample usage).

Summary

Callbacks

Link to this callback

resolve(subject, authorization_module, resource_module, action_group, resolution_context, arg6)

View Source

Implement to define a resolver's behavior.

The callback takes arguments in the following order:

  • subject typically takes the current user (or a record that Permit.SubjectMapping maps it to),
  • authorization_module takes the application's authorization configuration (i.e. the module that calls use Permit or use Permit.Ecto, or any other module with Permit behaviour),
  • resource_module takes the resource module - often, in Ecto applications, it's an Ecto schema,
  • action_group takes a name of an action, e.g. in Phoenix it's taken from a controller conn or a LiveView socket's live_action
  • meta - depending on the resolver's needs, it will carry metadata such as loader functions, Ecto query processing functions, controller params, etc. - this generally is private to the integration library a developer is creating,
  • arity - it takes :all if plural resolution is to be performed (e.g. :index), and :one if singular resolution is performed (e.g. :show)

The callback implementation should use the arguments, including authorization context and application-specific context (particularly in :meta key), to resolve and return a record or records according to the spec.

Returned value:

  • {:authorized, object} in a singular action if a record is found and authorization is granted,
  • {:authorized, [object]} in a plural action if authorization to given action is granted - and it is assumed that the resolver filters out records that are not authorized,
  • :not_found in a singular action if no record found, and thus authorization cannot be checked _(note that in plural actions {:authorized, []} should be returned)
  • :unauthorized in a singular action if a record is found but authorization check is negative, or in a singular or plural action if the action itself is not authorized at all.