Entity Access API

Component ID

1036738

Component name

Entity Access API

Component type

module

Maintenance status

Development status

Component security advisory coverage

not-covered

Downloads

1402

Component created

Component changed

Component body

This is a proof-of-concept module. Don't use it on a production site. This is an API module, and it does very little by itself. You probably shouldn't install it unless another module tells you to do so.

The original purpose of the module was to create a user-level access system for all entities. The high-level goal was to make it easy for a module to get an answer to the question "does User A have access to view the comment with ID 37?" The low-level goal was to create a system that allows simple granting/revoking of access to perform certain actions on entities, and this system should work with minimal changes across the rest of the Drupal site. For example, if User A does not have access to view node 42, then that node should not appear in Views listings for that user.

However, the reason this module was written was to make it easier to build a system for user-controlled privacy settings. That architecture has gone down a different route, and the code in this repository currently doesn't reflect that effort and won't be continued. I may still end up putting the user privacy effort at this namespace, but it will look very different than what is here now.

Current architecture

Let's take the action of viewing a node as an example.

If the function to view a node is node_view($node), then the node module would do something like this:

if (accessapi_access('node_view', $node, $account)) {
  return node_view($node);
}

The accessapi_access() function determines whether the user represented by $account is allowed to view the node $node. The answer to that question is determined as follows.

The node module implements hook_accessapi(), specifying each of the actions a user can take that might require user-level access control. For example:

function node_accessapi() {
  return array(
    'node_view' => array(
      'arguments' => array(
        'node' => NULL,
        'account' => NULL,
      ),
      'callback' => 'node_view_access', // default is user_access
    ),
  );
}

The specified callback, in this case node_view_access(), returns a default permission (either TRUE or FALSE) that will be applied if access records are unavailable or inconclusive. Other modules can also specify access records for the node_view action by implementing hook_accessapi_node_view() or change the array of access records by implementing hook_accessapi_node_view_alter(). For example, a node access control module called example might do something like this:

function example_accessapi_node_view($node, $account) {
  return array( // The return value is an array of access records.
    array( // This is an access record array.
      'value' => ACCESSAPI_ALLOW, // one of ACCESSAPI_ALLOW, ACCESSAPI_DISALLOW, ACCESSAPI_UNKNOWN
      'weight' => -30, // records will be re-ordered
      'id' => 'example special node view', // an identifier that will allow us to find and modify the record in an alter hook. Should be at least the module name
    );
  );
}

Access records are sorted by weight and the lightest one with a value of either ACCESSAPI_ALLOW or ACCESSAPI_DISALLOW will be applied. If there are no records or the records contain only values of ACCESSAPI_UNKNOWN, then the default value from the callback specified in hook_access will be used.

One possible extension would be to add a "settings" parameter to the arrays returned from hook_accessapi() (or add a new hook_accessapi_settings()). If an access setting was marked as user-controlled, a checkbox or select list would show up in the user's settings. These settings would be passed to access callbacks/hooks/alters in an additional $settings array. This would allow modules to easily let users say "I want only my friends to view my nodes."