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

gardien_user - user performing some action on a resource. By default Gardien will try to extract user from conn.assigns using current_user key. In case you want to change this 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, user, action) function and is used by Gardien to verify whether user is allowed to perform some action on a given resource.

Important: Gardien.Policy.authorize?/3 should 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, user, _action) when is_nil(user), do
do: false
def authorize?(resource, user, action),
do: apply(__MODULE__, action, [resource, user])
end
end
defimpl Gardien.Policy, for: MyApplication.Post do
use MyApplication.Authorize
...
end

TODO: describe available authorization functions

TODO: add examples