views:

166

answers:

1

I am using acl9 on top of authlogic on one of my projects. I like the approach acl9's approach but I guess I am trying to do something that is just not that simple (not to say impossible).

For reasons of usability I would like to have an inline admin panel. So for example say I got a resource auction and a nested resource auction/bid. When a normal user is on auctions/1 (1=id) he should see the "normal" stuff (description, price...), a privileged user on the same site should have additional links for editing an auction (= auctions/1/edit). And this is where the fun starts.

Maybe I did not look close enough or in the wrong places but I could not find way to determine wether my current user is authorized for the edit action. Obviously I could display the link to everyone and let the edit action reject the normal user, but that is not a viable option. What bugs me here is that the information is already in the system (see the access_control block below) and I can't seem to find a way to use it. This is not DRY on so many levels.

 access_control do
  allow :privileged, :to => [:index, :show, :edit, :update]
  allow anonymous, :to => [:new, :show, :create]
 end

It becomes even worse if I want to determine which rights a user has on auctions/1/bids/2/edit because this is in a totally different controller.

How can I access that information in advance and then decide whether to display a link to edit at all? Is it just not possible (without changing acl9 itself) or did I not look hard enough? Are there any authorization plugins that meet my requirements better?

A: 

what do you mean by accessing it "in advance"? Do you want to render different templates for the different users, or just have conditionals in the template to hide/show parts of it depending on the user's access levels? I believe it should be as simple as having something like this in the code or template:

if current_user.has_role?(:privileged)  
  # here goes the stuff that should be displayed to privileged user only  
end

If you need to access your specific set of rules in the template (like "have I allowed this user to access the edit action?") you can't do it with acl9. And I believe you shouldn't do it anyway, as it doesn't seem good to tie your business logic and auth control to your controller - if you decide to rename the controller tomorrow, your logic with fail. But it can see two ways to solve it.

  1. Split your roles into more detailed ones. For example, split "privileged" into "editor", "creator", "deleter", etc. Thus you can build your access rules with these smaller rules and use them in the template for a fine control.

  2. Delegate roles check to your objects. That's the way I usually do it in my projects, as it allows to work only with global roles and let the models decide whether the user is allowed to do something to them - like if @auction.allows_edit_for?(current_user) {}, for example. It requires a couple of overrides for the acl9, I've blogged about this method here some time ago.

morhekil