0
votes

I'm feeling really stupid right now. I am using ActiveAdmin to control different things in my NGO: members, staff, donations and so on, each defined as an ActiveAdmin Resource (i.e. tab with different views, actions and so on).

However, I don't seem to be able to implement proper authorization, because ActiveAdmin does not allow Resource to be a feature in its custom AuthorizationAdapters. That is, the subject of the authorize? method is either a Rails model (like User or Donation) or an ActiveAdmin::Page but not an ActiveAdmin Resource.

Actually using the ActiveAdmin::Page for authorization is worse than useless because the subject.name says "Dashboard" no matter whether someone is trying to access members, staff or donations. Also, using Namespace doesn't work because all three were assigned to the :admin namespace. I have not been able to get the authorized? method to tell me the controller name within that namespace, which, according to the documentation, should be Admin::StaffController or similar (knowing the controller name would solve the problem). Some people may be fine using the Rails model for authorisation, but both my Members resource and my Staff resource are based on the User model, they just provide vastly different admin experiences, different actions, and also different people should have access to these admin pages.

Is there really no way to implement access based on the Resource or the controller?? This seems to be the most common-sense way to restrict access to regions of the site, long before we talk about whether someone should be able to delete Users or not...

My production environment currently has ActiveAdmin 1.4.3 with Rails 5.1.

1

1 Answers

0
votes

I solved it. This is in my Staff resource now:

controller do
  before_action -> { require_privilege("administer_staff_in_country", "any") }

  def scoped_collection
    scope = UserPrivilege.get_scope_of_privilege(current_user, "administer_staff_in_country")
    if scope != "any"
      User.staff.where(country: scope)
    else
      User.staff
    end
  end

end

require_privilege is the method I already use elsewhere - authorisation is done on the basis of privileges, similar to Wordpress, rather than levels or roles, so that I can define access in a fine-grained way. Put whatever the name of your admin-checking method is inside the before_action -> { ... } and forget about AuthorizationAdapters unless you need to check authorisation on different model actions.