ProductPromotion
Logo

Elixir

made by https://0x3d.site

GitHub - jfrolich/authorize: Rule based authorization for Elixir
Rule based authorization for Elixir. Contribute to jfrolich/authorize development by creating an account on GitHub.
Visit Site

GitHub - jfrolich/authorize: Rule based authorization for Elixir

GitHub - jfrolich/authorize: Rule based authorization for Elixir

authorize-logo

Authorize

Authorize is a rule based authorization module for your elixir app.

Authorize walks through rules in your resource to determine if it grants authorization, or not. These rules are easily created using a DSL.

Any rule can return three states:

  • :ok: grand access (return :ok)
  • :next: got to next rule
  • :error: return {:error, description}

How this translates to code is as follows:

defmodule Item do
  use Authorize

  defstruct user_id: nil, private?: false, invisible?: false

  authorize do
    # signature of rule:
    # rule(
    #  actions: one or a list of actions [optional], if not included this rule
    #           applies to all actions
    #  description: a description of the the rule, this will be returned as the
    #               'reason'.
    #  struct_or_changeset: the struct or changeset that you wish to apply the
    #                       rule to.
    #  actor: a data structure that describes the actor of the action. This will
    #         be the user in most cases.
    # )

    rule "authorize super admins for everything", _, actor do
      if actor.super_admin?, do: :ok, else: :next
    end

    # An :error response will stop the chain, as will an :ok response.
    # When returning :next it will evaluate the next rule.
    rule [:read], "only admins can read invisible items", struct_or_changeset, actor do
      item = get_struct(struct_or_changeset)
      cond do
        item.invisible? and actor.admin? -> :ok
        item.invisible? -> :error
        :else -> :next
      end
    end

    # Action can be a list of actions, a single action such as ':read',
    # or be completely omitted (equivalent to :all)
    rule :read, "actors can read their own private items", struct_or_changeset, actor do
      item = get_struct(struct_or_changeset)
      if item.private? and item.user_id == actor.id do
        :ok
      else
        :next
      end
    end

    rule [:read], "admins can read private items", struct_or_changeset, actor do
      if actor.admin? and get_struct(struct_or_changeset).private?, do: :ok, else: :next
    end

    rule [:read], "all actors can read public items", struct_or_changeset, actor do
      if get_struct(struct_or_changeset).public?, do: :ok
    end
  end
end

defmodule User do
  defstruct id: nil, name: nil, admin?: false, super_admin?: false
end

We can now use this authorization module in the following way, with ordered rules (executed from top to bottom):

iex> normal_user = %User{id: 1, name: "Ed", admin?: false}
...> admin = %User{id: 2, name: "Admin", admin?: true}
...> invisible_item = %Item{private?: true, invisible?: true, user_id: 2}
...> private_item = %Item{private?: true, user_id: 2}

iex> Item.authorize(invisible_item, normal_user, :read)
{:error, "only admins can read invisible items"}

iex> Item.authorize(invisible_item, admin, :read)
:ok

iex> Item.authorize(private_item, normal_user, :read)
{:error, "no authorization rule found"}

iex> Item.authorize(private_item, admin, :read, include_reason: true)
{:ok, "members can read their own private items"}

You can define a rule with rule [action], description, struct_or_changeset, actor

With rule you are defining a rule.

The first argument is the action this rule applies to. I would recommend to use the well known CRUD (create, read, update, and delete) actions, but you can also use something else (Authorize does not care). If you leave the first argument out and start with the description, the rule will apply to all actions.

The second argument is a description, when this rule returns :error this will be passed as the reason.

struct_or_changeset and actor are the variables that you can use in the rule's body. The struct_or_changeset is the resource, and actor is the actor that tries to perform the action. This can be anything you like. To make it work well with ecto we provide two helper methods is_changeset?/1 and get_struct/1. is_changeset/1 will return true if struct_or_changeset is a changeset. get_struct/1 returns the struct. If the item is a changeset, it will return changeset.data.

If there is no rule found that returns :error or :ok, the authorize/3 function will return {:error, "no authorization rule found"}

More examples in test/authorize_test.

Installation

If available in Hex, the package can be installed as:

  1. Add authorize to your list of dependencies in mix.exs:
def deps do
  [{:authorize, "~> 1.0.0"}]
end
  1. Ensure authorize is started before your application:
def application do
  [applications: [:authorize]]
end

Articles
to learn more about the elixir concepts.

Resources
which are currently available to browse on.

mail [email protected] to add your project or resources here 🔥.

FAQ's
to know more about the topic.

mail [email protected] to add your project or resources here 🔥.

Queries
or most google FAQ's about Elixir.

mail [email protected] to add more queries here 🔍.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory