On Jan 17, 2011, at 10:16 AM, David Kahn wrote:

> On Mon, Jan 17, 2011 at 9:48 AM, Ants Pants <antsmailingl...@gmail.com> wrote:
> Hello all,
> 
> From what I've seen, this type of question doesn't really seem to get an 
> answer on this list as most of the replies relate to failures of RSpec. If 
> this is the case, where is the best place to go to get advice about best 
> practices etc?
> 
> I have a question about best practice. In some of my controllers only an 
> admin user can perform edit, update, show etc. So I have a before filter in 
> those controllers; ApplicationController#authorise_is_admin
> 
> The ApplicationController#authorise_is_admin throws an AccessDenied exception 
> and that is caught in ApplicationController#access_denied
> 
> My question is, in the spec for the calling controller, let's say 
> ProductGroups, what should I spec?
> 
> I have a context "user is admin" and that's easy to spec, but the context 
> "user is not admin" is where I'm stuck as no actions are performed in that 
> controller but I would just like to cover that failure somehow.
> 
> Interesting question. I had the same dilemma and decided that it took too 
> much effort and test code to test this at the controller level. What I do 
> (and this may or may not work for you depending on your apps security needs), 
> is to have an authorize method in the User model. It returns success or 
> failure based on the controller and action passed. The model looks something 
> like this:
> 
>   def authorize(controller_name, action_name)
>     if self.role
>       current_role = self.role.name
>     else
>       # guest user is empty user
>       current_role = 'guest'
>     end
>     
> 
>     case controller_name
>     when 'activations'
>       if current_role != 'guest'
>         return set_autorize_failure_value("You are already logged in to the 
> system. If you are activating a new user please log out first and try again.")
>       end
>       return authorize_success_message
>       
>     when 'feedback_supports'
>       if current_role == 'guest' || current_role == 'sysadmin'
>         return set_autorize_failure_value(LOGIN_NOTICE)
>       end
>       return authorize_success_message
> ...
> 
> end
> 
> Then in the spec it is real easy:
> 
>   describe "user authorization - guest role" do
>     it "is authorized to access certain pages only" do
>       user = User.new
>       user.authorize('activations', 'create')[:success].should == true
>       user.authorize('home', 'index')[:success].should == false
> 
>     ....
> 
>     end
>   end
> 
> This might not be everyone's cup of tea and I am sure I can refactor and make 
> this less verbose, but what I like is having the 'dna' of all my access 
> rights app wide in one place.

Definitely agree with the idea of keeping decisions in one place. I don't 
really like the idea of 'controllers' living inside a model, but change 
'controller_name' to 'resource_collection_name' and that solves that problem.

I would still want to specify that the controller asks the user for 
authorization. WDYT?
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to