Drupal Access Control Part 2: The ACL module explained

This is a collaborative document. It's by definition always a work in progress.
Want to participate? Drop me a line
published: March 22nd, 2008
modified: March 22nd, 2008

An in-depth review of the ACL module and the core components it ties into

Drupal’s ACL (Access Control List) module is an API-only module It does not provide a user interface, but a small framework that allows you to easily implement your own access control rules for any node you want.

The ACL ties in with Drupal’s core node module. The permissions you define in your ACL will automagically be in effect when a user views/updates or deletes a node.

The way ACL works is easily deducted from the data structure and the API itself.

ACL creates 3 tables:

  • acl
    • acl_id
    • module (‘content_access’)
    • name (‘view_{nid}’, ‘update{nid}’

  • acl_node
    • acl_id
    • nid
    • grant_view (1 or 0)
    • grant_update (1 or 0)
    • grant_delete (1 or 0)
  • acl_user
    • acl_id
    • uid

How to use it:

  • you define a new ACL (Access Control List)
  • you indicate which node(s) this ACL should control, and what actions it controls (view, update, delete)
  • you indicate which users are part of the ACL

First step: create the ACL
We’re going to assume you’re writing your own module named ‘foo’.

You start by creating a new entry in {acl} and give it a name that indicates your module name and the permission: (create, update, delete) + underscore + nid.


  $acl_id = acl_create_new_acl('foo', 'view_' . $node->nid);

This snippet creates a new ‘foo_view’ entry in the {acl} table.

Second step: indicate the content access rules for the new ACL

For each node over which wish to exercise access control, insert an entry in the table {acl_node} indicating the appropriate grant_view/grant_update/grant_delete permissions. It would make sense that you only assign grant_view permissions to an ACL that you name foo_view_x.


  acl_node_add_acl($node->nid, $acl_id, 1, 0, 0);

This snippet makes sure that a $node is tied to the ACL (with id = $acl_id) you just created. In addition, ‘grant_view’ permissions are given (3rd parameter), while ‘grant_update’ and ‘grant_delete’ (4th and 5th parameter) are not.

Note: obviously you can add multiple records with the same acl_id and different nids to link more than one node to this ACL. Think of the ACL as a placeholder for a set of permissions for one or more nodes.

Third step: indicate which users are tied to the set of node permissions you just created


  acl_add_user($acl_id, $uid);

This snippet adds a record to {acl_user}, indicating that ACL with id = $acl_id now applies to the user with uid = $uid.

That’s it. These are the basics of setting up ACL. What else can you do?

Remove a user from an ACL so the defined permissions no longer apply to that user


  acl_remove_user($acl_id, $uid);

Remove a node from an ACL so the defined permissions no longer apply to that node


  acl_remove_acl($nid, $acl_id);

Remove all the ACL’s your module applied to a node


  acl_node_clear_acls($nid, $module_name)

Retrieve the id of a certain ACL you defined for a certain node


  $acl_id = acl_get_id_by_name('foo', 'view_' . $node->nid);


And much more. Take a look at acl.module to see wha’ts available.

Important note for using ACL with your own module
If you want to use the ACL API, your module needs to implement some hooks and some functions:

  • hook_enable
  • hook_disable
  • _disabling()
  • _disabled()

These are necessary to make sure your module’s code is actually taken into account by Drupal’s node access system



/* Implementation of hook_enable() */
function foo_enable() { node_access_rebuild();
}

/* Used by the ACL module */
function foo_enabled() { return !foo_disabling();
}

/* Implementation of hook_disable() */
function foo_disable() { foo_disabling(TRUE); node_access_rebuild();
}

/* Remembers if we have disabled access */
function foo_disabling($set = NULL) { static $disabling = FALSE;

if (isset($set)) { $disabling = $set; } return $disabling; }

For implementation details, see also: http://api.drupal.org/api/file/developer/examples/node_access_example.module/5

To see ACL in action, tak a look at these modules that use it:

auhtors:

  • jpoesen

(note: this document will be published as a Drupal handbook page once it’s ready for a bigger audience)