public
Description: A Ruby on Rails plugin that provides fine grained access control to RESTful resources in a Ruby on Rails 2.0+ project.
Homepage: http://mdarby.github.com/restful_acl/
Clone URL: git://github.com/mdarby/restful_acl.git
name age message
file MIT-LICENSE Fri May 02 14:52:21 -0700 2008 I guess a license that references the author is... [mdarby]
file README.textile Tue Nov 24 06:13:40 -0800 2009 Updated README with updated installation instru... [mdarby]
file Rakefile Mon Nov 23 19:20:30 -0800 2009 Updated README, etc [mdarby]
file VERSION Tue Nov 24 07:45:31 -0800 2009 Version bump to 2.1.3 [mdarby]
file init.rb Sun Dec 14 09:41:00 -0800 2008 Now working as plugin and GemPlugin [mdarby]
directory lib/ Tue Nov 24 07:34:37 -0800 2009 Fixed accidental monkeypatch [mdarby]
directory rails/ Tue Nov 24 06:12:26 -0800 2009 Refactored so that you don't have to specify :l... [mdarby]
file restful_acl.gemspec Tue Nov 24 07:45:36 -0800 2009 Regenerated gemspec for version 2.1.3 [mdarby]
file uninstall.rb Thu Feb 07 20:08:06 -0800 2008 Initial import of Restful_Acl git-svn-id: htt... [mtdarby]
README.textile

RESTful_ACL

A Ruby on Rails plugin that provides fine grained access control through the MVC stack to RESTful resources in a Ruby on Rails 2.0+ application. Authorization is as simple as true or false.

What it does

RESTful_ACL is a simple Access Control Layer for Ruby on Rails. It restricts access on a fine-grained level to any RESTful MVC stack. Every application is different and everyone likes to setup their User / Account / Role resources differently; this plugin will allow you to do your thing and keep that thing locked down.

Requirements

RESTful_ACL requires the super amazing RESTful_Authentication plugin.

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 two named routes: “error” and “denied”. Add the following to your routes.rb file:


map.error ‘error’, :controller => ‘some_controller’, :action => ‘error_action’
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 Helpers

There are five view helpers also included in RESTful_ACL: #indexable, #creatable, #readable, #updatable, and #deletable. These enable you to do nifty things like:


= link_to ‘Foo Index’, foos_path if indexable
= link_to ‘Edit Foo’, edit_foo_path(foo) if updatable(foo)
= link_to ‘Create Foo’, new_foo_path if creatable
= link_to ‘View Foo’, foo_path(foo) if readable(foo)
= link_to ‘Delete Foo’, foo_path(foo) if deletable(foo), :method => :destroy

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
project = mock_model(Project) @author = mock_model(User, :projects => [project])

@issue = Issue.factory_girl(:issue, :author => @author, :project => @project) end it “should be modifiable by the author when the Project is active” do @project.stub!(:is_active? => true) issue.is_updatable_by(author, @project).should be_true end it “should be deletable by the author” do issue.is_deletable_by(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

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