1
votes

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?

3
I face the same error for rails_admin on /admin, though I added rescue_from in my application_controllerSaravanabalagi Ramachandran

3 Answers

0
votes

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
0
votes

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

0
votes

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

Making the change solved my issue.