Gardien

Authorization for Phoenix projects.

Installation

Add gardien to your list of dependencies in mix.exs:

def deps do
  [{:gardien, "~> 0.0.1"}]
end

Then run mix deps.get to fetch the dependencies.

Configuration

gardien_user - optional

By default Gardien will try to extract user from conn.assigns using current_user key. In case you want to change the default behaviour you can configure gardien_user as follows:

# specified as a key that can be used to extract user from `conn.assigns`, e.g
# %Plug.Conn{assigns: %{admin: user}}
config :gardien,
  gardien_user: :admin

# as a function that takes `conn` as an argument and returns user
config :gardien,
  gardien_user: fn(conn) -> conn.assigns.current_user end

# as a remote function in {Module, atom} format
config :gardien,
  gardien_user: {MyHelpers, :gardien_user}

Gardien.Policy protocol

Gardien.Policy protocol should be implemented for each resource that needs to be authorized! This protocol defines authorize?(resource, action, user) function and is used by Gardien to verify whether user is allowed to perform some action on a given resource.

Important:Gardien.Policy.authorize?/3should return true or false.

Note: Gardien comes with a Gardien.Authorize module, that can be use-d in order to implement a more descriptive policy.

Gardien.Policy implementation example (with Gardien.Authorize):

defimpl Gardien.Policy, for: MyApplication.Post do
  use Gardien.Authorize

  def new(_resource, _user) do
    true
  end

  def edit(resource, user) do
    user.id == resource.user_id
  end

  def update(resource, user) do
    edit(resource, user)
  end

  # ...
end

In case you're building a closed system, where only logged in users are able to do anything, you can define your own Authorize:

defmodule MyApplication.Authorize do
  defmacro __using__(_opts) do
    def authorize?(_resource, _action, user) when is_nil(user), do
      do: false
    def authorize?(resource, action, user),
      do: apply(__MODULE__, action, [resource, user])
  end
end

defimpl Gardien.Policy, for: MyApplication.Post do
  use MyApplication.Authorize

  # ...
end

TODO: describe headless policy implementation

TODO: describe available authorization functions

TODO: add examples