You are here

node_access_test.module in Drupal 9

Test module for testing the node access system.

This module's functionality depends on the following state variables:

  • node_access_test.no_access_uid: Used in NodeQueryAlterTest to enable the node_access_all grant realm.
  • node_access_test.private: When TRUE, the module controls access for nodes with a 'private' property set, and inherits the default core access for nodes without this flag. When FALSE, the module controls access for all nodes.
  • node_access_test_secret_catalan: When set to TRUE and using the Catalan 'ca' language code, makes all Catalan content secret.

See also

node_access_test_node_grants()

\Drupal\node\Tests\NodeQueryAlterTest

\Drupal\node\Tests\NodeAccessBaseTableTest

File

core/modules/node/tests/modules/node_access_test/node_access_test.module
View source
<?php

/**
 * @file
 * Test module for testing the node access system.
 *
 * This module's functionality depends on the following state variables:
 * - node_access_test.no_access_uid: Used in NodeQueryAlterTest to enable the
 *   node_access_all grant realm.
 * - node_access_test.private: When TRUE, the module controls access for nodes
 *   with a 'private' property set, and inherits the default core access for
 *   nodes without this flag. When FALSE, the module controls access for all
 *   nodes.
 * - node_access_test_secret_catalan: When set to TRUE and using the Catalan
 *   'ca' language code, makes all Catalan content secret.
 *
 * @see node_access_test_node_grants()
 * @see \Drupal\node\Tests\NodeQueryAlterTest
 * @see \Drupal\node\Tests\NodeAccessBaseTableTest
 */
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\field\Entity\FieldConfig;
use Drupal\node\NodeTypeInterface;
use Drupal\node\NodeInterface;

/**
 * Implements hook_node_grants().
 *
 * Provides three grant realms:
 * - node_access_test_author: Grants users view, update, and delete privileges
 *   on nodes they have authored. Users receive a group ID matching their user
 *   ID on this realm.
 * - node_access_test: Grants users view privileges when they have the
 *   'node test view' permission. Users with this permission receive two group
 *   IDs for the realm, 8888 and 8889. Access for both realms is identical;
 *   the second group is added so that the interaction of multiple groups on
 *   a given grant realm can be tested in NodeAccessPagerTest.
 * - node_access_all: Provides grants for the user whose user ID matches the
 *   'node_access_test.no_access_uid' state variable. Access control on this
 *   realm is not provided in this module; instead,
 *   NodeQueryAlterTest::testNodeQueryAlterOverride() manually writes a node
 *   access record defining the access control for this realm.
 *
 * @see \Drupal\node\Tests\NodeQueryAlterTest::testNodeQueryAlterOverride()
 * @see \Drupal\node\Tests\NodeAccessPagerTest
 * @see node_access_test.permissions.yml
 * @see node_access_test_node_access_records()
 */
function node_access_test_node_grants($account, $op) {
  $grants = [];
  $grants['node_access_test_author'] = [
    $account
      ->id(),
  ];
  if ($op == 'view' && $account
    ->hasPermission('node test view')) {
    $grants['node_access_test'] = [
      8888,
      8889,
    ];
  }
  $no_access_uid = \Drupal::state()
    ->get('node_access_test.no_access_uid', 0);
  if ($op == 'view' && $account
    ->id() == $no_access_uid) {
    $grants['node_access_all'] = [
      0,
    ];
  }
  return $grants;
}

/**
 * Implements hook_node_access_records().
 *
 * By default, records are written for all nodes. When the
 * 'node_access_test.private' state variable is set to TRUE, records
 * are only written for nodes with a "private" property set, which causes the
 * Node module to write the default global view grant for nodes that are not
 * marked private.
 *
 * @see \Drupal\node\Tests\NodeAccessBaseTableTest::setUp()
 * @see node_access_test_node_grants()
 * @see node_access_test.permissions.yml
 */
function node_access_test_node_access_records(NodeInterface $node) {
  $grants = [];

  // For NodeAccessBaseTableTestCase, only set records for private nodes.
  if (!\Drupal::state()
    ->get('node_access_test.private') || isset($node->private) && $node->private->value) {

    // Groups 8888 and 8889 for the node_access_test realm both receive a view
    // grant for all controlled nodes. See node_access_test_node_grants().
    $grants[] = [
      'realm' => 'node_access_test',
      'gid' => 8888,
      'grant_view' => 1,
      'grant_update' => 0,
      'grant_delete' => 0,
      'priority' => 0,
    ];
    $grants[] = [
      'realm' => 'node_access_test',
      'gid' => 8889,
      'grant_view' => 1,
      'grant_update' => 0,
      'grant_delete' => 0,
      'priority' => 0,
    ];

    // For the author realm, the group ID is equivalent to a user ID, which
    // means there are many many groups of just 1 user.
    $grants[] = [
      'realm' => 'node_access_test_author',
      'gid' => $node
        ->getOwnerId(),
      'grant_view' => 1,
      'grant_update' => 1,
      'grant_delete' => 1,
      'priority' => 0,
    ];
  }
  return $grants;
}

/**
 * Adds the private field to a node type.
 *
 * @param \Drupal\node\NodeTypeInterface $type
 *   A node type entity.
 */
function node_access_test_add_field(NodeTypeInterface $type) {
  $field_storage = FieldStorageConfig::create([
    'field_name' => 'private',
    'entity_type' => 'node',
    'type' => 'integer',
  ]);
  $field_storage
    ->save();
  $field = FieldConfig::create([
    'field_name' => 'private',
    'entity_type' => 'node',
    'bundle' => $type
      ->id(),
    'label' => 'Private',
  ]);
  $field
    ->save();

  // Assign widget settings for the 'default' form mode.
  \Drupal::service('entity_display.repository')
    ->getFormDisplay('node', $type
    ->id())
    ->setComponent('private', [
    'type' => 'number',
  ])
    ->save();
}

/**
 * Implements hook_node_access().
 */
function node_access_test_node_access(NodeInterface $node, $op, AccountInterface $account) {
  $secret_catalan = \Drupal::state()
    ->get('node_access_test_secret_catalan') ?: 0;
  if ($secret_catalan && $node
    ->language()
    ->getId() == 'ca') {

    // Make all Catalan content secret.
    return AccessResult::forbidden()
      ->setCacheMaxAge(0);
  }

  // Grant access if a specific user is specified.
  if (\Drupal::state()
    ->get('node_access_test.allow_uid') === $account
    ->id()) {
    return AccessResult::allowed();
  }

  // No opinion.
  return AccessResult::neutral()
    ->setCacheMaxAge(0);
}

Functions

Namesort descending Description
node_access_test_add_field Adds the private field to a node type.
node_access_test_node_access Implements hook_node_access().
node_access_test_node_access_records Implements hook_node_access_records().
node_access_test_node_grants Implements hook_node_grants().