The ACL Component in CakePHP is very powerful and can be used to solve a wide variety of access control problems. In this tutorial, we provide a step-by-step guide for implementing row level access control to a model. We will assume at least a basic understanding of ACL and Auth in CakePHP.
The example I am using is an editing platform. At the top of the tree are Volumes, each of which contain many Papers. Authors have access to papers, while Editors have access to volumes and all the papers there-in. Because we have two trees, it’s important to design our ACL tree well or it quickly becomes unmanageable. We’ll call the top of our tree Papers, but this choice is arbitrary.
We create the following ACO hierarchy: Papers/Volume/Paper
This tree structure allows you to provide editors access to a volume, which
automatically gives access to the papers inside. This is the beauty of
ACLs.
To create the ACO tree for an existing dataset, we can develop our own cake shell tool. I will assume you have already created the ARO tree for your users and groups.
Once our ACO tree is built, we need to give our users permissions. Again we will use a cake shell tool.
We need to inform our models about our chosen ACO structure. We do this for Papers and Volumes in the same way we would for Users and Groups.
Unfortunately Auth does not provide a way to automatically handle model access. We use beforeFilter to implement access control manually in the necessary controllers.
First we check that they’re not an admin, then we apply our Acl check. This relies on the fact that a) access is blocked to users by the ‘controllers’ Aco tree and b) access is granted to editors/volumes to this controller by the ‘controllers’ Aco tree. Both of these constraints are enforced by Auth (with $this->Auth->authorize = ‘actions’).
The only thing remaining is displaying a list of papers and volumes
that a user has access to, instead of all the papers/volumes. This is quite difficult for large trees because it’s simply not what ACL’s are designed for. There’s work being done in Cake 1.3.x.x to build an access cache which would solve this problem, but in the mean time:
The same applies to the volumes controller, but a little simpler as
you don’t need the hierarchy.
And that’s it, we’ve implemented complete row-level access control in CakePHP. Cake’s AclComponent is incredibly flexible and very powerful, as you can see you can design quite clean and fine-grained permissions quickly and efficiently.
I hope this tutorial helps other developers out there with similar problems, and as always let me know if you have comments or suggestions.