{"id":13507461,"url":"https://github.com/jarednorman/canada","last_synced_at":"2025-04-08T09:08:06.905Z","repository":{"id":20023800,"uuid":"23291684","full_name":"jarednorman/canada","owner":"jarednorman","description":"Easy permission definitions in Elixir apps!","archived":false,"fork":false,"pushed_at":"2021-04-21T20:40:57.000Z","size":26,"stargazers_count":452,"open_issues_count":2,"forks_count":29,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-01T07:51:26.197Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://github.com/jarednorman/canada","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jarednorman.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-08-24T20:19:21.000Z","updated_at":"2025-03-15T16:08:08.000Z","dependencies_parsed_at":"2022-07-27T01:02:05.047Z","dependency_job_id":null,"html_url":"https://github.com/jarednorman/canada","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jarednorman%2Fcanada","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jarednorman%2Fcanada/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jarednorman%2Fcanada/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jarednorman%2Fcanada/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jarednorman","download_url":"https://codeload.github.com/jarednorman/canada/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247809962,"owners_count":20999816,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T02:00:34.204Z","updated_at":"2025-04-08T09:08:06.888Z","avatar_url":"https://github.com/jarednorman.png","language":"Elixir","funding_links":[],"categories":["Authorization"],"sub_categories":[],"readme":"Canada: _Define you some permissions_\n=====================================\n\n[![Module Version](https://img.shields.io/hexpm/v/canada.svg)](https://hex.pm/packages/canada)\n[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/canada/)\n[![Total Download](https://img.shields.io/hexpm/dt/canada.svg)](https://hex.pm/packages/canada)\n[![License](https://img.shields.io/hexpm/l/canada.svg)](https://github.com/jarednorman/canada/blob/master/LICENSE)\n[![Last Updated](https://img.shields.io/github/last-commit/jarednorman/canada.svg)](https://github.com/jarednorman/canada/commits/master)\n\n\u003e **NOTE:** If you're concerned by the fact that this repository has very\n\u003e little activity, don't be. The functionality this package provides is very\n\u003e simple, it has no dependencies, and the Elixir language hasn't changed in any\n\u003e way that would break it. It still works just as well as when I first wrote\n\u003e it. :smiley:\n\nCanada provides a friendly interface for making easy use of\n[Elixir](http://elixir-lang.org/)'s excellent pattern matching to create\nreadable declarative permission rules.\n\nIf you're looking for something that fills more of what CanCan would provide\nyou in a Rails application you should have a look at\n[Canary](https://github.com/cpjk/canary) which adds Ecto/Plug support.\n\nInstallation\n------------\n\nAdd it to your deps list in your `mix.exs` if you want the latest release?\n\n```elixir\ndefp deps do\n  [\n    {:canada, \"~\u003e 2.0\"}\n  ]\nend\n```\n\nOr you want the latest greatest master?\n\n```elixir\ndefp deps do\n  [\n    {:canada, github: \"jarednorman/canada\"}\n  ]\nend\n```\n\nBecoming Canadian\n-----------------\n\nBecoming Canadian is easy. Presumably you have some kind of resource like a\nuser, and probably some kind of resource that belongs to users. Let's call that\nhypothetical resource a \"post\". Let's say they're structs.\n\n```elixir\ndefmodule User do\n  defstruct id: nil, name: nil, admin: false\nend\n\ndefmodule Post do\n  defstruct user_id: nil, content: nil\nend\n```\n\nTo make use of Canada, you need to implement the `Canada.Can` protocol\n(defining whatever rules you need) for the \"subject\" resource (your User struct\nin this case).\n\n```elixir\ndefimpl Canada.Can, for: User do\n  def can?(%User{id: user_id}, action, %Post{user_id: user_id})\n    when action in [:update, :read, :destroy, :touch], do: true\n\n  def can?(%User{admin: admin}, action, _)\n    when action in [:update, :read, :destroy, :touch], do: admin\n\n  def can?(%User{}, :create, Post), do: true\nend\n```\n\nWith this in place, you're good to start testing permissions wherever you need\nto, just remember to import the can? macro.\n\n```elixir\nimport Canada, only: [can?: 2]\n\nif some_user |\u003e can? read(some_post) do\n  # render the post\nelse\n  # sorry (raise a 403)\nend\n```\n\nA note from the author\n----------------------\n\nThis is very much what happened when I said to myself, \"I want the thing I had\nin Ruby, but in Elixir.\" I would be entirely unsurprised if myself or someone\nelse comes up with a more \"functional\" solution. That said, permissions are\nnecessarily a matter that governs conditional logic, so I currently see this as\na reasonable solution.\n\n## Copyright and License\n\nCopyright (c) 2014 Jared Norman\n\nThis software is licensed under [the MIT license](./LICENSE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjarednorman%2Fcanada","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjarednorman%2Fcanada","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjarednorman%2Fcanada/lists"}