Furwall plugin provides functionality to prevent unauthorized access to
objects within your controllers. It provides both model and controller extensions
to manage permissions on objects and classes depending on performed action.
The plugin works as an extension to acl_system2
plugin by Ezra Zygmuntowicz & Fabien Franzen.
In order to use this plugin you should install acl_system2 plugin, assign roles
to your users and check that the plugin works as expected.
Next, install the plugin to vendor/plugins folder:
script/plugin install git://github.com/dekart/furwall.gitThen you should create a migration that creates table for Permission model.
Please check db/migrations folder for migration example.
After the table is created you should create your permission rules and use it
in your controllers. For example, you want to check user permissions to edit
Product. You should add permission check in your controller:
If current user (returned by current_user method) has permission for @product –
it will simply pass, otherwise it will raise Furwall::PermissionDenied exception.
Let’s create your first permission rule:
Permission.create( :controllable => Prodict.first, :action => “edit”, :rule => “admin | product_manager” )This rule allows admin and product manager to edit first product. Imagine that
we want to allow admin to edit all products. This rule will help:
Now let’s define Car model which is accestor of Product model (using STI):
class Car < Product endIf we don’t specify any rules for Car model it will inherit rules from Product
model. But if we want – no problem:
Let’s imagine that we want to permit product manager to edit product only if
they are not published yet. Let’s define Product state check:
- Logic that returns true or false
end
end
Then we can specify access rules as follows:
Permission.create( :controllable_type => “Product”, :action => “edit”, :rule => “admin | (product_manager & :pending)” )Furwall will automatically check result of pending? method. If the product is
not published yet it will permit product manager to edit product, otherwise only
admin will be able to edit it.
Another option is to check user role in object context. Let’s assume that our
Product model has owner. Let’s create a method that checks if the user is owner
of the product:
- Logic that returns true or false
end
end
In this case we can create permission as follows:
Permission.create( :controllable_type => “Product”, :action => “edit”, :rule => “admin | .owner” )Furwall will check result of is_owner? method. If the method returns true -
it will pass.
Let’s take our magic wand and try to create advanced permission rules. For
example we want to permit product edition only for category moderator. We
can specify permission reference for the Product model:
- Logick that returns true or false
end
end
Now we can use it in our rules:
Permission.create( :controllable_type => “Product”, :action => “edit”, :rule => “admin | category.moderator” )Furwall will check is_moderator? for product’s category reference. If the method
returns true – it will pass.
By default Furwall uses current_user method to retreive user for permission
check. You can change this behavior by specifying required user manually:
You can use custom action name for permission taht can be different from
controller action name. For example you can use same action name for both edit and
update methods:
- Update logic goes here
end
end
You can check object permissions in your views:
<% if object_permit?(@product, :manage) %> Management permitted <% else %> Management not permitted <% end %>Or you can restrict some blocks to only permitted users:
<% object_restrict_to(@product, :manage) %> This block is only for managers <% end %>If you have any ideas about extending Furwall – feel free to fork it at Github:
http://github.com/dekart/furwall/tree/masterYou can also provide bug reports at Lighthouse:
http://furwall.lighthouseapp.comBug fixes, patches, and additional specs are greately appreciated.
Copyright © 2008 Alexey Dmitriev
Contact Email: rene.dekart@gmail.com