Demonstrates node access.

This is an example demonstrating how to grant or deny access to nodes using the Backdrop 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:

Backdrop'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.
  • If no resolution has yet been reached, then the node_access table is used along with hook_node_grants(). (Backdrop 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.

See also

node_access()

hook_node_access()

hook_node_grants()

hook_node_access_records()

Parent topics

File

modules/examples/node_access_example/node_access_example.module, line 8
Module file illustrating API-based node access.

Functions

Namesort descending Location Description
node_access_example_form_alter modules/examples/node_access_example/node_access_example.module Implements hook_form_alter().
node_access_example_menu modules/examples/node_access_example/node_access_example.module Implements hook_menu().
node_access_example_node_access modules/examples/node_access_example/node_access_example.module Implements hook_node_access().
node_access_example_node_access_records modules/examples/node_access_example/node_access_example.module Implements hook_node_access_records().
node_access_example_node_delete modules/examples/node_access_example/node_access_example.module Implements hook_node_delete().
node_access_example_node_grants modules/examples/node_access_example/node_access_example.module Implements hook_node_grants().
node_access_example_node_insert modules/examples/node_access_example/node_access_example.module Implements hook_node_insert().
node_access_example_node_load modules/examples/node_access_example/node_access_example.module Implements hook_node_load().
node_access_example_node_update modules/examples/node_access_example/node_access_example.module Implements hook_node_update().
node_access_example_permission modules/examples/node_access_example/node_access_example.module Implements hook_permission().
node_access_example_private_node_listing modules/examples/node_access_example/node_access_example.module Our hook_menu() page callback function.

Constants

Namesort descending Location Description
NODE_ACCESS_EXAMPLE_GRANT_ALL modules/examples/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

Namesort descending Location Description
NodeAccessExampleTestCase modules/examples/node_access_example/node_access_example.test Functional tests for the Node Access Example module.