Member-only story

The trinary states of Drupal access control: allowed, forbidden, neutral.

Matt Glaman
6 min readJan 31, 2023

One of my favorite features of Drupal is the user access control experience. Drupal has a robust permission and role (access control list) API that allows for fine-tuned control of what users can and cannot do. Drupal developers end up interacting with Drupal’s access system in one way or another. Every project has some request to enhance or alter how normal access works. When this happens, some modules (see Field Permissions) provide no-code solutions for the end user. Other times the developer taps into Drupal hooks and writes code to adjust the access result.

A common use case I have experienced is allowing content from a specific content type to be accessible to privileged users (like paywalled content.) Drupal core doesn’t provide granular permissions for viewing the content of specific content types. You need to extend Drupal and use the hook_node_access hook to alter the default user access.

function mymodule_node_access(
EntityInterface $entity,
string $operation,
AccountInterface $account
) {
// Only apply if viewing our content type.
if (
$operation === 'view'
&& $entity->bundle() === 'special_content'
) {
// Allow if the user has permission.
$has_permission = $account->hasPermission('custom special_content permission');
return AccessResult::forbiddenIf(
$has_permission === FALSE
)->cachePerPermissions();
}
// Otherwise, return neutral, so defaults apply.
return AccessResult::neutral();
}

--

--

Matt Glaman
Matt Glaman

Written by Matt Glaman

PHP software engineer, open source contributor, and speaker

No responses yet