SuperAPI AI Directory

drupal-access

General & other

View repository

Updated 10-16 05:07

About this skill

Drupal Access Control

Defining Permissions (permissions.yml)

administer my module:
  title: 'Administer My Module'
  restrict access: true

view my content:
  title: 'View My Content'

Route Requirements

requirements:
  _permission: 'administer my module'   # Permission check
  _role: 'administrator'                # Role check
  _custom_access: '\Drupal\my_module\Access\MyAccessCheck::access'
  _entity_access: 'node.update'
  _access: 'TRUE'

Custom Access Checker

namespace Drupal\my_module\Access;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Access\AccessResultInterface;
use Drupal\Core\Routing\Access\AccessInterface;
use Drupal\Core\Session\AccountInterface;

final class MyAccessCheck implements AccessInterface {

  public function access(AccountInterface $account): AccessResultInterface {
    if ($account->hasPermission('administer site configuration')) {
      return AccessResult::allowed()->cachePerPermissions();
    }
    if ($account->hasPermission('view my content')) {
      return AccessResult::allowed()->cachePerPermissions();
    }
    return AccessResult::forbidden()->cachePerPermissions();
  }

}

AccessResult Patterns

AccessResult::allowed();
AccessResult::forbidden();
AccessResult::neutral();
AccessResult::allowedIf($condition);
AccessResult::forbiddenIf($condition);
AccessResult::allowedIfHasPermission($account, 'my permission');

// Cache correctly
$result->cachePerPermissions();         // Varies by user permissions
$result->cachePerUser();                // Varies by user identity
$result->addCacheableDependency($node); // Varies by entity
$result->setCacheMaxAge(0);             // Not cacheable

Checking Access in Code

$node->access('view', $account);
$node->access('update', $account);
$account->hasPermission('administer content');
$account->hasRole('editor');

Entity Access Hook

#[Hook('node_access')]
public function nodeAccess(NodeInterface $node, string $op, AccountInterface $account): AccessResultInterface {
  if ($op === 'view' && $node->bundle() === 'private') {
    return AccessResult::forbiddenIf(
      !$account->hasPermission('view private content')
    )->cachePerPermissions()->addCacheableDependency($node);
  }
  return AccessResult::neutral();
}