papers_please
A roles and permissions gem from Apsis Labs.
NOTE: Still under heavy development, definitely not suitable for anything remotely resembling production usage. Very unlikely to even work.
Example
# app/policies/access_policy.rb
class AccessPolicy < PapersPlease::Policy
def configure
# Define your roles
role :super, (proc { |u| u.super? })
role :admin, (proc { |u| u.admin? })
role :member, (proc { |u| u.member? })
role :guest
permit :super do |role|
role.grant [:manage], User
end
permit :admin, :super do |role|
role.grant [:manage, :archive], Post
end
permit :member do |role|
role.grant [:create], Post
role.grant [:update, :read], Post, query: (proc { |u| u.posts })
role.grant [:archive], Post, query: (proc { |u| u.posts }), predicate: (proc { |u, post| !post.archived? })
end
permit :guest do |role|
role.grant [:read], Post, predicate: (proc { |u, post| !post.archived? })
end
permit :member, :guest do |role|
role.grant [:read], Attachment, granted_by: [Post, (proc { |u, | .post })]
end
end
end
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
# GET /posts
def index
@posts = policy.query(:read, Post)
render json: @posts
end
# GET /posts/:id
def show
@post = Post.find(params[:id])
policy. :read, @post
render json: @post
end
# POST /posts/:id/archive
def archive
@post = Post.find(params[:id])
policy. :archive, @post
@post.update!(archived: true)
render json: @post
end
end
class AttachmentsController < ApplicationController
# GET /attachments/:id
def show
@attachment = Attachment.find([:id])
policy. :read, @attachment # => proxied to Post permission check
send_data @attachment.data, type: @attachment.content_type
end
end
A helpful CLI
$ rails papers_please:roles
# =>
# +---------+------------+------------+------------+----------------+-------------------+
# | role | subject | permission | has query? | has predicate? | granted by other? |
# +---------+------------+------------+------------+----------------+-------------------+
# | admin | Post | create | yes | yes | no |
# | | Post | read | yes | yes | no |
# | | Post | update | yes | yes | no |
# | | Post | destroy | yes | yes | no |
# | | Attachment | create | yes | yes | no |
# | | Attachment | read | yes | yes | no |
# | | Attachment | update | yes | yes | no |
# | | Attachment | destroy | yes | yes | no |
# +---------+------------+------------+------------+----------------+-------------------+
# | manager | Post | create | yes | yes | no |
# | | Post | read | yes | yes | no |
# | | Post | update | yes | yes | no |
# | | Post | destroy | yes | yes | no |
# | | Attachment | create | yes | yes | yes |
# | | Attachment | read | yes | yes | yes |
# | | Attachment | update | yes | yes | yes |
# | | Attachment | destroy | yes | yes | yes |
# +---------+------------+------------+------------+----------------+-------------------+
# | member | Post | create | yes | yes | no |
# | | Post | read | yes | yes | no |
# | | Post | update | yes | yes | no |
# | | Attachment | create | yes | yes | yes |
# | | Attachment | read | yes | yes | yes |
# | | Attachment | update | yes | yes | yes |
# +---------+------------+------------+------------+----------------+-------------------+
Installation
Add this line to your application's Gemfile:
gem 'papers_please'
And then execute:
$ bundle
Or install it yourself as:
$ gem install papers_please
Usage
TODO: Write usage instructions here
Theory
The structure of papers_please
is very simple. At its core, it is a mechanism for storing and retrieving Procs
. In an authorization context, these Procs
answer two questions:
- Given a specific user and a specific permission, which objects am I allowed to operate on?
- Given a specific user and a specific object, do I have a specific permission?
The machinery of papers_please
tries to simplify the organization and subsequent access to these questions as much as possible.
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/wkirby/papers_please.
Special Thanks
This owes its existence to AccessGranted
. Thanks!
License
The gem is available as open source under the terms of the MIT License.
Built by Apsis
papers_please
was built by Apsis Labs. We love sharing what we build! Check out our other libraries on Github, and if you like our work you can hire us to build your vision.