How to limit access to model objects based on role?

Hi all,

I want to limit access to model objects based on the role of the logged
in
user. It seemed the most blunt way of doing this would be make copies of
each controller which accessed the models and use one of the access
control
systems out there to limit access to the controllers. However, with 9
different controllers this seems like a terrible choice.

Here’s what I’ve come up with. Each controller implements something like
the
following code. Basically, there’s a set_x_with_scope method which
takes
normal find() parameters, then passes them to X.find within
X.with_scope.

So, instead of having @category = Category.find(param[:id]), which would
occur multiple times in the controller, I use
set_category_with_scope(params[:id]), which sets @category and only
allows
access to data based on attributes of the current user.

Right now, I use a collection of methods to build the options for :find
in
with_scope. Soon, I’m going to alter the methods so that their return
values
will depend on the user’s role. I hope all this make sense :slight_smile:

On top of all this, I’m using Ezra’s access control plugin to limit
access
to the controllers.

So my question is: is there a better way to do this?

class CategoriesController < ApplicationController

access_control :DEFAULT => ‘(Administrator | SuperUser)’

def edit
set_category_with_scope(params[:id])
end

def update
set_category_with_scope(params[:id])
@category.update_attributes(params[:category])
end

def set_category_with_scope(*args)
Category.with_scope(:find => scoped_options) do
@category = Category.find(*args)
end
end

def scoped_finder_conditions
@scoped_finder_conditions ||= {:conditions => “positions.company_id =
#{current_user.company_id}”}
end

def scoped_finder_include
@scoped_finder_include ||= {:include => :position}
end

def scoped_options
scoped_finder_conditions.merge(scoped_finder_include)
end

Thanks!
Daniel