Permit.LiveViewAuthorization behaviour (permit v0.0.1)

A live view module using the authorization mechanism should mix in the LiveViewAuthorization module:

defmodule MyAppWeb.DocumentLive.Index
  use Permit.LiveViewAuthorization
end

which adds the LiveViewAuthorization behavior with the following callbacks to be implemented - for example:

# The related schema
@impl true
def resource_module, do: Document

# Loader function for a singular resource in appropriate actions (:show, etc.); usually a context
# function. If not defined, Repo.get is used by default.
@impl true
def loader_fn, do: fn id -> get_organization!(id) end

# How to fetch the current user from session - for instance:
@impl true
def user_from_session(session) do
  with token when not is_nil(token) <- session["token"],
       %User{} = current_user <- get_user(token) do
    current_user
  else
    _ -> nil
  end
end

Optionally, a handle_unauthorized/2 optional callback can be implemented, returning {:cont, socket} or {:halt, socket}. The default implementation returns:

{:halt, socket(socket, to: socket.view.fallback_path())}

Link to this section Summary

Functions

Returns true if inside mount/1, false otherwise. Useful for distinguishing between rendering directly via router or being in a handle_params lifecycle.

Link to this section Callbacks

Link to this callback

action_crud_mapping()

(optional)
@callback action_crud_mapping() :: keyword(Permit.Types.crud())
Link to this callback

authorization_module()

@callback authorization_module() :: module()
Link to this callback

except()

(optional)
@callback except() :: [atom()]
Link to this callback

fallback_path()

(optional)
@callback fallback_path() :: binary()
Link to this callback

handle_unauthorized(socket)

(optional)
@callback handle_unauthorized(Permit.Types.socket()) :: Permit.Types.hook_outcome()
Link to this callback

id_param_name()

(optional)
@callback id_param_name() :: Permit.Types.id_param_name()
Link to this callback

loader_fn()

(optional)
@callback loader_fn() :: (... -> any())
Link to this callback

preload_resource_in()

(optional)
@callback preload_resource_in() :: [atom()]
Link to this callback

resource_module()

(optional)
@callback resource_module() :: module()
Link to this callback

user_from_session(map)

@callback user_from_session(map()) :: struct()

Link to this section Functions

Link to this function

mounting?(socket)

@spec mounting?(Permit.Types.socket()) :: boolean()

Returns true if inside mount/1, false otherwise. Useful for distinguishing between rendering directly via router or being in a handle_params lifecycle.

For example, a handle_unauthorized/1 implementation must redirect when halting during mounting, while it needn't redirect when halting during the handle_params lifecycle.

@impl true
def handle_unauthorized(socket) do
  if mounting?(socket) do
    {:halt, push_redirect(socket, to: "/foo")}
  else
    {:halt, assign(socket, :unauthorized, true)}
  end
end