Canable

Simple permissions that I have used on my last several projects so I
figured it was time to abstract and wrap up into something more easily
reusable.

Cans

Whatever class you want all permissions to run through should include
Canable::Cans.

classUserincludeMongoMapper::DocumentincludeCanable::Cansend

This means that an instance of a user automatically gets can methods for
the default REST actions: can_view?(resource), can_create?(resource),
can_update?(resource), can_destroy?(resource).

Ables

Each of the can methods simply calls the related “able” method (viewable,
creatable, updatable, destroyable) for the action (view, create, update,
delete). Canable comes with defaults for this methods that you can then
override as makes sense for your permissions.

classArticleincludeMongoMapper::DocumentincludeCanable::Ablesend

Including Canable::Ables adds the able methods to the class including it.
In this instance, article now has viewable_by?(user), creatable_by?(user),
updatable_by?(user) and destroyable_by?(user).

Lets say an article can be viewed and created by anyone, but only updated
or destroyed by the user that created the article. To do that, you could
leave viewable_by? and creatable_by? alone as they default to true and just
override the other methods.

Now we can implement our permissions for each resource and then always
check whether a user can or cannot do something. This makes it all really
easy to test. Next, how would you use this in the controller.

Enforcers

classApplicationControllerincludeCanable::Enforcersend

Including Canable::Enforcers adds an enforce permission method for each of
the actions defined (by default view/create/update/destroy). It is the same
thing as doing this for each Canable action:

classApplicationControllerincludeCanable::Enforcersdelegate:can_view?,:to=>:current_userhelper_method:can_view?# so you can use it in your viewshide_action:can_view?privatedefenforce_view_permission(resource)raiseCanable::Transgressionunlesscan_view?(resource)endend

Review

So, lets review: cans go on user model, ables go on everything, you
override ables in each model where you want to enforce permissions, and
enforcers go after each time you find or initialize an object in a
controller. Bing, bang, boom.

Note on Patches/Pull Requests

Fork the project.

Make your feature addition or bug fix.

Add tests for it. This is important so I don't break it in a future
version unintentionally.

Commit, do not mess with rakefile, version, or history. (if you want to
have your own version, that is fine but bump version in a commit by itself
I can ignore when I pull)