Current section
Files
Jump to
Current section
Files
README.md
Canada: _Define you some permissions_=====================================**NOTE:** If you're concerned by the fact that this repository has no activitylately and hasn't had a release since `v1.0.1`, don't be. The functionalitythis package provides is very simple, it has no dependencies, and the Elixirlanguage hasn't changed in any way that would break it. It still works just aswell as when I first wrote it. :smiley:Canada provides a friendly interface for making easy use of[Elixir](http://elixir-lang.org/)'s excellent pattern matching to createreadable declarative permission rules.If you're looking for something that fills more of what CanCan would provideyou in a Rails application you should have a look at[Canary](https://github.com/cpjk/canary) which adds Ecto/Plug support.Installation------------Add it to your deps list in your `mix.exs`. You want the latest release?```elixirdefp deps do [{:canada, "~> 1.0.1"}]end```You want the latest master?```elixirdefp deps do [{:canada, github: "jarednorman/canada"}]end```Becoming Canadian-----------------Becoming Canadian is easy. Presumably you have some kind of resource like auser, and probably some kind of resource that belongs to users. Let's call thathypothetical resource a "post". Let's say they're structs.```elixirdefmodule User do defstruct id: nil, name: nil, admin: falseenddefmodule Post do defstruct user_id: nil, content: nilend```To make use of Canada, you need to implement the `Canada.Can` protocol(defining whatever rules you need) for the "subject" resource (your User structin this case).```elixirdefimpl Canada.Can, for: User do def can?(%User{id: user_id}, action, %Post{user_id: user_id}) when action in [:update, :read, :destroy, :touch], do: true def can?(%User{admin: admin}, action, _) when action in [:update, :read, :destroy, :touch], do: admin def can?(%User{}, :create, Post), do: trueend```With this in place, you're good to start testing permissions wherever you needto, just remember to import the can? macro.```elixirimport Canada, only: [can?: 2]if some_user |> can? read(some_post) do # render the postelse # sorry (raise a 403)end```A note from the author----------------------This is very much what happened when I said to myself, "I want the thing I hadin Ruby, but in Elixir." I would be entirely unsurprised if myself or someoneelse comes up with a more "functional" solution. That said, permissions arenecessarily a matter that governs conditional logic, so I currently see this asa reasonable solution.