aegis v0.2.0 Aegis.Controller View Source
Wraps controllers with Aegis authorization functionality.
Link to this section Summary
Functions
Allows another module to inherit Aegis.Controller
methods
Returns the set of accessible resources, for a user, for a given action
Authorizes a resource, for a user, for a given action, and marks the
connection as having had aegis authorization perfomed via the assignment of
a boolean value to aegis_auth_performed
on the connection
Calls controller action and performs a check on the connection in order to determine whether or not Aegis authorization has been performed
Link to this section Functions
Allows another module to inherit Aegis.Controller
methods.
Options
except
- list of actions to exclude from aegis authorization; defaults to an empty list
Examples:
For Phoenix applications:
defmodule MyApp.PuppyController do
use MyApp, :controller
use Aegis.Controller
def current_user(conn) do
conn.assigns[:user]
end
end
if you want to allow some actions to skip authorization, just use the
except
option:
defmodule MyApp.Controller do
use MyApp, :controller
use Aegis.Controller, except: [:custom_action]
def current_user(conn) do
conn.assigns[:user]
end
end
Returns the set of accessible resources, for a user, for a given action.
Examples
Suppose your library defines the following resource and resource policy:
defmodule Puppy do
defstruct [id: nil, user_id: nil, hungry: false]
end
defmodule Puppy.Policy do
@behaviour Aegis.Policy
...
# users should only be able to see puppies that belong to them..
def auth_scope(%User{id: user_id}, {:index, scope}) do
Enum.filter(scope, &(&1.user_id == user_id))
end
end
We can use auth_scope/4
to appropriately limit access to puppies for a given user
iex> user = %User{id: 1}
iex> puppy_1 = %Puppy{id: 1, user_id: 1}
iex> puppy_2 = %Puppy{id: 2, user_id: 2}
iex> all_puppies = [puppy_1, puppy_2]
iex> Aegis.Controller.auth_scope(user, all_puppies, :index)
[%Puppy{id: 1, user_id: 1, hungry: false}]
iex> Aegis.Controller.auth_scope(user, all_puppies, :index, Puppy.Policy)
[%Puppy{id: 1, user_id: 1, hungry: false}]
In the above example, Puppy.Policy.auth_scope
is written such that it
takes in and filters an enumerable. A more common use case—if you’re
integrating Aegis with database-backed data—is to filter data via building
a query that limits what data is returned.
For example, assuming our app uses Ecto as a database wrapper,
Puppy.Policy.auth_scope/2
can be rewritten as follows, so that data is
filtered as part of the querying process:
defmodule Puppy.Policy do
@behaviour Aegis.Policy
...
def auth_scope(%User{id: user_id}, {:index, scope}) do
import Ecto.Query
scope |> where([p], p.user_id == ^user_id)
end
end
authorized?(Plug.Conn.t(), term(), term(), Keyword.t()) :: {:ok, Plug.Conn.t()} | {:error, Plug.Conn.t()}
Authorizes a resource, for a user, for a given action, and marks the
connection as having had aegis authorization perfomed via the assignment of
a boolean value to aegis_auth_performed
on the connection.
Returns a two-element tuple: if authorization check passes, then
{:ok, conn}
is returned; otherwise, {:error, conn}
is returned.
Examples
defmodule Puppy do
defstruct [id: nil, user_id: nil, hungry: false]
end
defmodule Puppy.Policy do
@behaviour Aegis.Policy
def authorized?(_user, {:index, _puppy}), do: true
def authorized?(%User{id: id}, {:show, %Puppy{user_id: id}}), do: true
def authorized?(_user, {:show, _puppy}), do: false
end
iex> conn = %Plug.Conn{}
iex> user = :user
iex> resource = Puppy
iex> action = :index
iex> {:ok, conn} = Aegis.Controller.authorized?(conn, user, resource, action: action)
iex> conn.private[:aegis_auth_performed]
true
iex> conn = %Plug.Conn{}
iex> user = :user
iex> resource = Puppy
iex> action = :show
iex> {:error, conn} = Aegis.Controller.authorized?(conn, user, resource, action: action)
iex> conn.private[:aegis_auth_performed]
true
call_action_and_verify_authorized(module(), atom(), Plug.Conn.t(), term()) :: Plug.t()
Calls controller action and performs a check on the connection in order to determine whether or not Aegis authorization has been performed.
Examples
TODO..