Rails ACL Design Question
I am working on a legacy rails codebase and need to implement some ACL logic that is not based around standard CRUD operations on objects, but instead around custom logic about what parts of a page are shown to different groups of users. These page "parts" are not defined by any objects in the database, so my guess is that object-based ACL systems may not be the best fit here.
I currently researching declarative_authorization but haven't yet determined if it can do anything other than object-based permissions.
This must be a 开发者_JAVA技巧rather common use-case for web applications and I'd prefer not to roll yet another ACL. Does anyone have a suggestion for a 3rd party library that would work well for this?
I think CanCan can help you. It's simple to use and should do just what you need. Here's a RailsCast: Authorization with CanCan
I have looked through a whole bunch of different Authorization and ACL plugins and like you I did not like the CRUD approach that most of them used.
In the end, the most suitable for me was a setup similar to that which Redmine uses. I don't know if it origins from any named plugin but I spent some time getting to understand it and made the necessary adjustments for my case.
Basically what it does is to allow use of controllers and actions, either global or for specific models. You start with specifying what different permissions are assignable:
MyApplication::ACL.mapper do |map|
map.permission :view_project, {:projects => :show}
map.permission :manage_project, {:projects => [:update, :edit, :post_status]}
map.permission :delete_project, {:projects => :destroy}
end
Next step is to assign one or more permissions to a Role which is a model with a serialized field which can store the permissons, ie:
<#Role id: 1 name: "Intern" permissions: [:view_project] >
<#Role id: 2 name: "Member" permissions [:view_project, :manage_project] >
And then you map the different Roles with Users by a Membership model. The Membership can also be mapped with specific models, like Project, since you might be allowed to manage one project but not another one, or it can be global like some index actions which should be restricted but you don't know which Model to authorize against yet.
In the controllers you verify all this by using:
before_filter :authorize, :only => [:show, :update, :edit,
:post_status, :destroy]
And authorize is of course a method that checks if the current user is a member of any role that has the permission required for the current Controller and Action.
This is, although a long description here, only in short how it works :) It is alot more complicated than other ACL plugins out there but I think it is the most "clean" alternative while still allowing the flexibility that I need.
精彩评论