3. Defining Permissions: Cake's Database ACL

3.1. Getting Started

The default ACL permissions implementation is database stored. Database ACL, or dbACL consists of a set of core models, and a command-line script that comes with your Cake installation. The models are used by Cake to interact with your database in order to store and retrieve nodes the ACL trees. The command-line script is used to help you get started and be able to interact with your trees.

To get started, first you'll need to make sure your /app/config/database.php is present and correctly configured. For a new Cake installation, the easiest way to tell that this is so is to bring up the installation directory using a web browser. Near the top of the page, you should see the messages "Your database configuration file is present." and "Cake is able to connect to the database." if you've done it correctly. See section 4.1 for more information on database configuration.

Next, use the the ACL command-line script to initialize your database to store ACL information. The script found at /cake/scripts/acl.php will help you accomplish this. Initialize the your database for ACL by executing the following command (from your /cake/scripts/ directory):

Example 11.1. Initializing your database using acl.php

$ php acl.php initdb

Initializing Database...
Creating access control objects table (acos)...
Creating access request objects table (acos)...
Creating relationships table (aros_acos)...

Done.

At this point, you should be able to check your project's database to see the new tables. If you're curious about how Cake stores tree information in these tables, read up on modified database tree traversal. Basically, it stores nodes, and their place in the tree. The acos and aros tables store the nodes for their respective trees, and the aros_acos table is used to link your AROs to the ACOs they can access.

Now, you should be able to start creating your ARO and ACO trees.

3.2. Creating Access Request Objects (AROs) and Access Control Objects (ACOs)

There are two ways of referring to AROs/ACOs. One is by giving them an numeric id, which is usually just the primary key of the table they belong to. The other way is by giving them a string alias. The two are not mutually exclusive.

The way to create a new ARO is by using the methods defined the the Aro Cake model. The create() method of the Aro class takes three parameters: $link_id, $parent_id, and $alias. This method creates a new ACL object under the parent specified by a parent_id - or as a root object if the $parent_id passed is null. The $link_id allows you to link a current user object to Cake's ACL structures. The alias parameter allows you address your object using a non-integer ID.

Let's see what some examples might look like:

$aro = new Aro();

// First, set up a few AROs.
// These objects will have no parent initially.

$aro->create( 1, null, 'Bob Marley' );
$aro->create( 2, null, 'Jimi Hendrix');
$aro->create( 3, null, 'George Washington');
$aro->create( 4, null, 'Abraham Lincoln');

// Now, we can make groups to organize these users:
// Notice that the IDs for these objects are 0, because 
//     they will never tie to users in our system

$aro->create(0, null, 'Presidents');
$aro->create(0, null, 'Artists');

//Now, hook AROs to their respective groups:

$aro->setParent('Presidents', 'George Washington');
$aro->setParent('Presidents', 'Abraham Lincoln');
$aro->setParent('Artists', 'Jimi Hendrix');
$aro->setParent('Artists', 'Bob Marley');

//In short, here is how to create an ARO:
$aro = new Aro(); 
$aro->create($user_id, $parent_id, $alias);

You can also create AROs using the command line script using $acl.php create aro <link_id> <parent_id> <alias>.

Creating an ACO is done in a similar manner:

$aco = new Aco();

//Create some access control objects:
$aco->create(1, null, 'Electric Guitar');
$aco->create(2, null, 'United States Army');
$aco->create(3, null, 'Fans');

// I suppose we could create groups for these
// objects using setParent(), but we'll skip that
// for this particular example

//So, to create an ACO:
$aco = new Aco();
$aco->create($id, $parent, $alias);

The corresponding command line script command would be: $acl.php create aco <link_id> <parent_id> <alias>.

3.3. Assigning Permissions

After creating our ACOs and AROs, we can finally assign permission between the two groups. This is done using Cake's core Acl component. Let's continue on with our example:

// First, in a controller, we'll need access 
// to Cake's ACL component:

class SomethingsController extends AppController
{
    // You might want to place this in the AppController
    // instead, but here works great too.

    var $components = array('Acl');

    // Remember: ACL will always deny something
    // it doesn't have information on. If any 
    // checks were made on anything, it would
    // be denied. Let's allow an ARO access to an ACO.

    function someAction()
    {
        //ALLOW
    
        // Here is how you grant an ARO full access to an ACO
        $this->Acl->allow('Jimi Hendrix', 'Electric Guitar');
        $this->Acl->allow('Bob Marley',   'Electric Guitar');

        // We can also assign permissions to groups, remember?
        $this->Acl->Allow('Presidents', 'United States Army');
        
        // The allow() method has a third parameter, $action.
        // You can specify partial access using this parameter.
        // $action can be set to create, read, update or delete.
        // If no action is specified, full access is assumed.

        // Look, don't touch, gentlemen:
        $this->Acl->allow('George Washington', 'Electric Guitar', 'read');
        $this->Acl->allow('Abraham Lincoln',   'Electric Guitar', 'read');

        //DENY

        //Denies work in the same manner:

        //When his term is up...
        $this->Acl->deny('Abraham Lincoln', 'United States Army');


    }
}

This particular controller isn't especially useful, but it is mostly meant to show you how the process works. Using the Acl component in connection with your user management controller would be the best usage. Once a user has been created on the system, her ARO could be created and placed at the right point of the tree, and permissions could be assigned to specific ACO or ACO groups based on her identity.

Permissions can also be assigned using the command line script packaged with Cake. The syntax is similar to the model functions, and can be viewed by executing $php acl.php help.