access_policy-1.0.x-dev/tests/src/Functional/AccessPolicyEntityAssignTest.php
tests/src/Functional/AccessPolicyEntityAssignTest.php
<?php namespace Drupal\Tests\access_policy\Functional; use Drupal\access_policy\Entity\AccessPolicy; use Drupal\Core\Entity\Entity\EntityFormDisplay; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; use Drupal\node\Entity\NodeType; use Drupal\taxonomy\Entity\Vocabulary; use Drupal\Tests\taxonomy\Traits\TaxonomyTestTrait; /** * Ensures that access policy entity permissions work correctly. * * @group access_policy */ class AccessPolicyEntityAssignTest 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', '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(); $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(); // Make sure that the tags field is available on the node edit form. $form_display = EntityFormDisplay::load('node.page.default'); $form_display->setComponent('field_tags', [ 'type' => 'entity_reference_autocomplete', ])->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(); AccessPolicy::create([ 'id' => 'test_policy', 'description' => 'Test policy description', 'label' => 'Test policy', 'access_rules' => [], 'target_entity_type_id' => 'node', 'weight' => 0, ])->save(); AccessPolicy::create([ 'id' => 'test_policy_2', 'description' => 'Test policy 2 description', 'label' => 'Test policy 2', 'access_rules' => [], 'target_entity_type_id' => 'node', 'weight' => -10, ])->save(); $this->entityTypeSettings = $this->container->get('access_policy.entity_type_settings'); $settings = $this->entityTypeSettings->load('node'); $settings->set('selection_strategy', 'manual'); $settings->set('selection_strategy_settings', [ 'allow_empty' => FALSE, 'default_policy' => 'first_available', 'show_operations_link' => FALSE, ]); \Drupal::service('router.builder')->rebuildIfNeeded(); } /** * Tests accessing the access tab for entity without access policy. */ public function testAccessEntityWithoutAccessPolicy() { // Create an article content type that does not have access policy // enabled. NodeType::create([ 'type' => 'article', 'name' => 'Article', ])->save(); $node = $this->drupalCreateNode([ 'type' => 'article', 'status' => 1, ]); $web_user = $this->drupalCreateUser([ 'set entity access policy', 'edit any article content', ]); $this->drupalLogin($web_user); // They should be able to view the node like normal. $this->drupalGet('node/' . $node->id()); $this->assertSession()->statusCodeEquals(200); // They should be able to edit the node like normal. $this->drupalGet('node/' . $node->id() . '/edit'); $this->assertSession()->statusCodeEquals(200); $this->drupalGet('node/' . $node->id() . '/access'); $this->assertSession()->statusCodeEquals(403); } /** * Tests assigning a new policy only restricted by permissions. */ public function testAssignNewPolicy() { $settings = $this->entityTypeSettings->load('node'); $settings->set('selection_strategy', 'manual'); $settings->set('selection_strategy_settings', [ 'allow_empty' => TRUE, 'default_policy' => 'empty', 'show_confirmation_form' => TRUE, 'show_operations_link' => FALSE, ]); $settings->save(); // Having edit any page content and edit test_policy content should give // you access to the content. $web_user = $this->drupalCreateUser([ 'set entity access policy', 'assign test_policy access policy', 'assign test_policy_2 access policy', ]); $this->drupalLogin($web_user); $node = $this->drupalCreateNode([ 'type' => 'page', 'status' => 1, 'uid' => $web_user->id(), ]); $this->drupalGet('node/' . $node->id() . '/access'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->optionExists('access_policy', 'test_policy'); $this->assertSession()->optionExists('access_policy', 'test_policy_2'); $this->assertSession()->fieldValueEquals('access_policy', ''); $edit = [ 'access_policy' => 'test_policy_2', ]; $this->submitForm($edit, 'Save'); // Test the confirmation form. $this->assertSession()->pageTextContains('Are you sure you want to set access to Test policy 2?'); $this->submitForm([], 'Cancel'); $this->assertSession()->fieldValueEquals('access_policy', 'test_policy_2'); // Confirm that the policy was not saved on the node. $node = $this->drupalGetNodeByTitle($node->label()); $policy = $node->get('access_policy')->referencedEntities(); $this->assertEmpty($policy, 'The policy should not have been saved to the node.'); $edit = [ 'access_policy' => 'test_policy_2', ]; $this->submitForm($edit, 'Save'); $this->assertSession()->pageTextContains('Are you sure you want to set access to Test policy 2?'); $this->submitForm([], 'Save'); $this->assertSession()->fieldValueEquals('access_policy', 'test_policy_2'); $this->assertSession()->pageTextContains('Test policy 2 description'); $this->entityTypeManager->getStorage('node')->resetCache(); $node = $this->drupalGetNodeByTitle($node->label()); // Confirm that the policy was assigned to the node. $policy = $node->get('access_policy')->referencedEntities(); $this->assertNotEmpty($policy, 'The policy should have been saved to the node.'); $policy = $this->contentAccessPolicyManager->getAccessPolicy($node); $policy = reset($policy); $this->assertEquals('test_policy_2', $policy->id(), 'The access policy was incorrect.'); } /** * Test saving the access policy without the confirmation message. */ public function testAssignNewPolicyWithoutConfirmForm() { $settings = $this->entityTypeSettings->load('node'); $settings->set('selection_strategy', 'manual'); $settings->set('selection_strategy_settings', [ 'allow_empty' => TRUE, 'default_policy' => 'empty', 'show_operations_link' => FALSE, ]); $settings->save(); // Having edit any page content and edit test_policy content should give // you access to the content. $web_user = $this->drupalCreateUser([ 'set entity access policy', 'assign test_policy access policy', 'assign test_policy_2 access policy', ]); $this->drupalLogin($web_user); $node = $this->drupalCreateNode([ 'type' => 'page', 'status' => 1, 'uid' => $web_user->id(), ]); $this->drupalGet('node/' . $node->id() . '/access'); $this->assertSession()->statusCodeEquals(200); $edit = [ 'access_policy' => 'test_policy_2', ]; $this->submitForm($edit, 'Save'); $this->assertSession()->fieldValueEquals('access_policy', 'test_policy_2'); $this->assertSession()->pageTextContains('Test policy 2 description'); $this->entityTypeManager->getStorage('node')->resetCache(); $node = $this->drupalGetNodeByTitle($node->label()); // Confirm that the policy was assigned to the node. $policy = $node->get('access_policy')->referencedEntities(); $this->assertNotEmpty($policy, 'The policy should have been saved to the node.'); $policy = $this->contentAccessPolicyManager->getAccessPolicy($node); $policy = reset($policy); $this->assertEquals('test_policy_2', $policy->id(), 'The access policy was incorrect.'); } /** * Tests assigning a policy with selections rules on a node with no policy. */ public function testAssignNewPolicyWithSelectionRule() { $settings = $this->entityTypeSettings->load('node'); $settings->set('selection_strategy', 'manual'); $settings->save(); // Article is not applicable. NodeType::create([ 'type' => 'article', 'name' => 'Article', ])->save(); $access_policy = $this->entityTypeManager->getStorage('access_policy')->load('test_policy'); $selection_rule = $this->selectionRuleManager->getHandler('node', 'field_text'); $access_policy->addHandler('selection_rule', $selection_rule); $access_policy->save(); // Node has no access policy. $node_page = $this->drupalCreateNode([ 'type' => 'page', 'status' => 1, ]); $node_article = $this->drupalCreateNode([ 'type' => 'article', 'status' => 1, ]); $web_user = $this->drupalCreateUser([ 'set entity access policy', 'assign test_policy access policy', 'assign test_policy_2 access policy', ]); $this->drupalLogin($web_user); $this->drupalGet('node/' . $node_page->id() . '/access'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->optionExists('access_policy', 'test_policy'); $this->assertSession()->optionExists('access_policy', 'test_policy_2'); $this->drupalGet('node/' . $node_article->id() . '/access'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->optionNotExists('access_policy', 'test_policy'); $this->assertSession()->optionExists('access_policy', 'test_policy_2'); } /** * Tests assigning an access policy with an access rule. */ public function testAssignNewPolicyWithAccessRule() { $settings = $this->entityTypeSettings->load('node'); $settings->set('selection_strategy', 'manual'); $settings->save(); // Assign test_policy access policy to the node. $access_policy = $this->entityTypeManager->getStorage('access_policy')->load('test_policy'); $handler = $this->accessRuleManager->getHandler('node', 'match_field_tags'); $handler->setSettings([ 'operator' => 'in', 'widget' => [ 'show' => TRUE, ], 'value' => [ 'field' => 'field_tags', ], ]); $access_policy->addHandler('access_rule', $handler); $access_policy->save(); // Test entity reference fields. $term_1 = $this->createTerm($this->vocabulary, [ 'title' => 'Term 1', ]); $term_1->save(); // Assigning the inapplicable selection rule. $node = $this->drupalCreateNode([ 'type' => 'page', 'status' => 1, ]); $web_user = $this->drupalCreateUser([ 'set entity access policy', 'assign test_policy access policy', 'assign test_policy_2 access policy', ]); $web_user->set('field_tags', [ $term_1, ])->save(); $this->drupalLogin($web_user); $this->drupalGet('node/' . $node->id() . '/access'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->fieldValueEquals('access_policy', ''); $this->assertSession()->optionExists('access_policy', 'test_policy'); $this->assertSession()->optionExists('access_policy', 'test_policy_2'); // Assign the access policy with access rule so that we can set the tag. $node->set('access_policy', ['test_policy']); $node->save(); $this->drupalGet('node/' . $node->id() . '/access'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->fieldValueEquals('access_policy', 'test_policy'); $term_input = $term_1->label() . ' (' . $term_1->id() . ')'; $edit = [ 'field_tags[0][target_id]' => $term_input, ]; $this->submitForm($edit, 'Save'); $this->submitForm([], 'Save'); $this->assertSession()->fieldValueEquals('field_tags[0][target_id]', $term_input); $this->assertSession()->pageTextContains('Access has been changed to Test policy.'); $node = $this->drupalGetNodeByTitle($node->label()); $this->assertEquals($term_1->id(), $node->get('field_tags')->target_id); } /** * Tests changing the current policy to another access policy. */ public function testChangePolicy() { $settings = $this->entityTypeSettings->load('node'); $settings->set('selection_strategy', 'manual'); $settings->set('selection_strategy_settings', [ 'allow_empty' => TRUE, 'default_policy' => 'first_available', 'show_operations_link' => FALSE, ]); $settings->save(); // Page content type has the field so it should show the policy. $node = $this->drupalCreateNode([ 'type' => 'page', 'status' => 1, 'access_policy' => ['test_policy'], ]); $web_user = $this->drupalCreateUser([ 'set entity access policy', 'assign test_policy access policy', 'assign test_policy_2 access policy', ]); $this->drupalLogin($web_user); $this->drupalGet('node/' . $node->id() . '/access'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->fieldValueEquals('access_policy', 'test_policy'); $edit = [ 'access_policy' => 'test_policy_2', ]; $this->submitForm($edit, 'Save'); $this->submitForm([], 'Save'); $this->assertSession()->fieldValueEquals('access_policy', 'test_policy_2'); $node = $this->drupalGetNodeByTitle($node->label()); $policy = $this->contentAccessPolicyManager->getAccessPolicy($node); $policy = reset($policy); $this->assertEquals('test_policy_2', $policy->id(), 'The access policy was incorrect.'); // This user does not have permission to assign any policies. It should // trigger a 403. $web_user = $this->drupalCreateUser([ 'set entity access policy', ]); $this->drupalLogin($web_user); $this->drupalGet('node/' . $node->id() . '/access'); $this->assertSession()->statusCodeEquals(403); // This user does not have permission to assign test_policy_2. It should // trigger a 403. $web_user = $this->drupalCreateUser([ 'set entity access policy', 'assign test_policy access policy', ]); $this->drupalLogin($web_user); $this->drupalGet('node/' . $node->id() . '/access'); $this->assertSession()->statusCodeEquals(403); $web_user = $this->drupalCreateUser([ 'set entity access policy', 'assign test_policy_2 access policy', ]); $this->drupalLogin($web_user); $this->drupalGet('node/' . $node->id() . '/access'); $this->assertSession()->statusCodeEquals(200); } /** * Tests changing an access policy with a selection rule. */ public function testChangePolicyWithSelectionRule() { $settings = $this->entityTypeSettings->load('node'); $settings->set('selection_strategy', 'manual'); $settings->set('selection_strategy_settings', [ 'allow_empty' => FALSE, 'default_policy' => 'first_available', 'show_operations_link' => FALSE, ]); $settings->save(); $access_policy = $this->entityTypeManager->getStorage('access_policy')->load('test_policy_2'); $selection_rule = $this->selectionRuleManager->getHandler('node', 'field_text'); $access_policy->addHandler('selection_rule', $selection_rule); $access_policy->save(); // Page content type has the field so it should show the policy. $node = $this->drupalCreateNode([ 'type' => 'page', 'status' => 1, 'access_policy' => ['test_policy'], ]); $web_user = $this->drupalCreateUser([ 'set entity access policy', 'assign test_policy access policy', 'assign test_policy_2 access policy', ]); $this->drupalLogin($web_user); $this->drupalGet('node/' . $node->id() . '/access'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->fieldValueEquals('access_policy', 'test_policy'); $edit = [ 'access_policy' => 'test_policy_2', ]; $this->submitForm($edit, 'Save'); $this->submitForm([], 'Save'); $this->assertSession()->fieldValueEquals('access_policy', 'test_policy_2'); $node = $this->drupalGetNodeByTitle($node->label()); $policy = $this->contentAccessPolicyManager->getAccessPolicy($node); $policy = reset($policy); $this->assertEquals('test_policy_2', $policy->id(), 'The access policy was incorrect.'); } /** * Tests changing the access policy with an inapplicable selection rule. * * This is testing an edge case where a selection rule may have been * applicable once but after assignment. */ public function testChangePolicyWithInapplicableSelectionRule() { $settings = $this->entityTypeSettings->load('node'); $settings->set('selection_strategy', 'manual'); $settings->set('selection_strategy_settings', [ 'allow_empty' => FALSE, 'default_policy' => 'first_available', 'show_operations_link' => FALSE, ]); $settings->save(); // Article does not have field_text so it should not be applicable. NodeType::create([ 'type' => 'article', 'name' => 'Article', ])->save(); // Assign test_policy access policy to the node. $access_policy = $this->entityTypeManager->getStorage('access_policy')->load('test_policy'); $selection_rule = $this->selectionRuleManager->getHandler('node', 'field_text'); $access_policy->addHandler('selection_rule', $selection_rule); $access_policy->save(); // Assigning the inapplicable selection rule. $node_article = $this->drupalCreateNode([ 'type' => 'article', 'status' => 1, 'access_policy' => ['test_policy'], ]); // This does not have any access policy and therefore should not show // test_policy. $node_article_2 = $this->drupalCreateNode([ 'type' => 'article', 'status' => 1, ]); $web_user = $this->drupalCreateUser([ 'set entity access policy', 'assign test_policy access policy', 'assign test_policy_2 access policy', ]); $this->drupalLogin($web_user); $this->drupalGet('node/' . $node_article->id() . '/access'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->fieldValueEquals('access_policy', 'test_policy'); $this->assertSession()->optionExists('access_policy', 'test_policy_2'); // Change the policy, test_policy should then be removed from the select // list. $edit = [ 'access_policy' => 'test_policy_2', ]; $this->submitForm($edit, 'Save'); $this->submitForm([], 'Save'); $this->assertSession()->fieldValueEquals('access_policy', 'test_policy_2'); $this->assertSession()->fieldValueEquals('access_policy', 'test_policy_2'); $this->assertSession()->optionNotExists('access_policy', 'test_policy'); $this->drupalGet('node/' . $node_article_2->id() . '/access'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->optionNotExists('access_policy', 'test_policy'); $this->assertSession()->optionExists('access_policy', 'test_policy_2'); } /** * Tests accessing the access tab when it has the type selection rule. */ public function testChangeAccessPolicyWithTypeSelectionRule() { $settings = $this->entityTypeSettings->load('node'); $settings->set('selection_strategy', 'manual'); $settings->set('selection_strategy_settings', [ 'allow_empty' => FALSE, 'default_policy' => 'first_available', 'show_operations_link' => FALSE, ]); $settings->save(); NodeType::create([ 'type' => 'article', 'name' => 'Article', ])->save(); $access_policy = $this->entityTypeManager->getStorage('access_policy')->load('test_policy'); $selection_rule = $this->selectionRuleManager->getHandler('node', 'type'); $selection_rule->setSettings([ 'value' => [ 'page' => 'page', ], 'operator' => 'or', ]); $access_policy->addHandler('selection_rule', $selection_rule); $access_policy->save(); $web_user = $this->drupalCreateUser([ 'set entity access policy', 'assign test_policy access policy', 'assign test_policy_2 access policy', ]); $this->drupalLogin($web_user); // Page content type has the field so it should show the policy. $node = $this->drupalCreateNode([ 'type' => 'page', 'status' => 1, ]); $this->drupalGet('node/' . $node->id() . '/access'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->optionExists('access_policy', 'test_policy'); $this->assertSession()->optionExists('access_policy', 'test_policy_2'); // Article content type does not support Test policy, so it should not // appear. $node_article = $this->drupalCreateNode([ 'title' => 'Article', 'type' => 'article', 'status' => 1, ]); $this->drupalGet('node/' . $node_article->id() . '/access'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->optionNotExists('access_policy', 'test_policy'); $this->assertSession()->optionExists('access_policy', 'test_policy_2'); } /** * Tests changing a policy that has an access rule. */ public function testChangePolicyWithAccessRule() { $settings = $this->entityTypeSettings->load('node'); $settings->set('selection_strategy', 'manual'); $settings->save(); // Assign test_policy access policy to the node. $access_policy = $this->entityTypeManager->getStorage('access_policy')->load('test_policy'); $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(); // Test entity reference fields. $term_1 = $this->createTerm($this->vocabulary, [ 'title' => 'Term 1', ]); $term_1->save(); $term_2 = $this->createTerm($this->vocabulary, [ 'title' => 'Term 1', ]); $term_2->save(); // Assigning the inapplicable selection rule. $node = $this->drupalCreateNode([ 'type' => 'page', 'status' => 1, 'field_tags' => [ $term_1, ], 'access_policy' => ['test_policy_2'], ]); $web_user = $this->drupalCreateUser([ 'set entity access policy', 'assign test_policy access policy', 'assign test_policy_2 access policy', ]); $web_user->set('field_tags', [ $term_1, ])->save(); $this->drupalLogin($web_user); $this->drupalGet('node/' . $node->id() . '/access'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->fieldValueEquals('access_policy', 'test_policy_2'); $this->assertSession()->optionExists('access_policy', 'test_policy'); // Change the policy to one with an access rule. $edit = [ 'access_policy' => 'test_policy', ]; $this->submitForm($edit, 'Save'); $this->submitForm([], 'Save'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->fieldValueEquals('access_policy', 'test_policy'); $this->assertSession()->optionExists('access_policy', 'test_policy_2'); // This user has the same permissions but different tag, therefore they // shouldn't have access. $web_user = $this->drupalCreateUser([ 'set entity access policy', 'assign test_policy access policy', 'assign test_policy_2 access policy', ]); $web_user->set('field_tags', [ $term_2, ])->save(); $this->drupalLogin($web_user); $this->drupalGet('node/' . $node->id() . '/access'); $this->assertSession()->statusCodeEquals(403); } /** * Tests changing the current policy to another on save. */ public function testChangePolicyOnSave() { $settings = $this->entityTypeSettings->load('node'); $settings->set('selection_strategy', 'dynamic'); $settings->save(); AccessPolicy::create([ 'id' => 'public', 'label' => 'Test policy', 'access_rules' => [], 'target_entity_type_id' => 'node', 'weight' => 0, ])->save(); AccessPolicy::create([ 'id' => 'tags', 'label' => 'Tags', 'access_rules' => [], 'target_entity_type_id' => 'node', 'weight' => -10, ])->save(); // Page content type has the field so it should show the policy. $node = $this->drupalCreateNode([ 'title' => 'Node 1', 'type' => 'page', 'status' => 1, 'access_policy' => ['public'], ]); $node = $this->drupalGetNodeByTitle($node->label()); $policy = $this->contentAccessPolicyManager->getAccessPolicy($node); $policy = reset($policy); $this->assertEquals('public', $policy->id(), 'The access policy should be public.'); $web_user = $this->drupalCreateUser([ 'access content', 'access administration pages', 'access content overview', 'edit any page content', 'create page content', 'edit public content', 'edit tags content', 'assign public access policy', 'assign tags access policy', ]); $this->drupalLogin($web_user); $this->drupalGet('node/' . $node->id() . '/edit'); $this->assertSession()->statusCodeEquals(200); $edit = [ 'title[0][value]' => 'Node 1', ]; $this->submitForm($edit, 'Save'); $this->entityTypeManager->getStorage('node')->resetCache(); $node = $this->drupalGetNodeByTitle($node->label()); $policy = $this->contentAccessPolicyManager->getAccessPolicy($node); $policy = reset($policy); $this->assertEquals('tags', $policy->id(), 'The access policy should be tags.'); } /** * Tests changing the access policy on save with a selection rule. */ public function testChangePolicyOnSaveWithSelectionRule() { $settings = $this->entityTypeSettings->load('node'); $settings->set('selection_strategy', 'dynamic'); $settings->save(); AccessPolicy::create([ 'id' => 'public', 'label' => 'Public', 'access_rules' => [], 'target_entity_type_id' => 'node', 'type' => 'public', 'weight' => 0, ])->save(); $access_policy = AccessPolicy::create([ 'id' => 'tags', 'label' => 'Tags', 'access_rules' => [], 'target_entity_type_id' => 'node', 'weight' => -10, ]); $access_policy->save(); $handler = $this->selectionRuleManager->getHandler('node', 'field_tags'); $handler->setSettings([ 'operator' => 'not empty', ]); $access_policy->addHandler('selection_rule', $handler); $access_policy->save(); $term_1 = $this->createTerm($this->vocabulary, [ 'title' => 'Term 1', ]); $term_1->save(); $web_user = $this->drupalCreateUser([ 'access content', 'administer nodes', 'access administration pages', 'access content overview', 'edit any page content', 'create page content', 'edit public content', 'edit tags content', 'set entity access policy', 'assign public access policy', 'assign tags access policy', ]); $this->drupalLogin($web_user); $node = $this->drupalCreateNode([ 'title' => 'Node 1', 'type' => 'page', 'status' => 1, 'field_tags' => [ $term_1, ], ]); $node = $this->drupalGetNodeByTitle($node->label()); $policy = $this->contentAccessPolicyManager->getAccessPolicy($node); $policy = reset($policy); $this->assertEquals('tags', $policy->id(), 'The access policy should be tags.'); // Remove the access policy but leave the taxonomy term. On save, this // should add the policy back. $this->contentAccessPolicyManager->remove($node); $node = $this->drupalGetNodeByTitle($node->label()); $policy = $this->contentAccessPolicyManager->getAccessPolicy($node); $this->assertNotEmpty($policy, 'The access policy should not have been removed'); $policy = reset($policy); $this->assertEquals('tags', $policy->id(), 'The access policy should be tags.'); // Remove the tag, it should change it to public. $this->drupalGet('node/' . $node->id() . '/edit'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->pageTextContains('Access Tags'); // Remove the tag, it should change it to public. $edit = [ 'title[0][value]' => 'Node 1', 'field_tags[0][target_id]' => '', ]; $this->submitForm($edit, 'Save'); $this->entityTypeManager->getStorage('node')->resetCache(); $node = $this->drupalGetNodeByTitle($node->label()); $policy = $this->contentAccessPolicyManager->getAccessPolicy($node); $policy = reset($policy); $this->assertEquals('public', $policy->id(), 'The access policy should be public.'); $this->drupalGet('node/' . $node->id() . '/access'); $this->assertSession()->statusCodeEquals(403); $this->drupalGet('node/' . $node->id() . '/edit'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->pageTextContains('Access Public'); } /** * Test that the default access policy gets saved to the node when created. */ public function testDefaultAccessPolicyOnNodeCreate() { $web_user = $this->drupalCreateUser([ 'assign test_policy access policy', ]); $this->drupalLogin($web_user); $node = $this->drupalCreateNode([ 'type' => 'page', 'status' => 1, ]); $node->save(); $policy = $this->contentAccessPolicyManager->getAccessPolicy($node); $policy = reset($policy); $this->assertEquals('test_policy', $policy->id(), 'The access policy should be test_policy'); } /** * Tests removing an access policy from a node via a form. */ public function testSetEmptyAccessPolicyOnEntity() { // Allow the access policy to be empty. $settings = $this->entityTypeSettings->load('node'); $settings->set('selection_strategy', 'manual'); $settings->set('selection_strategy_settings', [ 'allow_empty' => TRUE, 'default_policy' => 'empty', 'show_operations_link' => FALSE, ]); $settings->save(); // Create a published page. Under normal circumstances this will always // be visible. $node = $this->drupalCreateNode([ 'type' => 'page', 'status' => 1, ]); // Assign test_policy access policy to the node. $access_policy = \Drupal::entityTypeManager()->getStorage('access_policy')->load('test_policy'); $this->contentAccessPolicyManager->assign($node, $access_policy); // Having edit any page content and edit test_policy content should give // you access to the content. $web_user = $this->drupalCreateUser([ 'set entity access policy', 'assign test_policy access policy', ]); $this->drupalLogin($web_user); $this->drupalGet('node/' . $node->id() . '/access'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->pageTextContains('- Unrestricted -'); // Remove the access policy and then assert that the access policy is // marked as removed and it won't revert to the default value again. $edit = [ 'access_policy' => '', ]; $this->submitForm($edit, 'Save'); $this->submitForm([], 'Save'); $node = $this->drupalGetNodeByTitle($node->label()); $empty = $this->contentAccessPolicyManager->isEmpty($node); $this->assertTrue($empty, 'The access policy should have been removed.'); $this->assertSession()->fieldValueEquals('access_policy', ''); // Assert that the row was removed. $policies = $node->get('access_policy')->referencedEntities(); $this->assertEmpty($policies, 'There should be no access policies.'); } /** * Tests not allowing users to disable an access policy on a node. */ public function testDoNotRemoveAccessPolicyOnEntityWhenNotAllowed() { // Allow the access policy to be disabled. $settings = $this->entityTypeSettings->load('node'); $settings->set('selection_strategy', 'manual'); $settings->set('selection_strategy_settings', [ 'allow_empty' => FALSE, 'default_policy' => 'first_available', 'show_operations_link' => FALSE, ]); $settings->save(); // Create a published page. Under normal circumstances this will always // be visible. $node = $this->drupalCreateNode([ 'type' => 'page', 'status' => 1, ]); // Assign test_policy access policy to the node. $access_policy = \Drupal::entityTypeManager()->getStorage('access_policy')->load('test_policy'); $this->contentAccessPolicyManager->assign($node, $access_policy); // Having edit any page content and edit test_policy content should give // you access to the content. $web_user = $this->drupalCreateUser([ 'set entity access policy', 'assign test_policy access policy', ]); $this->drupalLogin($web_user); $this->drupalGet('node/' . $node->id() . '/access'); $this->assertSession()->statusCodeEquals(200); // Assert that the "Disabled" option exists in the select list. $this->assertSession()->pageTextNotContains('- Unrestricted -'); // Attempt to remove the access policy. This should not be allowed. try { $edit = [ 'access_policy' => '', ]; $this->submitForm($edit, 'Save'); } catch (\InvalidArgumentException $e) { // Expected exception; just continue testing. } $node = $this->drupalGetNodeByTitle($node->label()); $empty = $this->contentAccessPolicyManager->isEmpty($node); $this->assertFalse($empty, 'The access policy should not have been removed.'); $this->assertSession()->fieldValueEquals('access_policy', 'test_policy'); } /** * Tests assigning an empty policy if no applicable policy was found. */ public function testAssignEmptyPolicyIfNoneFound() { // Even if allow empty is FALSE it should still set it to empty if no // applicable policy was found. $settings = $this->entityTypeSettings->load('node'); $settings->set('selection_strategy', 'manual'); $settings->set('selection_strategy_settings', [ 'allow_empty' => FALSE, 'default_policy' => 'first_available', 'show_operations_link' => FALSE, ]); $settings->save(); // This user can't assign any access policies. $web_user = $this->drupalCreateUser([ 'set entity access policy', ]); $this->drupalLogin($web_user); $node = $this->drupalCreateNode([ 'type' => 'page', 'status' => 1, ]); // Confirm that the policy was not assigned. $node = $this->drupalGetNodeByTitle($node->label()); $empty = $this->contentAccessPolicyManager->isEmpty($node); $this->assertTrue($empty, 'The access policy should not have been set.'); // View the Access policy selection page as super admin and confirm that // '- Unrestricted -' is selected and that the field is enabled. $web_user = $this->drupalCreateUser([ 'set entity access policy', 'assign test_policy access policy', ]); $this->drupalLogin($web_user); $this->drupalGet('node/' . $node->id() . '/access'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->pageTextContains('- Unrestricted -'); $this->assertSession()->fieldEnabled('access_policy'); // Change the policy to test_policy. This should then remove // '- Unrestricted -'. $edit = [ 'access_policy' => 'test_policy', ]; $this->submitForm($edit, 'Save'); $this->assertSession()->pageTextNotContains('- Unrestricted -'); } }