access_policy-1.0.x-dev/tests/src/Kernel/AccessPolicyOperationsAccessTest.php

tests/src/Kernel/AccessPolicyOperationsAccessTest.php
<?php

namespace Drupal\Tests\access_policy\Kernel;

use Drupal\access_policy\Entity\AccessPolicy;
use Drupal\Core\Session\UserSession;
use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\Entity\Vocabulary;

/**
 * Tests Access Policy permissions.
 *
 * @group access_policy
 */
class AccessPolicyOperationsAccessTest extends AccessPolicyKernelTestBase {

  /**
   * The entity storage.
   *
   * @var \Drupal\Core\Entity\RevisionableStorageInterface
   */
  protected $storage;

  /**
   * The modules required for this test.
   *
   * @var string[]
   */
  protected static $modules = [
    'field',
    'filter',
    'node',
    'taxonomy',
    'options',
    'access_policy',
    'access_policy_test',
    'system',
    'text',
    'user',
  ];

  /**
   * The default permissions of each user.
   *
   * @var array
   */
  protected $defaultPermissions = [
    'access content',
    'edit any page content',
    'delete any page content',
    'view all revisions',
    'revert page revisions',
    'delete page revisions',
  ];

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

    $this->installConfig(['access_policy']);
    $this->installConfig(['access_policy_test']);
    $this->installEntitySchema('taxonomy_term');

    $vocabulary = Vocabulary::create([
      'name' => 'tags',
      'vid' => 'tags',
    ]);
    $vocabulary->save();

    // First user is always admin.
    $this->createUser();

    $this->createAccessPolicyFixtures();

    $this->contentAccessPolicyManager = $this->container->get('access_policy.content_policy_manager');
    $this->storage = $this->container->get('entity_type.manager')->getStorage('node');
  }

  /**
   * Create access policy fixtures.
   *
   * These different access policies will be test against as part of each
   * test defined in the data providers.
   */
  public function createAccessPolicyFixtures() {
    AccessPolicy::create([
      'id' => 'public',
      'label' => 'Public test policy',
      'access_rules' => [],
      'target_entity_type_id' => 'node',
      'operations' => [
        'view' => [],
        'view_all_revisions' => [
          'permission' => TRUE,
        ],
        'edit' => [
          'permission' => TRUE,
        ],
        'delete' => [
          'permission' => TRUE,
        ],
        'view_unpublished' => [
          'permission' => TRUE,
        ],
        'manage_access' => [],
      ],
    ])->save();

    $public_with_rules = AccessPolicy::create([
      'id' => 'public_with_rules',
      'label' => 'Public test policy with access rules',
      'access_rules' => [],
      'target_entity_type_id' => 'node',
      'operations' => [
        'view' => [],
        'view_all_revisions' => [
          'access_rules' => TRUE,
        ],
        'edit' => [
          'access_rules' => TRUE,
        ],
        'delete' => [
          'access_rules' => TRUE,
        ],
        'view_unpublished' => [
          'access_rules' => TRUE,
        ],
        'manage_access' => [
          'access_rules' => TRUE,
        ],
      ],
    ]);
    $access_rule = $this->accessRuleManager->getHandler('node', 'is_own');
    $public_with_rules->addHandler('access_rule', $access_rule);
    $selection_rule = $this->selectionRuleManager->getHandler('node', 'is_own');
    $public_with_rules->addHandler('selection_rule', $selection_rule);
    $public_with_rules->save();

    AccessPolicy::create([
      'id' => 'group',
      'label' => 'Group test policy without rules',
      'target_entity_type_id' => 'node',
    ])->save();

    $group_with_rules = AccessPolicy::create([
      'id' => 'group_with_rules',
      'label' => 'Group test policy without rules',
      'target_entity_type_id' => 'node',
    ]);

    $access_rule = $this->accessRuleManager->getHandler('user', 'field_text');
    $access_rule->setSettings([
      'operator' => '=',
      'value' => 'Foo',
    ]);
    $group_with_rules->addHandler('access_rule', $access_rule);
    $group_with_rules->save();

    $private_policy = AccessPolicy::create([
      'id' => 'private',
      'label' => 'Private policy',
      'target_entity_type_id' => 'node',
      'operations' => [
        'view' => [
          'access_rules' => TRUE,
        ],
        'view_all_revisions' => [
          'access_rules' => TRUE,
        ],
        'edit' => [
          'access_rules' => TRUE,
        ],
        'delete' => [
          'access_rules' => TRUE,
        ],
        'view_unpublished' => [
          'access_rules' => TRUE,
        ],
        'manage_access' => [],
      ],
    ]);

    $access_rule = $this->accessRuleManager->getHandler('node', 'is_own');
    $private_policy->addHandler('access_rule', $access_rule);
    $selection_rule = $this->selectionRuleManager->getHandler('node', 'is_own');
    $private_policy->addHandler('selection_rule', $selection_rule);
    $private_policy->save();

  }

  /**
   * Tests the access policy operations for various policy types.
   *
   * @dataProvider providerAccessPolicyOperations
   */
  public function testAccessPolicyOperations($policy, $user, $expected_operations, $expected_contexts) {
    $perms = array_merge($this->defaultPermissions, $user['permissions']);
    $user_fields = $user['fields'] ?? [];
    $account = $this->createUser($perms, 'user', FALSE, $user_fields);
    $this->setCurrentUser($account);

    $policy = $this->entityTypeManager->getStorage('access_policy')->load($policy);
    $node = $this->createNode(['type' => 'page', 'uid' => 2]);
    $this->contentAccessPolicyManager->assign($node, $policy);

    // Create a new revision, this is necessary for revert/delete revisions.
    $node->setNewRevision();
    $node->set('title', 'New revision');
    $node->save();

    foreach ($expected_operations as $op => $expected_access) {
      $revision_ops = [
        'view all revisions',
        'view revision',
        'delete revision',
        'revert revision',
      ];
      if (in_array($op, $revision_ops)) {
        $entity = $this->storage->loadRevision(1);
      }
      else {
        $entity = $node;
      }

      $result = $entity->access($op, $account, TRUE);

      if ($expected_operations[$op]) {
        $this->assertTrue($result->isAllowed(), 'Operation "' . $op . '" should be allowed for node ' . $entity->id());
      }
      else {
        $this->assertTrue($result->isForbidden(), 'Operation "' . $op . '" should be forbidden for node ' . $entity->id());
      }

      // It's only necessary to check this for the view operation.
      if ($op == 'view') {
        // Verify the cache contexts. Public content does not have access rules
        // so it will always be user.permissions.
        $result = $node->access($op, $account, TRUE);
        $contexts = $result->getCacheContexts();
        $this->assertEquals($expected_contexts, $contexts, 'The cache contexts is incorrect.');

        $tags = $result->getCacheTags();
        $expected = [
          'node:1',
          'config:access_policy.access_policy.' . $policy->id(),
        ];
        $this->assertEquals($expected, $tags, 'The cache tags are incorrect for operation: ' . $op);

        $this->setCurrentUser($account);

        $expected_query = ($expected_operations['view']) ? [$node->id()] : [];
        $this->assertQueryResults('node', $expected_query);
      }
    }
  }

  /**
   * Data provider for access policy operations test.
   */
  public function providerAccessPolicyOperations() {
    return [
      'user has access to public content' => [
        'policy' => 'public',
        'user' => [
          'permissions' => [
            'edit public content',
            'delete public content',
            'view all public content revisions',
            'set entity access policy',
            'assign public access policy',
          ],
        ],
        'expected operations' => [
          'view' => TRUE,
          'update' => TRUE,
          'delete' => TRUE,
          'manage access' => TRUE,
          'view all revisions' => TRUE,
          'view revision' => TRUE,
          'delete revision' => TRUE,
          'revert revision' => TRUE,
        ],
        'expected contexts' => ['user.permissions'],
      ],
      'user only has view access to public content' => [
        'policy' => 'public',
        'user' => [
          'permissions' => [],
        ],
        'expected operations' => [
          'view' => TRUE,
          'update' => FALSE,
          'delete' => FALSE,
          'manage access' => FALSE,
          'view all revisions' => FALSE,
          'view revision' => FALSE,
          'delete revision' => FALSE,
          'revert revision' => FALSE,
        ],
        'expected contexts' => ['user.permissions'],
      ],
      'user has access to public content (with access rules)' => [
        'policy' => 'public_with_rules',
        'user' => [
          'permissions' => [],
          // This is not the original author.
          'fields' => ['uid' => 3],
        ],
        'expected operations' => [
          'view' => TRUE,
          'update' => FALSE,
          'delete' => FALSE,
          'manage access' => FALSE,
          'view all revisions' => FALSE,
          'view revision' => FALSE,
          'delete revision' => FALSE,
          'revert revision' => FALSE,
        ],
        'expected contexts' => ['user', 'user.permissions'],
      ],
      'user has access to group content (without access rules)' => [
        'policy' => 'group',
        'user' => [
          'permissions' => [
            'view group content',
            'edit group content',
            'delete group content',
            'view all group content revisions',
            'set entity access policy',
            'assign group access policy',
          ],
        ],
        'expected operations' => [
          'view' => TRUE,
          'update' => TRUE,
          'delete' => TRUE,
          'manage access' => TRUE,
          'view all revisions' => TRUE,
          'view revision' => TRUE,
          'delete revision' => TRUE,
          'revert revision' => TRUE,
        ],
        'expected contexts' => ['user.permissions'],
      ],
      'user does not have access to group content (without access rules)' => [
        'policy' => 'group',
        'user' => [
          'permissions' => [],
        ],
        'expected operations' => [
          'view' => FALSE,
          'update' => FALSE,
          'delete' => FALSE,
          'manage access' => FALSE,
          'view all revisions' => FALSE,
          'view revision' => FALSE,
          'delete revision' => FALSE,
          'revert revision' => FALSE,
        ],
        'expected contexts' => ['user.permissions'],
      ],
      'user has access to group content (with access rules)' => [
        'policy' => 'group_with_rules',
        'user' => [
          'permissions' => [
            'view group_with_rules content',
            'edit group_with_rules content',
            'delete group_with_rules content',
            'view all group_with_rules content revisions',
            'set entity access policy',
            'assign group_with_rules access policy',
          ],
          'fields' => [
            'field_text' => 'Foo',
          ],
        ],
        'expected operations' => [
          'view' => TRUE,
          'update' => TRUE,
          'delete' => TRUE,
          'manage access' => TRUE,
          'view all revisions' => TRUE,
          'view revision' => TRUE,
          'delete revision' => TRUE,
          'revert revision' => TRUE,
        ],
        'expected contexts' => [
          'user.field_values', 'user.permissions',
        ],
      ],
      'user does not have access to group content (with access rules)' => [
        'policy' => 'group_with_rules',
        'user' => [
          'permissions' => [
            'view group_with_rules content',
            'edit group_with_rules content',
            'delete group_with_rules content',
            'view all group_with_rules content revisions',
            'set entity access policy',
            'assign group_with_rules access policy',
          ],
          'fields' => [
            'field_text' => 'Bar',
          ],
        ],
        'expected operations' => [
          'view' => FALSE,
          'update' => FALSE,
          'delete' => FALSE,
          'manage access' => FALSE,
          'view all revisions' => FALSE,
          'view revision' => FALSE,
          'delete revision' => FALSE,
          'revert revision' => FALSE,
        ],
        'expected contexts' => [
          'user.field_values', 'user.permissions',
        ],
      ],
      'user has access to private content' => [
        'policy' => 'private',
        'user' => [
          'permissions' => [
            'set entity access policy',
            'assign private access policy',
          ],
          'fields' => ['uid' => 2],
        ],
        'expected operations' => [
          'view' => TRUE,
          'update' => TRUE,
          'delete' => TRUE,
          'manage access' => TRUE,
          'view all revisions' => TRUE,
          'view revision' => TRUE,
          'delete revision' => TRUE,
          'revert revision' => TRUE,
        ],
        'expected contexts' => ['user', 'user.permissions'],
      ],
      'user does not have access to private content' => [
        'policy' => 'private',
        'user' => [
          'permissions' => [
            'set entity access policy',
            'assign private access policy',
          ],
          'fields' => ['uid' => 3],
        ],
        'expected operations' => [
          'view' => FALSE,
          'update' => FALSE,
          'delete' => FALSE,
          'manage access' => FALSE,
          'view all revisions' => FALSE,
          'view revision' => FALSE,
          'delete revision' => FALSE,
          'revert revision' => FALSE,
        ],
        'expected contexts' => ['user', 'user.permissions'],
      ],
    ];
  }

  /**
   * Testing Drupal default Access Policy operation access.
   *
   * This is mostly just testing drupal core access except for the assign
   * operation. This has slightly different behavior than the other operations
   * therefore it's not included in the data provider.
   */
  public function testDefaultAccessPolicyOperations() {
    $policy = AccessPolicy::create([
      'id' => 'default_policy',
      'label' => 'Default test policy.',
      'target_entity_type_id' => 'node',
      'operations' => [
        'view' => [],
        'view_all_revisions' => [],
        'update' => [],
        'delete' => [],
        'view_unpublished' => [],
        'manage_access' => [],
      ],
    ]);
    $policy->save();

    $this->createRole([
      'access content',
      'edit any page content',
      'delete any page content',
      'view all revisions',
      'set entity access policy',
      'assign default_policy access policy',
    ], 'test_role');

    $account = $this->createUser([], 'user1', FALSE, ['uid' => 2]);
    $account->addRole('test_role');
    $account->save();

    $node = $this->createNode(['type' => 'page', 'uid' => $account->id()]);
    $this->contentAccessPolicyManager->assign($node, $policy);

    // Create a new revision, this is necessary for revert/delete revisions.
    $node->setNewRevision();
    $node->set('title', 'New revision');
    $node->save();

    $result = $node->access('view', $account, TRUE);
    $this->assertTrue($result->isAllowed(), 'The user should be able to view the content.');

    $contexts = $result->getCacheContexts();
    $this->assertEquals(['user.permissions'], $contexts, 'The cache contexts is incorrect.');

    $result = $node->access('update', $account, TRUE);
    $this->assertTrue($result->isAllowed(), 'The user should be able to edit the content.');

    $result = $node->access('delete', $account, TRUE);
    $this->assertTrue($result->isAllowed(), 'The user should be able to delete the content.');

    $result = $node->access('manage access', $account, TRUE);
    $this->assertTrue($result->isAllowed(), 'The user should be able to view the content Access page.');

    $result = $node->access('view all revisions', $account, TRUE);
    $this->assertTrue($result->isAllowed(), 'The user should be be able to view all revisions.');

    $node_revision = $this->storage->loadRevision(1);
    $result = $node_revision->access('view revision', $account, TRUE);
    $this->assertTrue($result->isAllowed(), 'The user should be be able to view the revision.');

    $account = $this->createUser([
      'access content',
    ]);

    $result = $node->access('view', $account, TRUE);
    $this->assertTrue($result->isAllowed(), 'The user should be able to view the content.');

    $result = $node->access('update', $account, TRUE);
    $this->assertTrue($result->isNeutral(), 'The user should not able to edit the content.');

    $result = $node->access('delete', $account, TRUE);
    $this->assertTrue($result->isNeutral(), 'The user should not be able to delete the content.');

    $result = $node->access('manage access', $account, TRUE);
    $this->assertTrue($result->isForbidden(), 'The user should not be able to assign the policy.');

    $result = $node->access('view all revisions', $account, TRUE);
    $this->assertTrue($result->isNeutral(), 'The user should not be able to see all revisions.');

    $node_revision = $this->storage->loadRevision(1);
    $result = $node_revision->access('view revision', $account, TRUE);
    $this->assertTrue($result->isNeutral(), 'The user should not be able to see the revision.');
  }

  /**
   * Test access policy group permissions with taxonomy terms.
   */
  public function testTaxonomyTermGroupAccessPolicyOperations() {
    $policy = AccessPolicy::create([
      'id' => 'group_policy_with_terms',
      'label' => 'Group test policy taxonomy terms',
      'target_entity_type_id' => 'taxonomy_term',
    ]);
    $policy->save();
    // Add a term to the vocabulary.
    $term = Term::create([
      'name' => 'Sometimes people are just jerks',
      'vid' => 'tags',
    ]);
    $term->save();

    $this->contentAccessPolicyManager->assign($term, $policy);

    $this->createRole([
      'access content',
      'create terms in tags',
      'delete terms in tags',
      'edit terms in tags',
      'view group_policy_with_terms taxonomy term',
      'edit group_policy_with_terms taxonomy term',
      'delete group_policy_with_terms taxonomy term',
      'set entity access policy',
      'assign group_policy_with_terms access policy',
    ], 'group_policy');

    $account = new UserSession([
      'uid' => 2,
      'roles' => ['group_policy'],
    ]);

    $result = $term->access('view', $account, TRUE);
    $this->assertTrue($result->isAllowed(), 'The user should be able to view the term.');

    $result = $term->access('update', $account, TRUE);
    $this->assertTrue($result->isAllowed(), 'The user should be able to edit the term.');

    $result = $term->access('delete', $account, TRUE);
    $this->assertTrue($result->isAllowed(), 'The user should be able to delete the term.');

    $result = $term->access('manage access', $account, TRUE);
    $this->assertTrue($result->isAllowed(), 'The user should be able to view the term Access page.');

    $this->createRole([
      'access content',
      'create terms in tags',
      'delete terms in tags',
      'edit terms in tags',
      'set entity access policy',
    ], 'authenticated');

    $account = new UserSession([
      'roles' => ['authenticated'],
    ]);

    $result = $term->access('view', $account, TRUE);
    $this->assertTrue($result->isForbidden(), 'The user should not be able to view the term.');

    $result = $term->access('update', $account, TRUE);
    $this->assertTrue($result->isForbidden(), 'The user should not able to edit the term.');

    $result = $term->access('delete', $account, TRUE);
    $this->assertTrue($result->isForbidden(), 'The user should not be able to delete the term.');

    $result = $term->access('manage access', $account, TRUE);
    $this->assertTrue($result->isForbidden(), 'The user should not be able to assign the policy.');

  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc