access_policy-1.0.x-dev/tests/src/Functional/AccessRulesEntityPermissionsTest.php

tests/src/Functional/AccessRulesEntityPermissionsTest.php
<?php

namespace Drupal\Tests\access_policy\Functional;

use Drupal\access_policy\Entity\AccessPolicy;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\taxonomy\Entity\Vocabulary;
use Drupal\Tests\taxonomy\Traits\TaxonomyTestTrait;

/**
 * Ensures that access rule validation works.
 *
 * @group access_policy
 */
class AccessRulesEntityPermissionsTest extends AccessPolicyTestBase {

  use TaxonomyTestTrait;

  /**
   * The tags vocabulary.
   *
   * @var \Drupal\Core\Entity\EntityInterface
   */
  protected $vocabulary;

  /**
   * Modules to enable.
   *
   * @var array
   */
  protected static $modules = [
    'access_policy',
    'access_policy_test',
    'filter',
    'node',
    'taxonomy',
    'field',
    'user',
    'datetime',
  ];

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

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

    // Create a tags vocabulary.
    $this->vocabulary = Vocabulary::create([
      'name' => 'tags',
      'vid' => 'tags',
    ]);
    $this->vocabulary->save();

    // @todo move this to config install.
    $field_storage = FieldStorageConfig::create([
      'field_name' => 'field_tags',
      'entity_type' => 'node',
      'type' => 'entity_reference',
      'cardinality' => -1,
      'settings' => [
        'target_type' => 'taxonomy_term',
      ],
    ]);
    $field_storage->save();

    $field = FieldConfig::create([
      'field_storage' => $field_storage,
      'field_name' => 'field_tags',
      'bundle' => 'page',
      'translatable' => FALSE,
      'settings' => [
        'handler_settings' => [
          'target_bundles' => ['tags' => 'tags'],
        ],
      ],
    ]);
    $field->save();

    $field_storage = FieldStorageConfig::create([
      'field_name' => 'field_tags',
      'entity_type' => 'user',
      'type' => 'entity_reference',
      'cardinality' => -1,
      'settings' => [
        'target_type' => 'taxonomy_term',
      ],
    ]);
    $field_storage->save();

    $field = FieldConfig::create([
      'field_storage' => $field_storage,
      'field_name' => 'field_tags',
      'bundle' => 'user',
      'translatable' => FALSE,
      'settings' => [
        'handler_settings' => [
          'target_bundles' => ['tags' => 'tags'],
        ],
      ],
    ]);
    $field->save();

    $policy = AccessPolicy::create([
      'id' => 'tags',
      'label' => 'Tags policy',
      'target_entity_type_id' => 'node',
    ]);
    $policy->save();

    \Drupal::service('router.builder')->rebuildIfNeeded();
  }

  /**
   * Tests view permissions restricted by access policy with access rules.
   */
  public function testViewEntityWithAccessRules() {
    $term_1 = $this->createTerm($this->vocabulary, [
      'title' => 'Term 1',
    ]);

    $access_policy = $this->entityTypeManager->getStorage('access_policy')->load('tags');
    $handler = $this->accessRuleManager->getHandler('node', 'match_field_tags');
    $handler->setSettings([
      'operator' => 'in',
      'value' => [
        'field' => 'field_tags',
      ],
    ]);
    $access_policy->addHandler('access_rule', $handler);
    $access_policy->save();

    // Create a node with a value for field_text. This will be validated by
    // the access rule plugin.
    $node = $this->drupalCreateNode([
      'type' => 'page',
      'status' => 1,
      'field_tags' => [
        $term_1,
      ],
      'access_policy' => ['tags'],
    ]);

    // Attempt to view the content that has matching text with the user. If the
    // text matches then they should be allowed.
    $web_user_valid = $this->drupalCreateUser([
      'access content',
      'access administration pages',
      'access content overview',
      'administer nodes',
      'view tags content',
    ]);
    $web_user_valid->set('field_tags', [$term_1]);
    $web_user_valid->save();
    $this->drupalLogin($web_user_valid);

    $this->drupalGet('node/' . $node->id());
    $this->assertSession()->statusCodeEquals(200);

    $this->drupalGet('admin/content');
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->pageTextContainsOnce($node->label());
    $this->drupalLogout();

    // Create a user without any value for field_text. They should not be able
    // to see the node.
    $web_user_invalid = $this->drupalCreateUser([
      'access content',
      'access administration pages',
      'access content overview',
      'administer nodes',
      'view tags content',
    ]);
    $this->drupalLogin($web_user_invalid);

    $this->entityTypeManager->getStorage('node')->resetCache();
    $this->drupalGet('node/' . $node->id());
    $this->assertSession()->statusCodeEquals(403);

    $this->drupalGet('admin/content');
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->pageTextNotContains($node->label());
  }

  /**
   * Tests view permissions with multiple access rules using AND operator.
   */
  public function testViewEntityWithMultipleAndAccessRules() {
    $policy = AccessPolicy::create([
      'id' => 'test_policy_with_and_rules',
      'label' => 'Test policy with multiple AND rules',
      'access_rule_operator' => 'AND',
      'target_entity_type_id' => 'node',
    ]);
    $policy->save();
    $handler = $this->accessRuleManager->getHandler('node', 'match_field_tags');
    $handler->setSettings([
      'operator' => 'in',
      'value' => [
        'field' => 'field_tags',
      ],
    ]);
    $policy->addHandler('access_rule', $handler);
    $policy->addHandler('access_rule', $this->accessRuleManager->getHandler('node', 'is_own'));
    $policy->save();

    $term_1 = $this->createTerm($this->vocabulary, [
      'title' => 'Term 1',
    ]);

    // Create a user with the right permissions and matching text.
    $web_user = $this->drupalCreateUser([
      'access content',
      'access administration pages',
      'access content overview',
      'view test_policy_with_and_rules content',
    ]);
    $web_user->set('field_tags', [
      $term_1,
    ]);
    $web_user->save();
    $this->drupalLogin($web_user);

    // Attempt to view the content that has matching text with the user. If the
    // text matches AND the content is published then they should be allowed.
    $node = $this->drupalCreateNode([
      'type' => 'page',
      'uid' => $web_user->id(),
      'status' => 1,
      'field_tags' => [
        $term_1,
      ],
      'access_policy' => ['test_policy_with_and_rules'],
    ]);

    $this->drupalGet('node/' . $node->id());
    $this->assertSession()->statusCodeEquals(200);

    // Create a node with a different uid and matching value for field_text.
    // this should fail validation.
    $diff_author = $this->createUser();
    $node_diff_owner = $this->drupalCreateNode([
      'type' => 'page',
      'status' => 1,
      'uid' => $diff_author->id(),
      'field_tags' => [
        $term_1,
      ],
      'access_policy' => ['test_policy_with_and_rules'],
    ]);

    $this->drupalGet('node/' . $node_diff_owner->id());
    $this->assertSession()->statusCodeEquals(403);

    $this->drupalGet('admin/content');
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->pageTextContainsOnce($node->label());
    $this->assertSession()->pageTextNotContains($node_diff_owner->label());
  }

  /**
   * Tests view permissions with multiple access rules using OR operator.
   */
  public function testViewEntityWithMultipleOrAccessRules() {

    $policy = AccessPolicy::create([
      'id' => 'test_policy_with_or_rules',
      'label' => 'Test policy with OR rules',
      'access_rule_operator' => 'OR',
      'target_entity_type_id' => 'node',
    ]);
    $policy->addHandler('access_rule', $this->accessRuleManager->getHandler('node', 'is_own'));
    $handler = $this->accessRuleManager->getHandler('node', 'match_field_tags');
    $handler->setSettings([
      'operator' => 'in',
      'value' => [
        'field' => 'field_tags',
      ],
    ]);
    $policy->addHandler('access_rule', $handler);
    $policy->addHandler('access_rule', $this->accessRuleManager->getHandler('node', 'is_own'));
    $policy->save();

    $term_1 = $this->createTerm($this->vocabulary, [
      'title' => 'Term 1',
    ]);

    $term_2 = $this->createTerm($this->vocabulary, [
      'title' => 'Term 1',
    ]);

    // Create a user with the right permissions and matching text.
    $web_user = $this->drupalCreateUser([
      'access content',
      'access administration pages',
      'access content overview',
      'administer nodes',
      'view test_policy_with_or_rules content',
    ]);

    $web_user->set('field_tags', [
      $term_1,
    ]);
    $web_user->save();
    $this->drupalLogin($web_user);

    // Attempt to view the content that has matching text with the user. If the
    // text matches OR the content is published then they should be allowed.
    $node = $this->drupalCreateNode([
      'type' => 'page',
      'uid' => $web_user->id(),
      'status' => 1,
      'field_tags' => [
        $term_1,
      ],
      'access_policy' => ['test_policy_with_or_rules'],
    ]);

    $this->drupalGet('node/' . $node->id());
    $this->assertSession()->statusCodeEquals(200);

    // Create a node with a different uid and matching value for field_text.
    // this should pass validation because one of them is true.
    $node_diff_owner = $this->drupalCreateNode([
      'type' => 'page',
      'status' => 1,
      'uid' => 100,
      'field_tags' => [
        $term_1,
      ],
      'access_policy' => ['test_policy_with_or_rules'],
    ]);

    $this->drupalGet('node/' . $node_diff_owner->id());
    $this->assertSession()->statusCodeEquals(200);

    // Create a node with a different uid and different value for field_tags.
    // This should not pass validation because none of them are true.
    $node_no_match = $this->drupalCreateNode([
      'type' => 'page',
      'status' => 1,
      'uid' => 100,
      'field_tags' => [
        $term_2,
      ],
      'access_policy' => ['test_policy_with_or_rules'],
    ]);
    $this->drupalGet('node/' . $node_no_match->id());
    $this->assertSession()->statusCodeEquals(403);

    $this->drupalGet('admin/content');
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->pageTextContainsOnce($node->label());
    $this->assertSession()->pageTextContainsOnce($node_diff_owner->label());
    $this->assertSession()->pageTextNotContains($node_no_match->label());

  }

  /**
   * Tests bypassed access rules.
   */
  public function testViewEntityWithBypassedAccessRules() {

    $policy = $this->entityTypeManager->getStorage('access_policy')->load('tags');
    $handler = $this->accessRuleManager->getHandler('node', 'match_field_tags');
    $handler->setSettings([
      'operator' => 'in',
      'value' => [
        'field' => 'field_tags',
      ],
    ]);
    $policy->addHandler('access_rule', $handler);

    $term_1 = $this->createTerm($this->vocabulary, [
      'title' => 'Term 1',
    ]);

    $term_2 = $this->createTerm($this->vocabulary, [
      'title' => 'Term 1',
    ]);

    // Create a node with a value for field_text. This will be validated by
    // the access rule plugin.
    $node = $this->drupalCreateNode([
      'type' => 'page',
      'status' => 1,
      'field_tags' => [
        $term_1,
      ],
      'access_policy' => ['tags'],
    ]);

    // Create a user without any value for field_text but they have the bypass
    // permission. They should be able to see the node.
    $web_user_invalid = $this->drupalCreateUser([
      'access content',
      'access administration pages',
      'access content overview',
      'administer nodes',
      'view tags content',
      'bypass tags access rules',
    ]);
    $web_user_invalid->set('field_tags', [
      $term_2,
    ]);
    $web_user_invalid->save();
    $this->drupalLogin($web_user_invalid);

    $this->drupalGet('node/' . $node->id());
    $this->assertSession()->statusCodeEquals(200);

    $this->drupalGet('admin/content');
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->pageTextContainsOnce($node->label());
  }

}

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

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