Cancan + Devise rescue_from not catching exception
Asked Answered
W

3

1

I am implementing Devise and Cancan for user authentication and permissions. Everything works great so far except I am not able to redirect users to the login page when they are not allowed to access a specific feature.

My test is:

feature 'A signed in user' do
  before(:each) do
    user = FactoryGirl.create(:user)
    visit "/login"
    fill_in "user_email", :with => user.email
    fill_in "user_password", :with => "ilovebananas"
    click_button "Sign in"
  end

  scenario 'should not have access to admin dashboard' do
    visit '/admin'
    page.should have_content 'Log in'
  end
end

And I get the following failure:

Failures:
      1) A signed in user should not have access to admin dashboard
         Failure/Error: visit '/admin'
         CanCan::AccessDenied:
         You are not authorized to access this page.

To be clear, all my permission management works as expected so far, except the redirection to login page.


Here is how things are set up:

ApplicationController:

check_authorization :unless => :devise_controller? # Cancan

rescue_from CanCan::AccessDenied do |exception|
  redirect_to login_path, alert: exception.message
end

UsersController

class UsersController < ApplicationController
  load_and_authorize_resource         # Cancan
  def queue  
    ...
  end

  ...
end

AdminsController

class AdminController < ActionController::Base
  authorize_resource :class => false # Cancan, used because AdminController doesn't have an associated model
  ...
end

ability.rb

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user, not logged in
    can :queue, User

    if user.has_permission? :super_admin
      can :manage, :all
    elsif user.has_permission? :network_admin

    end      
  end
end

What am I missing?

Whenever answered 26/12, 2012 at 21:4 Comment(1)
I face the same error for rails_admin on /admin, though I added rescue_from in my application_controllerCatawba
W
0

My Admins Controller was not < ApplicationController, so it did not load the ApplicationController rescue_from method.

Making the change solved my issue.

Whenever answered 26/12, 2012 at 22:27 Comment(0)
G
0

you must pass class name as string. try quoting it. or try

rescue_from CanCan::AccessDenied , :with => :login_page
private
def login_page
   redirect_to login_path
end
Grimaud answered 26/12, 2012 at 21:19 Comment(2)
I just tried it and it doesn't seem to work either. How is this different from what I already have in my ApplicationController?Whenever
try like rescue_from 'CanCan::AccessDenied' (quotes)Grimaud
A
0

You should to add "controller.authorize_resource" to admin/register.if abilities without conditions.

controller.authorize_resource

Example: can :manage, :all

If conditions are,

controller do
  load_and_authorize_resource :except => [:update,:index, :show, :edit]
    def scoped_collection
      end_of_association_chain.accessible_by(current_ability)
  end
end

Example: can :manage, Master::Country, :organization_branch_id => each_branch.id

i hope it help you

Acquiescent answered 26/12, 2012 at 21:19 Comment(1)
I already have this in my code (see edit in my question). Any other idea?Whenever
W
0

My Admins Controller was not < ApplicationController, so it did not load the ApplicationController rescue_from method.

Making the change solved my issue.

Whenever answered 26/12, 2012 at 22:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.