View Source Bosun
A simple authorization package that uses protocols.
installation
Installation
If available in Hex, the package can be installed
by adding bosun to your list of dependencies in mix.exs:
def deps do
[
{:bosun, "~> 1.0.1"}
]
end
basic-usage
Basic Usage
To use Bosun all you need to do is define your policy by implementing the Bosun.Policy protocol for a struct. Example below:
defmodule User do
defstruct role: :guest, username: "", blocked: false
end
defmodule Post do
defstruct title: "", body: ""
end
defimpl Bosun.Policy, for: Post do
alias Bosun.Context
def permitted?(_resource, _action, %User{role: :admin}, context, _options) do
Context.permit(context, "Admins are allowed to do anything")
end
def permitted?(%Post{title: "A Guest Post"}, _action, %User{role: :guest}, context, _options) do
Context.permit(context, "Guests are allowed to do stuff to guest posts")
end
def permitted?(_resource, :read, %User{role: :guest}, context, _options) do
Context.permit(context, "Guests are allowed to read posts")
end
def permitted?(_resource, :comment, %User{role: :guest} = user, context, options) do
if options[:super_fan] do
Context.permit(context, "Super fans are permitted")
else
Context.deny(context, "Guests that are not super fans are not permitted")
end
|> blocked_commenter?(user)
end
def blocked_commenter?(%Context{permitted: true} = context, %User{blocked: true}) do
Context.deny(context, "User blocked from commenting")
end
def blocked_commenter?(context, _user) do
context
end
def permitted?(_resource, :update, %User{role: :guest}, context, _options) do
Context.deny(context, "User is a guest")
end
def permitted?(_resource, _action, _user, context, _options) do
context
end
endAfter defining your policy as seen above anywhere in your codebase you can call the Bosun.permit?/3 or Bosun.permit?/4 functions.
if Bosun.permit?(%User{role: :guest}, :comment, %Post{title: "Another Guest Post"}, super_fan: true) do
do_something()
else
Logger.error("Boom!!!?!")
end
case Bosun.permit(%User{role: :guest}, :comment, %Post{title: "Another Guest Post"}, super_fan: true) do
{:ok, _} -> do_something()
{:error, context} -> Logger.error(context.reason)
end
try do
Bosun.permit!(%User{role: :guest}, :comment, %Post{title: "Another Guest Post"}, super_fan: true)
do_something()
rescue
e in Impermissible -> Logger.error(e.message)
endYou can define an Any implementation as a fallback policy
defimpl Bosun.Policy, for: Any do
alias Bosun.Context
def authorized?(_resource, _action, _subject, context, _options) do
Context.reject(context, "Impermissible")
end
end
configuration
Configuration
Here is the default library config.
config :bosun,
debug: true
todo
Todo
- [ ] improve documentation
Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/bosun.