Example: Node Access

Same name in other branches
  1. 6.x-1.x node_access_example/node_access_example.module \node_access_example

Demonstrates node access.

This is an example demonstrating how to grant or deny access to nodes using the Drupal core API node access system.

This module will add a 'private' flag for each node, which the node's author can manage. Nodes marked private can only be viewed, edited, or deleted by the author. However, not everything is as private as it seems on the internet, and so we need to implement some ways to allow other users to manage this 'private' content.

We will use the node grant system to specify which users are allowed to view, edit, or delete 'private' content. We will also allow a user named 'foobar' to have edit privileges on private content as well.

In addition, we will provide a page which will show some minimal instructions, and statistics on private nodes on the site.

We use NodeAPI hooks to put a single marker on a node, called 'private'. The marker is implemented by a database table which has one row per node simply indicating that the node is private. If the "private" marker is set, users other than the owner and privileged users are denied access.

Standard permissions are defined which allow users with 'access any private content' or 'edit any private content' to override the 'private' node access restrictions.

A separate access realm grants privileges to each node's author, so that they can always view, edit, and delete their own private nodes.

The only page provided by this module gives a rundown of how many nodes are marked private, and how many of those are accessible to the current user. This demonstrates the use of the 'node_access' tag in node queries, preventing disclosure of information which should not be shown to users who don't have the proper permissions.

Most relevant functions:

Drupal's node access system has three layers.

  • Overall override permissions. User 1 and any user with 'bypass node access' permission are automatically granted access.
  • hook_node_access() gives each module the opportunity to approve or deny access. Any module that returns NODE_ACCESS_DENY from hook_node_access() will result in denial of access. If no module denies access and one or more modules allow access, then access is granted. hook_node_access() was introduced in Drupal 7.
  • If no resolution has yet been reached, then the node_access table is used along with hook_node_grants(). (Drupal updates the node_access table when nodes are saved, by calling hook_node_access_records().)

Note that the hook_node_grants()/hook_node_access_records() layer is a first-grant-wins system, which means a module using it can't deny access to a node. Contributed modules have been developed to overcome this shortcoming, with their own APIs, such as ACL. ACL, in fact, has emerged as the more-or-less standard solution for fine-grained access control, and you really should be reading up on it. Many modules use it, and if your module implements another node access system, there could be chaos.

A list of the many node access modules (and differing APIs) is here: Overview of Node Access Modules. Note that this is Drupal 6 documentation, linked here so the reader can understand the historical reasons for using contributed node access modules such as ACL.

See also

node_access()

hook_node_access()

hook_node_grants()

hook_node_access_records()

Parent topics

File

node_access_example/node_access_example.module, line 8

Functions

Title Sort descending File name Summary
node_access_example_form_alter node_access_example/node_access_example.module Implements hook_form_alter().
node_access_example_menu node_access_example/node_access_example.module Implements hook_menu().
node_access_example_node_access node_access_example/node_access_example.module Implements hook_node_access().
node_access_example_node_access_records node_access_example/node_access_example.module Implements hook_node_access_records().
node_access_example_node_delete node_access_example/node_access_example.module Implements hook_node_delete().
node_access_example_node_grants node_access_example/node_access_example.module Implements hook_node_grants().
node_access_example_node_insert node_access_example/node_access_example.module Implements hook_node_insert().
node_access_example_node_load node_access_example/node_access_example.module Implements hook_node_load().
node_access_example_node_update node_access_example/node_access_example.module Implements hook_node_update().
node_access_example_permission node_access_example/node_access_example.module Implements hook_permission().
node_access_example_private_node_listing node_access_example/node_access_example.module Our hook_menu() page callback function.

Constants

Title Sort descending File name Summary
NODE_ACCESS_EXAMPLE_GRANT_ALL node_access_example/node_access_example.module Here we define a constant for our node access grant ID, for the
node_access_example_view and node_access_example_edit realms. This ID could
be any integer, but here we choose 23, because it is this author's favorite
number.

Classes

Title Sort descending File name Summary
NodeAccessExampleTestCase node_access_example/node_access_example.test Functional tests for the Node Access Example module.