# Gardien

Authorization for Phoenix projects.

## Installation

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

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

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?/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

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

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

      # ...

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])

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

      # ...

## TODO: describe headless policy implementation

## TODO: describe available authorization functions

## TODO: add examples