[rspec-users] [rails] An authorization question

Zach Dennis zach.dennis at gmail.com
Mon Mar 2 17:16:33 EST 2009

On Mon, Mar 2, 2009 at 4:50 PM, Zach Dennis <zach.dennis at gmail.com> wrote:
> On Mon, Mar 2, 2009 at 3:59 PM, James Byrne <lists at ruby-forum.com> wrote:
>> unknown wrote:
>>>> sam.authorized?(controller_or_model, action)?
>>> I'll suggest that it's the controllers who are responsible for telling
>>> what role or other requirements need to be satisfied to get their
>>> services, and that it's the job of the user object (maybe by delegating
>>> to some role class or objects) to provide the information as to whether
>>> those requirements are met.
>> That is what I thought that I was doing.  The Controller sends the
>> message to the User Instance telling it to answer the question: are you
>> authorized to perform "controller + action"?; or role, or whatever the
>> controller sends as the criteria to be met.  It seems to me necessary
>> that the User model receive the context of the authorization call.  Now
>> the actual check on whether user x is authorized to perform the create
>> method of the PaymentReceivedController is done in the #authorized?
>> method of User.
>> Is this what should be done or is there a different way?
> Today, my pair and I hit a scenario which I think maybe a good example
> to clarify.
> Let's say that you have an "admin" and "associate" role. Each role can
> access invoices in the system, but each role can access different
> subsets of invoices.
> In our controller, we could have something like:
> def index
>   if user.has_role?("admin")
>      Invoice.all
>   elsif user.has_role?("associate")
>      Invoice.by_area(current_user.area)
>   else
>     raise AccessDenied
>   end
> end
> We ended up not doing this because the lines "Invoice.all" and
> "Invoice.by_area" is behaviour which is tied specifically to a certain
> role in the system. We don't want behaviour for these roles to be
> scattered throughout controller actions. We want it in one single
> location.
> So we create a FiscalAdmin role object and a FiscalAssociate role
> object. As these roles become filled out we leave the role-specific
> behaviour in one location, creating a well-defined cohesive class for
> each role.
> For me it's a little win, that results in big ways. :)

Forgot to mention what we did do. We ended up with the following...

def index
  if user.has_role?("admin")
  elsif user.has_role?("associate")
    raise AccessDenied

To us, the change here is subtle, but important. The controller is
allowed to ask for invoices from each role, but is not allowed to know
how find the invoices, that's the behaviour of the role.

> --
> - Show quoted text -
> Zach Dennis
> http://www.continuousthinking.com
> http://www.mutuallyhuman.com

Zach Dennis

More information about the rspec-users mailing list