# Bastion
[![Hex pm](http://img.shields.io/hexpm/v/bastion.svg?style=flat)](https://hex.pm/packages/bastion)
## Installation
Bastion can be installed by adding `bastion` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:bastion, "~> 0.1.0"},
]
end
```
## Overview ([from Bastion main @moduledoc](https://github.com/urbint/bastion/blob/master/lib/bastion.ex))
Bastion allows you to specify scopes in your Absinthe GraphQL Schemas,
and then authorize requests only on requested fields.
To use Bastion, you need to:
1. Set scopes on your GraphQL fields via Bastion's `scopes` macro
2. Set the authorized scopes on each Plug.Conn.t, via `Bastion.Plug.set_authorized_scopes/2`
3. Call `plug Bastion.Plug` ahead of `plug Absinthe.Plug` in your router
Bastion will reject requests to scoped fields that the user does not have an authorized scope for.
Notably, the request is rejected only if a scoped field is included - requests for non protected fields will pass through.
## Example Usage
In your Absinthe.Schema:
defmodule MyAbsintheSchema do
use Absinthe.Schema
use Bastion
query do
field :users, list_of(:user) do
scopes [:admin]
end
end
object :user do
field :name, :string
end
end
In your router:
defmodule MyRouter do
use Plug
plug :set_scopes
defp set_scopes(conn, _opts) do
# get authorized scopes from your own user or domain logic
Bastion.Plug.set_authorized_scopes(conn, [:admin])
end
plug Bastion.Plug, schema: MyAbsintheSchema
plug Absinthe.Plug, schema: MyAbsintheSchema
end
## Rejecting all requests
This is effectively an authorization middleware,
and so its opinion leans toward rejecting requests more quickly than not.
If you do not set the authorized scopes on the connection with a call to `Bastion.Plug.set_authorized_scopes/2`
BEFORE calling `plug Bastion.Plug` in your router,
ALL of the requests will be rejected.
If you're getting started with Bastion,
you can write a simple plug function to set the authorized scopes to an empty list,
as exemplified in the readme.