Grant
Grant is a Ruby gem and Rails plugin that forces you to make explicit security decisions about the operations performed on your ActiveRecord models. It provides a declarative way to specify rules granting permission to perform CRUD operations on ActiveRecord objects.
Grant does not allow you to specify which operations are restricted. Instead, it restricts all CRUD operations unless they’re explicitly granted to the user. Only allowing operations explicitly granted forces you to make conscious security decisions. Grant will not help you make those decisions, but it won’t let you forget to.
Additional information beyond that found in this README is available on the wiki.
Installation
To install the Grant gem, simply run
gem install grant
To use it with a Rails 3 project or other project using Bundler, add the following line to your Gemfile
gem 'grant'
For your Rails 2.x project, add the following to your environment.rb file
config.gem 'grant'
Lastly, Grant can also be installed as a Rails plugin
script/plugin install git://github.com/nearinfinity/grant.git
Setup
Grant needs to know who the current user is, but with no standard for doing so you’ll have to do a little work to set things up unless your ApplicationController exposes a current_user method. If you don’t have a current_user method in ApplicationController, you simply need to set your current user model object as the Grant current user before any CRUD operations are performed. For example, in a Rails application you could add the following to your application_controller.rb
class ApplicationController < ActionController::Base
before_filter :set_current_user
private
def set_current_user
Grant::User.current_user = @current_user
end
end
The above is essentially what Grant does if you have a current_user method in ApplicationController.
Usage
To enable grant you simply start calling the grant method. Grant will initialize itself on the first invocation of the grant method in a class. In the example below you see two grant statements. The first grants find (aka read) permission all the time. The second example grants create, update, and destroy permission when the passed block evaluates to true, which in this case happens when the model is editable by the current user. A Grant::Error is raised if any grant block evaluates to false or nil.
class Book < ActiveRecord::Base
grant(:find) { true }
grant(:create, :update, :destroy) { |user, model, action| model.editable_by_user? user }
def editable_by_user? user
user.administrator? || user.has_role?(:editor)
end
end
The valid actions to pass to a grant statement are :find, :create, :update, and :destroy. Each action can be passed as a Symbol or String. Any number of actions can be passed to a single grant statement, which is very useful if each of the actions share the same logic for determining access.
If you’d like to find out if a certain action is granted without attempting the action and having Grant potentially raise an error, you can use the ‘granted?` method.
book = Book.first
book.granted?(:destroy, some_user)
If you don’t pass a user as the second argument to ‘granted?`, the `Grant::User.current_user` will be assumed.
Inheritance
Subclasses inherit all the ‘grant` statements defined on their parent, but are free to override any of them individually simply by redefining them. For example:
class Book < ActiveRecord::Base
self.abstract_class = true
grant(:create, :find, :destroy) { true }
grant(:update) { false }
end
class Ebook < ActiveRecord::Base
grant(:update) { true }
grant(:destroy) { false }
end
Instances of the parent class ‘Book` can always be created, found, and destroyed, but never updated. However, `Ebook` instances can be created, found, and updated, but never destroyed.
Integration
There may be some instances where you need to perform an action on your model object without Grant stepping in and stopping you. In those cases you can include the Grant::Status module for help.
class BooksController < ApplicationController
include Grant::Status
def update
book = Book.find(params[:id])
without_grant { book.update_attributes(params[:book]) } # Grant is disabled for the entire block
end
end
License
Grant is released under the MIT license.
Copyright © 2011 Near Infinity. www.nearinfinity.com