Access Control for all (Part 2)

5 October, 2006

Show comments

If you have followed the advice of the previous post on ACL then you should have some code that permits you to put in place ACL checks for your site with very little effort. There is however still the other side of ACL to do and that is the (potentially) significant effort of setting up your ACL rules.

As I mentioned in that post I was going to provide a live demo as always, the source code for which you can download from the demos tab at the top of the page.

The code was based on the ACM plugin, but is completely rewritten with some enhancements - especially to the way access control objects are defined. It is not perfect and I removed any extra javascript code for simplicity, I would welcome comments and even contributions ;).

Learn by doing

Explanations are great, but you can learn more by seeing changes occurring, so there will be no code description in this blog because you can download the source and see it for yourself.

Manage what is controlled

Have a look at the ACO Management section.

In this section you can define what level of granularity you want to apply. You can create acos for a plugin/application, for a controller or for a method. The aco objects are found by directly querying your application, and as such there is no tedium in typing the names of your controllers and methods into the acl management system. After a mini debate I didn't modify the way the code generates the aco objects and as such you can see some controllers that are not publicly visible - an advanced hidden preview feature for this site built in :)!

If you already have some acos that are not displayed on this page you can see them via the data view or if you prefer you can view them flat with the paginated index.

If there is no aco created for a given method or controller the rights are inherited from the 'parent'. I say 'parent' because if there is no aco - it has no parent. So what am I talking about? Well, if you do not create an aco for app:private_personal_controller:private_personal_things, then the rights will be inherited as whatever is defined for app:private_personal_controller and so on. If there is no aco defined for the last parent, the code for querying the acl in the first post on this topic will assume that the user has access as it is not included in the acl system.

How does it work

If you choose to define a 'global' aco for any section/controller, 1 aco will be created, and queries for the associated methods will inherit whatever acl you define for the 'global' aco.

If you choose to define 'Granular' level of control, an aco will be created for each controller and controller method that is under your chosen object.

If you add a new method to a controller or create a new controller in a section that has granular level of acos defined you can incorporate your new method by choosing the 'recheck' option which will create acos for any controllers/methods that do not exist.

The remove links should be quite clear, with this you can delete the aco (and any associated rights) such that the parent definition prevails, you also have the possibility to only delete the child acos to revert to global control without losing any rules defined for the new global aro.

In this way you can define any type of control that you would like, so for example:

You would like to have granular control at the 'app' level, because by default you want to be able to deny all users, and you want the option to define on a controller by controller (or method by method) basis who has access to what - so you click that option 'granular' for app. However you don´t care for this level of detail for your 'pages' controller and would simply like to be able to say "all users can access all pages" - there's no need in this case to define an aco for each page, there's no harm in it either, but you can remove the granular control from this controller and 'go global' instead. In this way it is possible to meet this requirement.

By now you are getting the idea I hope :).

Manage who is controlled

Have a look at the ARO Management section.

This section isn't so advanced but permits you to create an aro for each user in your system, and move them around such that they have the rights that you want.

In the demo example, aros in capital letters (such as "USERS") are groups, and lower case aros are individuals.

There should be little explanation required here - you have the possibility to add an aro into the system that is missing (you would normally edit your user create method to create this object for you) and also assign a user to a group etc. The demo does not cater for the possibility of a user being a member of more than one group because the DB ACL solution at this time also doesn´t permit this. However, it would not be difficult to change your app controller checkACL function to check the rights for the user and each group they are a part of.

As with your controllers and methods you can also view your aros flat via the paginated index.

If you already have a table full of uses, specify the name of the user model you are using in the constant at the top of the plugin app controller, and with the "Load from user table" you can create an aro for each user. The code here doesn't refer to roles or groups and as such they are loaded 'flat', with the possibility to move or delete users/groups.

Manage who can access what

Have a look at the ACL Management section.

The permission section allows you to allow or deny any defined aro access to any defined aco. The aro list is limited to the current aro and it's direct children, hence initially you can see only the aros PUBLIC and USERS. If you click the row USERS you will then have the possibility to administer rights on a user by user basis. Don't see what I'm talking about? Well it's live, and that means that anyone can delete the aros or acos but simply by using the aco management section you can create granular control for the app (for example) and from the aro section create the aros from the user table and voila the acl section is populated again.

As with the other tables there is also Paginated indexes for your defined acl rules so that you can see the effect of the changes you make.

Wrapping up

So what now, that's all well and good but how can I use it? Here's the no-nonsense answer:

  • Get the code from the Demo download section
  • Create the acl tables using the sql script that comes with cake
  • Put the plugin into your own application
  • Define the name of your user table in the plugin app controller file
  • Use the plugin to create the aros, acos and rules as you want for your own application
  • Add the code from the previous post on ACL to check the ACL for each page request
  • Add to your user/group beforeSave method such that an aro is created when a new user or group is created. Equivalently you should also add a beforeDelete method.

You then have fully and easily configurable access control applied to your application.

Well that's it for today, I hope that's found to be useful and comments are most welcome :).