Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActiveAdmin + CanCanCan errors with : protected method `authorize!' called for <Every ActiveAdmin Controller>

I'm having some trouble getting ActiveAdmin to work with CanCanCan. I'm using CanCanCan version 1.9.2 and ActiveAdmin version 1.0.0.pre in a Rails 4 app. After setting up my ability class and enabling authorization checks in the rest of my app by adding load_and_authorize_resource and check_authorization to my ApplicationController, I get the error

protected method 'authorize!' called for #<Activeadmin::<SomeControler>> (NoMethodError)

After some searching, I ran into this this GitHub issue that looks exactly like the problem I'm having. The solution does not work at all for me, however. In config/initializers/active_admin.rb I have, among other things: ... config.authorization_adapter = ActiveAdmin::CanCanAdapter ... I have also ensured that I have no references to controller.authorize_resource in any ActiveAdmin controller, yet I still get the protected method authorize! ... error when I try to access any ActiveAdmin resources from my integration tests.

After some more trial and error and more searching, I discovered that calling load_and_authorize_resource from ApplicationController was not recommended, and that setting ActiveAdmin's authorization_adapter to CanCanAdapter as I did above should automatically enable CanCanCan's authorization checks in ActiveAdmin, but check_authorization fails because the resource was not authorized for every ActiveAdmin controller when load_and_authorize_resource is removed from ApplicationController.

So what is the correct way to enable CanCanCan's authorization checks for my ActiveAdmin controllers? How should I integrate CanCanCan and ActiveAdmin so that non admin users can't access any ActiveAdmin resources?

I also posted this question to the ActiveAdmin mailing list but got no responses. Any help would be greatly appreciated.

like image 894
732 Avatar asked Oct 06 '14 22:10

732


2 Answers

After digging through the code, I've figured out what's happening. ActiveAdmin and it's CanCanAdapter is not yet compatible with CanCanCan's check_authorization method. That method relies on an @_authorized instance variable being set on the controller by the authorization method, but ActiveAdmin's authorization does not set this variable. So, even though ActiveAdmin IS performing the authorization, check_authorization always fails because ActiveAdmin is not setting this instance variable. I've reported the issue, but the workaround for now is to add an unless: clause to check_authorization that matches all ActiveAdmin controllers. This stops check_authorization from running for these controllers, but, as long as CanCanAdapter is enabled, ActiveAdmin IS still performing the proper authorizations before responding with the resource.

Here is the workaround that I've added to my ApplicationController until the issue is fixed, if it ever will be:

class ApplicationController < ActionController::Base
  ...
  check_authorization unless: :activeadmin_resource?
  ...
  private

  def activeadmin_resource?
    self.class.ancestors.include? ActiveAdmin::BaseController
  end
end
like image 121
732 Avatar answered Oct 20 '22 07:10

732


This no longer works with Rails 5.

like image 44
Bramski Avatar answered Oct 20 '22 07:10

Bramski