{"id":19781966,"url":"https://github.com/bmuller/pundit-elixir","last_synced_at":"2025-10-18T12:35:13.631Z","repository":{"id":53558943,"uuid":"172585657","full_name":"bmuller/pundit-elixir","owner":"bmuller","description":"Simple authorization helpers for Elixir stucts, like Ruby's Pundit","archived":false,"fork":false,"pushed_at":"2024-07-24T00:23:11.000Z","size":40,"stargazers_count":37,"open_issues_count":0,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-26T04:34:33.257Z","etag":null,"topics":["access-control","elixir","permissions","pundit"],"latest_commit_sha":null,"homepage":"https://hex.pm/packages/pundit","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/bmuller.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-02-25T21:12:27.000Z","updated_at":"2024-11-19T18:49:02.000Z","dependencies_parsed_at":"2024-12-16T01:14:19.573Z","dependency_job_id":null,"html_url":"https://github.com/bmuller/pundit-elixir","commit_stats":{"total_commits":20,"total_committers":3,"mean_commits":6.666666666666667,"dds":0.09999999999999998,"last_synced_commit":"d784d59dd35d390076e2f72769418252126417d3"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmuller%2Fpundit-elixir","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmuller%2Fpundit-elixir/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmuller%2Fpundit-elixir/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmuller%2Fpundit-elixir/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bmuller","download_url":"https://codeload.github.com/bmuller/pundit-elixir/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248547184,"owners_count":21122465,"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":["access-control","elixir","permissions","pundit"],"created_at":"2024-11-12T06:03:16.651Z","updated_at":"2025-10-18T12:35:13.624Z","avatar_url":"https://github.com/bmuller.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pundit\n[![Build Status](https://github.com/bmuller/pundit-elixir/actions/workflows/ci.yml/badge.svg)](https://github.com/bmuller/pundit-elixir/actions/workflows/ci.yml)\n[![Hex pm](http://img.shields.io/hexpm/v/pundit.svg?style=flat)](https://hex.pm/packages/pundit)\n[![API Docs](https://img.shields.io/badge/api-docs-lightgreen.svg?style=flat)](https://hexdocs.pm/pundit/)\n\nPundit provides a set of helpers which guide you in leveraging regular Elixir methods to\nbuild a simple authorization system.  This library is based heavily on Jonas Nicklas' [Ruby project of the same name](https://github.com/varvet/pundit).\n\nSimple Elixir functions are defined for a given struct and allow you to encapsulate authorization logic.  You can use\nthis code within a module that is an Ecto.Schema, but that's not necessary (Ecto isn't required).  The action names are taken from the list\nof [actions defined by Phoenix controllers](https://hexdocs.pm/phoenix/controllers.html#actions).\n\n## Installation\n\nTo install Pundit, just add an entry to your `mix.exs`:\n\n``` elixir\ndef deps do\n  [\n    # ...\n    {:pundit, \"~\u003e 1.1\"}\n  ]\nend\n```\n\n(Check [Hex](https://hex.pm/packages/pundit) to make sure you're using an up-to-date version number.)\n\n## Usage\nHere's a basic example, starting with a simple struct for a `Post`.  A module named `Post.Policy` should be created to\nencapsulate all of the access methods (`Pundit` will automatically look for the `\u003cstruct module\u003e.Policy` module\nto determine the module name to look at for access methods).\n\nTo declare an initial set of access functions (`show?`, `edit?`, `delete?`, etc)\nwhich all return `false` (default safe!), just `use` `Pundit.DefaultPolicy`.  You can then override the functions as needed\nwith the logic necessary to determine whether a user should be able to perform the given action.  In this example, we only\ndetermine whether a user can `edit?` a post, leaving all other functions (like `delete?`) to return the default of `false`.\n\n```elixir\ndefmodule Post do\n  defstruct [:author, :title, :body, :comments]\n\n  defmodule Policy do\n    # This will initialize all the action functions, all of which return false\n    # by default. Override them individually to return true when they should,\n    # like edit? is overriden below.\n    use Pundit.DefaultPolicy\n\n    def edit?(post, user) do\n      user.name == post.author\n    end\n  end\nend\n\npost = %Post{author: \"Snake Plissken\"}\nauthor = %{name: \"Snake Plissken\"}\n# next line is same as Pundit.can?(post, author, :edit?)\n# Pundit will just delegate to Post.Policy.edit?(post, user)\nif Pundit.edit?(post, author) do\n  IO.puts(\"Can edit!\")\nend\n\nif Pundit.delete?(post, author) do\n  IO.puts(\"This line should never be called\")\nend\n\n# raise exception if user should be able to do a thing\nPundit.authorize!(post, author, :edit?)\n```\n\n## Scope\nYou can also provide query scope for a struct (say, if you're using `Ecto.Schema`) for a given user.  For instance,\nsay our `Post` was an `Ecto` schema.  Our function for scoping all `Post`s to a specific `User` could be to find all\n`Post`s that were authored by a user.  For instance:\n\n```elixir\ndefmodule Post do\n  use Ecto.Schema\n  import Ecto.Query, only: [from: 2]\n\n  defmodule Policy do\n    use Pundit.DefaultPolicy\n\n    def scope(query, user) do\n      from post in query,\n        where: post.author_id == ^user.id\n    end\n  end\nend\n\nuser = MyApp.Repo.get(User, 1)\nposts = Pundit.scope(Post, user) |\u003e Repo.all()\n\nquery = from p in Post, where: p.comment_count \u003e 10\npopular_posts = Pundit.scope(query, user) |\u003e Repo.all()\n```\n\nSee [the docs](https://hexdocs.pm/pundit) for more examples.\n\n## Running Tests\n\nTo run tests:\n\n```shell\n$ mix test\n```\n\n## Reporting Issues\n\nPlease report all issues [on github](https://github.com/bmuller/pundit-elixir/issues).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbmuller%2Fpundit-elixir","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbmuller%2Fpundit-elixir","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbmuller%2Fpundit-elixir/lists"}