RMAC is dead, long live RMAC
…and the Permissionable plugin rose from the ashes…
with apologies to the queen
after an incredibly long delay i have updated the PermissionableBehavior to be a more feature complete plugin (1.3 compatible). my apologies for taking so long, life has been hectic. if you don’t know what i’m talking about, go look here and come back.
so, where’s the beef?
what does the update contain, you ask? well, that’s an excellent question!
- all code bundled up in a nice tidy plugin
- the concept of group bits has been discarded, removing the artificial limitation on number of possible groups
- much faster (possibly due to cakephp 1.3 being faster, dunno)
- test cases and fixtures (100% coverage, bitches!)
- using constants for user_id/group_id(s) has been abandoned in favor of static storage classes (note: not that i think constants are a bad solution, but only that the static class is more flexible)
- behavior init now binds the Permissionable.Permission model in a hasOne association to the primary model. this is better than the previous adding of a join via the $queryData in beforeFind
- an additional benefit of this is the unbinding of the model when permissions are not needed (when user is root, or when permissions have been disabled)
- more concise handling of permissions checking
- better handling of “backout” scenarios (when a record is attempted to be saved when no permissionable information is available)
- better handling of model aliasing, which should help prevent name collisions when querying multiple models that reference the same permissioned model
- added cake schema file to easily create the permissions table (along with a couple SQL files, for those afraid of the command-line)
- 500% cooler. it’ll bring all the boys to the yard.
- Permissionable now lives on github. it’s enjoying its stay so far. go check it out.
how do i tame this wild beast?
easier than ever:
- check out the code from github:
cd /path/to/your/app/plugins && git clone git://github.com/jmcneese/permissionable.git
if you already have your project under git you can do this (it’s call sub-tree’ing), or muddle through setting up and using submodules. pick your poison.
- create the required db table. you can either do this via the SQL files included in permissionable/config/schema (there are two, those who prefer UUID ids, and those who prefer INT), or you can use the schema shell to do this:
cake schema create Permissionable.permission
- take a look at permissionable/controllers/components/permissionable.php. you’ll need to include this in the components array for whichever controllers use your permissioned models, or in AppController.
public $components = array('Permissionable.Permissionable');
also, you’ll need to put some code in the initialize method of the component that sets the id of the logged in user (via AuthComponent or whatever method you use), as well as the group id(s).
- next up, you’ll need to include the behavior in whatever models you want to be permission-controlled:
public $actsAs = array('Permissionable.Permissionable' => array('defaultBits'=>480);
note: you need not include the defaultBits option to the behavior, unless you a) know what you are doing, b) can calculate up the proper bits and c) really need to. if any of the above apply, feel free. if you need a refresher course, look here.
*batteries not included
so, now that you’ve done all that, there’s only a few things you need to know about how to use it. as before, permissions are checked on the fly and transparently. if you have permission to the action you are trying to perform (read/update/delete), then your model call will be successful. if not, you’ll get a big fat false. if you wish to disable this on a per-find basis, you can. e.g.:
$result = $this->Foo->find('all', array( 'permissionable' => false, 'conditions' => array( 'Foo.val' => 'Bar' ) ));
or, this way, in case you need to add it to the scope of something like TreeBehavior or AuthComponent:
$result = $this->Foo->find('all', array( 'conditions' => array( 'permissionable' => false, 'Foo.val' => 'Bar' ) ));
permissions will always be created updated on save though. i might make this configurable in the future, or accept patches for it via github. you can, however, override the permissions of the item being saved via:
$this->Thing->save(array( 'Thing' => array( 'name' => 'Baz', 'desc' => 'Baz is a Thing!' ), 'Permissionable' => array( 'perms' => 416 ) ));
what the future holds
i intend on updating the plugin to have more options for configuration, to whit: implementing some level of inheritable permissions, introducing the concept of roles, supporting “trickle-down” permission changes to models that actAs Tree, common UNIX-y commands like chmod/chown/chgrp.
as always, i welcome comments, questions, patches and suggestions. if you find a bug, let me know… or better yet, submit a patch!
caveat emptor, balatros
- i assume that you have users and groups, meaning that your user has a primary group, and secondary groups. this is UNIX-like, after all. now, an easy and standard way to do this is define model associations like User hasMany Group, User belongsTo Group. it’s really up to you how you want to get that list, Permissionable doesn’t care, so long as you set it in the component.