AccessGranted

proudly made by Chaps
Multi-role and whitelist based authorization gem for Rails. And it's lightweight (~300 lines of code)!
Supported Ruby versions
Guaranteed to work on MRI 1.9.3/2.0/2.1, Rubinius >= 2.1.1 and JRuby >= 1.7.6.
Summary
AccessGranted is meant as a replacement for CanCan to solve three major problems:
- built-in support for roles
Easy to read access policy code where permissions are cleanly grouped into roles. Additionally, permissions are forced to be unique in the scope of a role. This greatly simplifies the resolving permissions while substantially reducing the code-base.
- white-list based
This means that you define what a role can do, which results in clean, readable policies regardless of complexity.
You don't have to worry about juggling cans and cannots in a very convoluted way!
Note: cannot is still available, but has a very specifc use. See Usage below.
- framework agnostic
Permissions can work on basically any object and AccessGranted is framework-agnostic, But we offer extensions for your favourite frameworks as gems:
- Rails: access-granted-rails
- ... more to come!
See Usage for an example of a complete AccessPolicy file.
Compatibility with CanCan
This gem was created as a replacement for CanCan and therefore it requires minimum work to switch.
Main differences
AccessGranted does not extend ActiveRecord in any way, so it does not have the
accessible_by?method which could be used for querying objects available to current user. This was very complex and only worked with permissions defined using hash conditions, so I decided to not implement this functionality as it was mostly ignored by CanCan users.Both
can?/cannot?andauthorize!methods work in Rails controllers and views, just like in CanCan. The only change you have to make is to replace allcan? :manage, Classwith the exact action to check against.can :manageis still available for defining methods and serves as a shortcut for defining:read,:create,:update,:destroyall in one line.Syntax for defining permissions in AccessPolicy file (Ability in CanCan) is exactly the same, with added roles on top. See Usage below.
Installation
Rails
This includes Rails-specific integration (can?, cannot?, current_policy helpers and more):
gem 'access-granted-rails'
Others
gem 'access-granted'
Usage
Roles are defined using blocks (or by passing custom classes to keep things tidy). Order of the roles is important, because they are being traversed in the top-to-bottom order. Generally at the top you will have an admin or other important role giving the user top permissions, and as you go down you define less-privileged roles.
See full example:
class Policy
include AccessGranted::Policy
def configure(user)
# The most important role prohibiting banned
# users from doing anything.
# (even if they are moderators or admins)
role :banned, { is_banned: true } do
cannot [:create, :update, :destroy], Post
# same as above, :manage is just a shortcut for
# `[:read, :create, :update, :destroy]`
cannot :manage, Comment
end
# Takes precedences over roles placed lower
# and explicitly lets admin manage everything.
role :admin, { is_admin: true } do
can :manage, Post
can :manage, Comment
end
# You can also use Procs to determine
# if the role should apply to a given user.
role :moderator, proc {|u| u.moderator? } do
# takes precedence over :update/:destroy
# permissions defined in member role below
# and lets moderators edit and delete all posts
can [:update, :destroy], Post
# and a new permission which lets moderators
# modify user accounts
can :update, User
end
# The basic role.
# Applies to everyone logged in.
role :member do
can :create, Post
# For more advanced permissions
# you must use blocks. Hash
# conditions should be used for
# simple checks only.
can [:update, :destroy], Post do |post|
post.user_id == user.id && post.comments.empty?
end
end
end
end
Common examples
Extracting roles to separate files
Let's say your app is getting bigger and more complex. This means your policy file is also getting longer.
Below you can see an extracted :member role:
class AccessPolicy
include AccessGranted::Policy
def configure(user)
role :administrator, is_admin: true do
can :manage, User
end
role :member, MemberRole, lambda { |user| !u.guest? }
end
end
And roles should look like this
# app/roles/member_role.rb
class MemberRole < AccessGranted::Role
def configure(user)
can :create, Post
can :destroy, Post do |post|
post. == user
end
end
end
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create new Pull Request