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.
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
This no longer works with Rails 5.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With