rails_admin with cancan not catching access denied exception for redirect
Asked Answered
C

2

9

I am using rails 5, rails_admin, devise and cancancan.

Everything works correctly, but when there is access denied, it shows a 'You are not authorized to access this page' error screen.

I want to redirect to root_path, I've been searching and I only found that I have to write in app/controllers/application_controller.rb this code:

class ApplicationController < ActionController::Base    
    rescue_from CanCan::AccessDenied do |exception|
        redirect_to root_path, :alert => exception.message
    end
end

And I did, but I am still in the error message when not authorised. It does not redirect.

I think the rest of the code must be ok, because it works, but not redirecting to anywhere.

#config/initializers/rails_admin.rb
config.authorize_with :cancan
config.current_user_method(&:current_user)

.

#app/models/ability.rb
class Ability
    include CanCan::Ability

    def initialize(user)

    user ||= User.new # guest user (not logged in)
    if user.admin
        can :access, :rails_admin       # only allow admin users to access Rails Admin
        can :dashboard           
        can :manage, :all
    else
        can :read, :all                   # allow everyone to read everything
    end
  end
end

I saw more people asking the same, but all of them are without answers. I found one with 3 answers, but I don't understand the accepted solution because it really do not explain any solution: Cancan + Devise rescue_from not catching exception

Claudiaclaudian answered 2/11, 2016 at 18:52 Comment(0)
S
14

It looks like ApplicationController isn't actually a parent of RailsAdmin::MainController by default. So, when RailsAdmin::MainController throws the CanCan::AccessDenied exception, it never actually touches ApplicationController, and the rescue block never kicks in.

You can explicitly declare ApplicationController as the parent for RailsAdmin::MainController in the rails_admin.rb config block with

config.parent_controller = 'ApplicationController' 
Stickler answered 4/11, 2016 at 4:52 Comment(3)
Yes - also solution for mine. Using rails_admin (1.1.1)Cavil
Worked for me I upgraded from 0.8.0 to 2.0.2Freezedrying
This answer worked for me as well. Thank youContradance
G
5

You can also achieve this by extending the rails_admin controller. This is monkey patching, but can be useful if you don't want to set the parent controller to ApplicationController due to a particular reason.

Add following to config/initializers/rails_admin_cancan.rb file.

require 'rails_admin/main_controller'

module RailsAdmin

  class MainController < RailsAdmin::ApplicationController
    rescue_from CanCan::AccessDenied do |exception|
      flash[:alert] = 'Access denied.'
      redirect_to main_app.root_path
    end
  end
end
Garrow answered 28/11, 2019 at 13:21 Comment(2)
This worked like a charm! The accepted solution raised an Access Denied error for the dashboard of rails admin, as it there was no authorization performed. Maybe bc I have a check_authorization in my applications_controller and no load_and_authorize_resource in a specific rails admin resource. Nevertheless your suggestion worked.Borate
This is the way better solution! Changing the parent controller brought other problems to me as well!Parttime

© 2022 - 2024 — McMap. All rights reserved.