Access Control Lists (ACLs) Part 2

In my last post, I covered a little bit about what an Access Control List (ACL) was. The Cookbook provides a great more detail.
To go along with the idea of the last post, the application has a few different areas: Users who are members of groups, Groups which have users as members, and Events that belong to either the user or the group. Since the creation of ACOs and AROs are basically the same for each area (Users, Groups, Events), I will detail some code for the Users area making use of ACLs.
The first thing we need to do is create an ARO grouping and an ACO grouping. Remember that AROs are the requester of an object. In this example, we can think of them as people. And people have different types of roles, which is what we need to create for the people. In this example application, there will be site admins (Admins), group leaders (Leaders) and regular members (Members). So we need to create this type of ARO. We can do this in a controller, and a page, or we can do this via the command line.

If you create the AROs and ACOs via a controller, it would be done this way:

$aro = new Aro();
$groups = array(
0 => array('alias' => 'Admins'),
1 => array('alias' => 'Leaders'),
2 => array('alias' => 'Members'),
);

foreach($groups as $data)
{
$aro->create();
$aro->save($data);
}

Instantiate the new ARO object, then set up information for the ARO. Then iterate through the array in a foreach loop. You can do the same for the ACO parents that need to be created. The ACOs in this example are similar to our models. There are events, users, and groups. To create those, follow the same pattern as above, only make sure to use the “Aco()” object. However, an easier way (at least I think so), is to use the command line interface (cli) to create these.
To use the cli for this, you will need to be logged in via “SSH” to the server, or connected via shell, or however else you choose to connect. The command to create the ACOs and AROs is:

# cake acl create aro (parent) (node)
# cake acl create aco (parent) (node)

So if I was going to create the groups for the parent AROs, I would do the following:

# cake acl create aro Members admin

NOTE: If you have not set up the CakePHP console paths according the Cookbook specifications, then you may have to use this command line a little different call. I always suggest to run the console from the App folder. From there, you can run the following:

# php ../cake/console/cake.php acl create aro Members admin

I do suggest you set up the console to work without this, but if for some reason you are unable to, this can work as well.
So this will set up each parent ARO and ACO. Now we need to address the users. If there are already users in the system, then we can use the cli to update them and add them to the ARO table. However, users a different bunch, and this is why I choose to use the example on them instead of events or groups. Events and groups are both objects which are requested by users. But users, they are different. For example, if a user with the username of “test1″ exists, and logs in, and then sees another account, let’s say that account username is “answer1″, we do not want “test1″ to be able to edit this account. However, we would want an administrator to have this ability. So we need to lock down edit permissions from “test1″ so that he can only update his own account, and we want to be able to give administrators access to edit any User account. So now users are not only an ARO, but they become an ACO as well. And we need to give (or deny) permissions to any user based on who they are.
So lets say we have 3 users already in the system. “BigMan1″, and administrator, “Newbie” and “Lilie” both regular members. We want to be able to create an ARO for each of them, and then create an ACO for each of their accounts, and then give them permissions. To create the ARO and ACO for each account (with showing the return from the console):

$ cake acl create aro Members BigMan1
New Aro 'BigMan1' created.

X-Powered-By: PHP/5.2.6
Content-type: text/html

$ cake acl create aco Users BigMan1
New Aco 'BigMan1' created.

X-Powered-By: PHP/5.2.6
Content-type: text/html

Now we can follow this for the other two and they would be created. Now we need to give them permissions. The admin should have access to edit any User account, delete any user account except for their own, and be able to view any User account. To grant permissions, the command is:

$ cake acl grant admin aro aco action

The action can be one of the four CRUD members or “all”. We are going to start with the admin user, because they will get access to all Users.

$ cake acl grant BigMan1 Users update
Permission granted.
X-Powered-By: PHP/5.2.6
Content-type: text/html

$ cake acl grant BigMan1 Users delete
Permission granted.
X-Powered-By: PHP/5.2.6
Content-type: text/html

$ cake acl grant BigMan1 Users read
Permission granted.
X-Powered-By: PHP/5.2.6
Content-type: text/html

Now there is a problem here. The Admin can delete his own account right now, because we have given him permissions to delete and User account (parent ACO = Users). We do not want him to delete his own account, so we need to deny him permission. This is done very similar, only instead of “grant”, it is “deny”.

$ cake acl deny BigMan1 BigMan1 delete
Permission granted.
X-Powered-By: PHP/5.2.6
Content-type: text/html

In the above example, we are doing an acl command, denying permissions for ARO BigMan1 on ACL BigMan1 for the delete action. In the previous example where we granted him permissions, we set the ACO on the parent, so that any child nodes would inherit the same permissions. But on this deny, we want to deny only for a child node.
Now, when we grant access to other users who are not admins, we would do this on the child nodes. So lets say that users can read any User account, only edit their own, and never delete their own account. So we would do that as:

$ cake acl grant Newbie Newbie update
Permission granted.
X-Powered-By: PHP/5.2.6
Content-type: text/html

$ cake acl deny Newbie Users delete
Permission denied.
X-Powered-By: PHP/5.2.6
Content-type: text/html

$ cake acl grant Newbie Users read
Permission granted.
X-Powered-By: PHP/5.2.6
Content-type: text/html

This will grant “Newbie” access to read any User account, update their own account, and denied being able to delete any account.
So that does it for the existing users. But now what about any new user that registers on the site? That will be covered in part 3, and will show some of the true power of the ACL when used in applications.