Major changes in 3.0 release!

  • RESTful_ACL has been completely refactored for speed and usability.
  • A full Cucumber test suite has been written (http://github.com/mdarby/restful_acl_app).
  • The view helpers creatable, deletable, updatable, readable have been replaced by allowed? (see below for more details).

RESTful_ACL

RESTful_ACL is rails gem that provides a full stack, contextual access control to RESTful resources. Authorization is as simple as true or false.

What it does

RESTful_ACL is a context-based permission engine. It provides full stack access control that is resource context aware. (If a parent is closed, a child is not editable, etc.)

Requirements

RESTful_ACL requires the notion of a current_user. Most authenticaion plugins provide this (AuthLogic, RESTful_Authentication, etc.)

How to Install

Install the RESTful_ACL gem:

sudo gem install restful_acl -s http://gemcutter.org

Add the gem to your environment.rb file as thus:

config.gem “restful_acl”

RESTful_ACL requires a named route named “denied”. Add the following to your routes.rb file:

map.denied ‘denied’, :controller => ‘some_controller’, :action => ‘denied_action’

How to Use

Controllers

Add before_filter :has_permission? into any controller that you’d like to restrict access to (or application_controller.rb for your entire app).

Models

Define a parent resource (if one exists) by using the logical_parent method, and define the following five methods in the model of every resource you’d like to restrict access to. The five methods can contain anything you’d like so long as they return a boolean true or false. This allows you to define your User’s roles any way you wish.


  class Issue < ActiveRecord::Base
    logical_parent :some_model_name

    # This method checks permissions for the :index action
    def self.is_indexable_by(user, parent = nil)
    end

    # This method checks permissions for the :create and :new action
    def self.is_creatable_by(user, parent = nil)
    end

    # This method checks permissions for the :show action
    def is_readable_by(user, parent = nil)
    end

    # This method checks permissions for the :update and :edit action
    def is_updatable_by(user, parent = nil)
    end

    # This method checks permissions for the :destroy action
    def is_deletable_by(user, parent = nil)
    end
  end

Singleton Resources

RESTful_ACL 2.1+ supports singleton resources. Just pass :singleton to the logical_parent


  class Car < ActiveRecord::Base
    logical_parent :owner, :singleton
    ...
  end

View Helper

RESTful_ACL provides you with a view helper named allowed?. Simply pass this method a block containing the URL you’d like to check permission on and it will do the rest. If the current_user is allowed to access the requested link’s action, the link will appear; otherwise no link will show.

= allowed?{ link_to ‘Foo Index’, foos_path }
= allowed?{ link_to ‘Edit Foo’, edit_foo_path(<code>foo) }
= allowed?{ link_to 'Create Foo', new_foo_path }
= allowed?{ link_to 'View Foo', foo_path(</code>foo) }
= allowed?{ link_to ‘Delete Foo’, foo_path(@foo), :method => :delete }

Huh? Here’s an example

Let’s say that you have two resources: Project and Issue. A Project has many Issues, an Issue belongs to a Project. I’d like to make sure that the current user is a member of the Project before they can create a new Issue in that Project:


  class Issue < ActiveRecord::Base
    logical_parent :project

    belongs_to :author
    belongs_to :project

    def self.is_indexable_by(user, parent = nil)
      user.projects.include?(parent)
    end

    def self.is_creatable_by(user, parent = nil)
      user.projects.include?(parent)
    end

    def is_updatable_by(user, parent = nil)
      user == author && parent.is_active?
    end

    def is_deletable_by(user, parent = nil)
      user == author
    end

    def is_readable_by(user, parent = nil)
      user.projects.include?(parent)
    end
  end

Admins RULE!

RESTful_ACL grants global access to all actions to site administrators. To enable this, make sure that your User model defines an is_admin? method and/or an is_admin attribute. If the current_user.is_admin? returns true, access will be granted automatically.

How to Test

I normally do something along these lines in RSpec:


  describe “Issue” do
    before do
      <code>project = mock_model(Project)
      @author  = mock_model(User, :projects => [</code>project])
      @issue = Issue.factory_girl(:issue, :author => @author, :project => @project)
    end</p>
it “should be modifiable by the author when the Project is active” do
@project.stub!(:is_active? => true)
<code>issue.is_updatable_by(</code>author, @project).should be_true
end
it “should be deletable by the author” do
<code>issue.is_deletable_by(</code>author, @project).should be_true
end
it “should be readable by those assigned to the Project” do
Issue.is_readable_by(@author, @project).should be_true
end
it “should be creatable by those assigned to the Project” do
Issue.is_creatable_by(@author, @project).should be_true
end
end
<p>

Help

Add a ticket to RESTful_ACL’s Lighthouse Account

About the Author

My name is Matt Darby. I’m an IT Manager and pro-web-dev at for Dynamix Engineering and hold a Master’s Degree in Computer Science from Franklin University in sunny Columbus, OH.

Feel free to check out my site or recommend me