access_policy-1.0.x-dev/tests/src/Functional/AccessPolicyCreationTest.php
tests/src/Functional/AccessPolicyCreationTest.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; /** * Tests the creation and deletion of access policy entities. * * @group access_policy */ class AccessPolicyCreationTest extends AccessPolicyTestBase { /** * Modules to enable. * * @var array */ protected static $modules = [ 'access_policy', 'access_policy_test', 'taxonomy', 'filter', 'node', 'block_content', 'comment', 'datetime', 'options', ]; /** * {@inheritdoc} */ protected $defaultTheme = 'stark'; /** * Tests creating and deleting a new access policy with rules and bundles. */ public function testCreateAndDeleteAccessPolicyWithRules() { $settings = $this->entityTypeSettings->load('node'); $settings->set('selection_strategy', 'manual'); $settings->save(); $rid = $this->drupalCreateRole([ 'access administration pages', 'administer access policy entities', ]); $web_user = $this->drupalCreateUser(); $web_user->addRole($rid); $web_user->save(); $this->drupalLogin($web_user); $this->drupalGet('admin/people/access-policies'); $this->assertSession()->statusCodeEquals(200); $this->drupalGet('admin/people/access-policies/add'); $this->assertSession()->optionExists('target_entity_type_id', 'node'); $this->assertSession()->optionExists('target_entity_type_id', 'taxonomy_term'); $this->assertSession()->optionExists('target_entity_type_id', 'block_content'); $this->assertSession()->optionNotExists('target_entity_type_id', 'comment'); $edit = [ 'label' => 'Foo', 'id' => 'foo', ]; $this->submitForm($edit, 'Save'); // Add a rule to the policy (cancel) $this->drupalGet('/admin/people/access-policies/foo/handler/access_rule/add'); $this->assertSession()->statusCodeEquals(200); $edit = [ 'access_rules[node:title]' => TRUE, ]; $this->submitForm($edit, 'Add and configure'); // Go to access rule configuration form and press cancel. Make sure it // does not save anything. $this->submitForm([], 'Cancel'); $this->drupalGet('/admin/people/access-policies/foo'); $this->assertSession()->pageTextNotContains('Title (= )'); // Add a rule to the policy (submit). $this->drupalGet('/admin/people/access-policies/foo/handler/access_rule/add'); $this->assertSession()->statusCodeEquals(200); $edit = [ 'access_rules[node:title]' => TRUE, ]; $this->submitForm($edit, 'Add and configure'); $this->assertSession()->fieldValueEquals('query', TRUE); $this->assertSession()->fieldValueEquals('admin_label', ''); $this->submitForm([], 'Save'); $this->drupalGet('/admin/people/access-policies/foo'); $this->assertSession()->pageTextContains('Title (= )'); // Change settings of title access rule. $this->drupalGet('/admin/people/access-policies/foo/handler/access_rule/title'); $this->assertSession()->statusCodeEquals(200); $edit = [ 'operator' => '=', 'value' => 'Foo bar', 'query' => FALSE, ]; $this->submitForm($edit, 'Save'); $this->drupalGet('/admin/people/access-policies/foo'); $this->assertSession()->pageTextContains('Configure Foo access policy'); $this->assertSession()->pageTextContains('Title (= Foo bar)'); $this->drupalGet('/admin/people/access-policies/foo/handler/access_rule/title'); $this->assertSession()->fieldValueEquals('operator', '='); $this->assertSession()->fieldValueEquals('value', 'Foo bar'); $this->assertSession()->fieldValueEquals('query', FALSE); // Change the admin label. $edit = [ 'admin_label' => 'Title field overridden.', ]; $this->submitForm($edit, 'Save'); $this->drupalGet('/admin/people/access-policies/foo'); $this->assertSession()->pageTextContains('Title field overridden.'); // Delete the is_own access rule. $this->drupalGet('/admin/people/access-policies/foo/handler/access_rule/title/remove'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->pageTextContains('Are you sure you want to remove this?'); $this->submitForm([], 'Remove'); $this->drupalGet('/admin/people/access-policies/foo'); $this->assertSession()->pageTextNotContains('Authored by current user (modified)'); // Change the other fields in the policy. $edit = [ 'label' => 'Bar', 'description' => 'Lorem ipsum dolor.', 'access_rule_operator' => 'OR', ]; $this->submitForm($edit, 'Save'); $this->clickLink('Configure'); $this->assertSession()->fieldValueEquals('label', 'Bar'); $this->assertSession()->fieldValueEquals('description', 'Lorem ipsum dolor.'); $this->assertSession()->fieldValueEquals('access_rule_operator', 'OR'); $this->clickLink('Delete'); $this->assertSession()->pageTextContains('Are you sure you want to delete Bar?'); $this->submitForm([], 'Delete'); $this->assertSession()->pageTextContains('Deleted Bar Access Policy'); $policy = $this->entityTypeManager->getStorage('access_policy')->load('foo'); $this->assertEmpty($policy, 'The policy should have been deleted.'); } /** * Tests setting creating a new access policy. */ public function testDoNotPermitPolicyDeletionWhenUsed() { AccessPolicy::create([ 'id' => 'test_policy', 'label' => 'Test policy', 'access_rules' => [], 'target_entity_type_id' => 'node', ])->save(); $this->drupalCreateNode([ 'type' => 'page', 'access_policy' => ['test_policy'], ]); $web_user = $this->drupalCreateUser([ 'access administration pages', 'administer access policy entities', ]); $this->drupalLogin($web_user); $this->drupalGet('admin/people/access-policies/test_policy/delete'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->pageTextContains('Are you sure you want to delete Test policy?'); $this->assertSession()->pageTextContains('The access policy Test policy is being used, and cannot be deleted.'); $this->assertSession()->linkNotExists('Delete'); } /** * Tests updating the access policy operations. */ public function testUpdateAccessPolicyOperations() { $rid = $this->drupalCreateRole([ 'access administration pages', 'administer access policy entities', ]); $web_user = $this->drupalCreateUser(); $web_user->addRole($rid); $web_user->save(); $this->drupalLogin($web_user); $this->drupalGet('admin/people/access-policies'); $this->assertSession()->statusCodeEquals(200); $this->drupalGet('admin/people/access-policies/add'); $edit = [ 'label' => 'Foo', 'id' => 'foo', ]; $this->submitForm($edit, 'Save'); // Add a rule to the policy and override its default operations. $this->drupalGet('/admin/people/access-policies/foo/handler/access_rule/add'); $this->assertSession()->statusCodeEquals(200); $edit = [ 'access_rules[node:title]' => TRUE, ]; $this->submitForm($edit, 'Add and configure'); $this->submitForm([], 'Save'); // Disable the default access rule operations and use 'view' and 'edit'. // For some reason it needs to be done through the API. it doesn't work // through the interface during the test. $policy = $this->entityTypeManager->getStorage('access_policy')->load('foo'); $handlers = $policy->getHandlers('access_rule'); $handlers['title']['settings']['operations'] = ['view', 'edit']; $policy->setHandlers('access_rule', $handlers); $policy->save(); // Add the new permissions to the role. They should be generated after // creating the new policy. $role = $this->entityTypeManager->getStorage('user_role')->load($rid); $role->grantPermission('view foo content'); $role->grantPermission('delete foo content'); $role->grantPermission('edit foo content'); $role->grantPermission('view all foo content revisions'); $role->grantPermission('view any foo unpublished content'); $role->grantPermission('assign foo access policy'); $role->save(); // Confirm that manage access is checked and disabled. $this->drupalGet('admin/people/access-policies/foo/operations'); $this->assertSession()->checkboxChecked('operations[manage_access][permission]'); $this->assertSession()->fieldDisabled('operations[manage_access][permission]'); // Disable the permissions. It should automatically remove the permissions // from the roles. $edit = [ 'operations[view][permission]' => 0, 'operations[view_unpublished][permission]' => 0, 'operations[view_all_revisions][permission]' => 0, 'operations[edit][permission]' => 0, 'operations[delete][permission]' => 0, 'operations[manage_access][permission]' => 0, ]; $this->submitForm($edit, 'Save operations'); $this->entityTypeManager->getStorage('user_role')->resetCache(); $role = $this->entityTypeManager->getStorage('user_role')->load($rid); $expected = [ 'access administration pages', 'administer access policy entities', // It should not be possible to remove this because it is not owned by // the manage_access operation. 'assign foo access policy', ]; $this->assertEquals($expected, $role->getPermissions()); // Disable the view access rule, it should remove the view operation // override. $this->drupalGet('admin/people/access-policies/foo/operations'); $edit = [ 'operations[view][access_rules]' => 0, ]; $this->submitForm($edit, 'Save operations'); $this->entityTypeManager->getStorage('access_policy')->resetCache(); $policy = $this->entityTypeManager->getStorage('access_policy')->load('foo'); $handler = $policy->getHandler('access_rule', 'title'); $this->assertEquals(['edit'], $handler['settings']['operations'], 'The view operation should be removed.'); // Disable all the access rules, it should hide the access rules form and // remove all the access rules. $this->drupalGet('admin/people/access-policies/foo/operations'); $edit = [ 'operations[view][access_rules]' => 0, 'operations[view_unpublished][access_rules]' => 0, 'operations[view_all_revisions][access_rules]' => 0, 'operations[edit][access_rules]' => 0, 'operations[delete][access_rules]' => 0, 'operations[manage_access][access_rules]' => 0, ]; $this->submitForm($edit, 'Save operations'); $this->assertSession()->linkNotExists('Add Rule'); $this->assertSession()->linkNotExists('Validation operator'); $this->entityTypeManager->getStorage('access_policy')->resetCache(); $policy = $this->entityTypeManager->getStorage('access_policy')->load('foo'); $handlers = $policy->getHandlers('access_rule'); $this->assertEmpty($handlers, 'The access rules should have been removed.'); // Disable the columns, it should hide them on the form. $this->drupalGet('admin/people/access-policies/foo'); $session = $this->assertSession(); $session->elementExists('xpath', "//th[text() = 'View unpublished']"); $session->elementExists('xpath', "//th[text() = 'View']"); $session->elementExists('xpath', "//th[text() = 'View all revisions']"); $session->elementExists('xpath', "//th[text() = 'Edit']"); $session->elementExists('xpath', "//th[text() = 'Delete']"); $this->drupalGet('admin/people/access-policies/foo/operations'); $edit = [ 'operations[view][show_column]' => 0, 'operations[view_unpublished][show_column]' => 0, 'operations[view_all_revisions][show_column]' => 0, 'operations[edit][show_column]' => 0, 'operations[delete][show_column]' => 0, 'operations[manage_access][show_column]' => 0, ]; $this->submitForm($edit, 'Save operations'); $this->drupalGet('admin/people/access-policies/foo'); $session->elementNotExists('xpath', "//th[text() = 'View unpublished']"); $session->elementNotExists('xpath', "//th[text() = 'View']"); $session->elementNotExists('xpath', "//th[text() = 'View all revisions']"); $session->elementNotExists('xpath', "//th[text() = 'Edit']"); $session->elementNotExists('xpath', "//th[text() = 'Delete']"); } /** * Tests creating and viewing an access policy with broken access rules. */ public function testCreatePolicyWithBrokenRule() { // This is an access policy with the old access rule data and a missing // plugin. Without a valid plugin it is effectively broken. AccessPolicy::create([ 'id' => 'broken_rules', 'label' => 'Access policy with broken rules.', 'access_rules' => [ 'field_value:node:field_text' => [ 'plugin_id' => 'field_value:node:field_text', 'settings' => [ 'target' => 'value', 'value' => 'My text', 'operator' => '=', 'query' => TRUE, 'empty_behavior' => 'deny', ], ], ], 'target_entity_type_id' => 'node', ])->save(); // This is an access policy with correct access rule data. This acts as a // control to compare against the broken_rules policy. $policy = AccessPolicy::create([ 'id' => 'working_rules', 'label' => 'Access policy with working rules.', 'target_entity_type_id' => 'node', ]); $access_rule = $this->accessRuleManager->getHandler('node', 'field_text', [ 'value' => 'My text', 'operator' => '=', 'query' => TRUE, 'empty_behavior' => 'deny', ]); $policy->addHandler('access_rule', $access_rule); $policy->save(); $rid = $this->drupalCreateRole([ 'access administration pages', 'access content overview', 'administer access policy entities', 'view broken_rules content', ]); $web_user = $this->drupalCreateUser(); $web_user->addRole($rid); $web_user->save(); $this->drupalLogin($web_user); // Because the user does not have an entity reference this normally // would return 403, but because it's broken it should return 200. $node_broken = $this->drupalCreateNode([ 'title' => 'Node (broken)', 'type' => 'page', 'status' => 1, 'access_policy' => ['broken_rules'], ]); $node_working = $this->drupalCreateNode([ 'title' => 'Node (working)', 'type' => 'page', 'status' => 1, 'field_text' => 'My text', 'access_policy' => ['working_rules'], ]); $this->drupalGet('node/' . $node_working->id()); $this->assertSession()->statusCodeEquals(403); $this->drupalGet('node/' . $node_broken->id()); $this->assertSession()->statusCodeEquals(200); $this->drupalGet('admin/content'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->pageTextContainsOnce('Node (broken)'); $this->assertSession()->pageTextNotContains('Node (working)'); // Configure the policy. $this->drupalGet('admin/people/access-policies/broken_rules'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->pageTextContainsOnce('Broken/missing handler'); // Configure the broken access rule. $this->clickLink('Configure'); $this->assertSession()->pageTextContains('The handler for this access rule is broken or missing.'); // Delete the broken access rule. $this->drupalGet('/admin/people/access-policies/broken_rules/handler/access_rule/field_value:node:field_text/remove'); $this->submitForm([], 'Remove'); $this->drupalGet('/admin/people/access-policies/broken_rules'); $this->assertSession()->pageTextNotContains('Broken/missing handler'); // Add a rule to the policy. It should show the broken handler. $this->drupalGet('/admin/people/access-policies/broken_rules/handler/access_rule/add'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->pageTextContains('Broken/missing handler'); } /** * Tests creating and viewing an access policy invalid access rule data. */ public function testCreatePolicyWithInvalidAccessRuleData() { // This is an access policy with the old access rule data. However, this has // a valid plugin id, therefore it should still work but show a warning. AccessPolicy::create([ 'id' => 'invalid_rules', 'label' => 'Access policy with invalid rule data.', 'access_rules' => [ 'field_text' => [ 'plugin_id' => 'entity_field_string', 'settings' => [ 'target' => 'value', 'value' => 'My text', 'operator' => '=', 'query' => TRUE, 'empty_behavior' => 'deny', 'admin_label' => '', ], ], ], 'target_entity_type_id' => 'node', ])->save(); // This is an access policy with valid access rule data. This acts as a // control to compare against the invalid_rules policy. $policy = AccessPolicy::create([ 'id' => 'valid_rules', 'label' => 'Access policy with valid rule data.', 'target_entity_type_id' => 'node', ]); $access_rule = $this->accessRuleManager->getHandler('node', 'field_text', [ 'value' => 'My text', 'operator' => '=', 'query' => TRUE, 'empty_behavior' => 'deny', ]); $policy->addHandler('access_rule', $access_rule); $policy->save(); $rid = $this->drupalCreateRole([ 'access administration pages', 'access content overview', 'administer access policy entities', 'view invalid_rules content', 'view valid_rules content', ]); $web_user = $this->drupalCreateUser(); $web_user->addRole($rid); $web_user->save(); $this->drupalLogin($web_user); $node_invalid = $this->drupalCreateNode([ 'title' => 'Node (invalid)', 'type' => 'page', 'status' => 1, 'field_text' => 'Not matching text', 'access_policy' => ['invalid_rules'], ]); $node_valid = $this->drupalCreateNode([ 'title' => 'Node (valid)', 'type' => 'page', 'status' => 1, 'field_text' => 'Not matching text', 'access_policy' => ['valid_rules'], ]); $this->drupalGet('node/' . $node_valid->id()); $this->assertSession()->statusCodeEquals(403); $this->drupalGet('node/' . $node_invalid->id()); $this->assertSession()->statusCodeEquals(403); $this->drupalGet('admin/content'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->pageTextNotContains('Node (invalid)'); $this->assertSession()->pageTextNotContains('Node (valid)'); // Configure the policy. $this->drupalGet('admin/people/access-policies/invalid_rules'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->pageTextContainsOnce('Warning: invalid data detected'); // It should be possible to configure it. $this->clickLink('Configure'); $this->assertSession()->fieldExists('operations[view]'); $this->assertSession()->fieldExists('admin_label'); // Delete the invalid access rule. $this->drupalGet('/admin/people/access-policies/invalid_rules/handler/access_rule/field_text/remove'); $this->submitForm([], 'Remove'); $this->drupalGet('/admin/people/access-policies/invalid_rules'); $this->assertSession()->pageTextNotContains('Warning: invalid data detected'); } /** * Confirm that immutable operator access rules do not show the operator. */ public function testCreateAccessRuleWithImmutableOperator() { $field_storage = FieldStorageConfig::create([ 'field_name' => 'field_user', 'entity_type' => 'node', 'type' => 'entity_reference', 'cardinality' => -1, 'settings' => [ 'target_type' => 'user', ], ]); $field_storage->save(); $field = FieldConfig::create([ 'field_storage' => $field_storage, 'field_name' => 'field_user', 'bundle' => 'page', 'translatable' => FALSE, ]); $field->save(); $policy = AccessPolicy::create([ 'id' => 'basic_policy', 'label' => 'Basic policy', 'target_entity_type_id' => 'node', ]); $policy->save(); $access_rule = $this->accessRuleManager->getHandler('node', 'field_user_user_reference'); $policy->addHandler('access_rule', $access_rule); $policy->save(); $rid = $this->drupalCreateRole([ 'access administration pages', 'access content overview', 'administer access policy entities', ]); $web_user = $this->drupalCreateUser(); $web_user->addRole($rid); $web_user->save(); $this->drupalLogin($web_user); $this->drupalGet('/admin/people/access-policies/basic_policy'); $this->assertSession()->pageTextContains('field_user field has reference to current user'); $this->clickLink('Configure'); // Confirm that the operator field is not shown. $this->assertSession()->statusCodeEquals(200); $this->assertSession()->fieldNotExists('operator'); } /** * Tests the field access permission setting on selection rules. */ public function testCreateSelectionRuleWithFieldAccessPermission() { $policy = AccessPolicy::create([ 'id' => 'basic_policy', 'label' => 'Basic policy', 'target_entity_type_id' => 'node', 'weight' => -10, ]); $policy->save(); $selection_rule = $this->selectionRuleManager->getHandler('node', 'field_text'); $selection_rule->setSettings([ 'operator' => 'not empty', ]); $policy->addHandler('selection_rule', $selection_rule); $policy->save(); $rid = $this->drupalCreateRole([ 'access content', 'access administration pages', 'access content overview', 'edit any page content', 'create page content', 'administer access policy entities', 'assign basic_policy access policy', 'view basic_policy content', 'edit basic_policy content', ]); $admin_user = $this->drupalCreateUser(); $admin_user->addRole($rid); $admin_user->save(); $this->drupalLogin($admin_user); $this->drupalGet('/admin/people/access-policies/basic_policy/handler/selection_rule/field_text'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->pageTextContains('Field access'); $this->assertSession()->fieldExists('field_access[type]'); $edit = [ 'field_access[type]' => 'permission', 'field_access[permission]' => 'assign basic_policy access policy', ]; $this->submitForm($edit, 'Save'); // Make sure it saved properly. $this->drupalGet('/admin/people/access-policies/basic_policy/selection'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->pageTextContains('Text (not empty)'); $policy = $this->entityTypeManager->getStorage('access_policy')->load($policy->id()); $rules = $policy->getHandlers('selection_rule'); $rule_settings = $rules['field_text']['settings']; $this->assertEquals('permission', $rule_settings['field_access']['type']); $this->assertEquals('assign basic_policy access policy', $rule_settings['field_access']['permission']); // Assign the access policy to a node and edit it. Make sure that the field // is hidden. $node = $this->drupalCreateNode([ 'title' => 'Node', 'type' => 'page', 'status' => 1, ]); // Edit the node, confirm that they can see the field. $this->drupalGet('node/' . $node->id() . '/edit'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->fieldExists('field_text[0][value]'); // Create a new node. They should be able to see the field. $this->drupalGet('node/add/page'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->fieldExists('field_text[0][value]'); // This user can't assign the basic policy, therefore should not be able // to see the field. $web_user = $this->drupalCreateUser([ 'access content', 'access administration pages', 'access content overview', 'edit any page content', 'create page content', ]); $this->drupalLogin($web_user); // Edit the node, confirm that they can't see the field. $this->drupalGet('node/' . $node->id() . '/edit'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->fieldNotExists('field_text[0][value]'); // Create a new node. They should not be able to see the field. $this->drupalGet('node/add/page'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->fieldNotExists('field_text[0][value]'); // Create a new node that is assigned the Basic policy. Make sure that // It doesn't change the policy if another user without permission to // assign that policy edits it. $this->drupalLogin($admin_user); $node_2 = $this->drupalCreateNode([ 'title' => 'Node 2', 'type' => 'page', 'status' => 1, 'field_text' => 'Foo bar', ]); $node_2 = $this->drupalGetNodeByTitle($node_2->label()); $policy = $this->contentAccessPolicyManager->getAccessPolicy($node_2); $policy = reset($policy); $this->assertEquals('basic_policy', $policy->id()); // This user can edit Basic policy content node but can't assign the Basic // policy. Make sure that it doesn't reset the policy. $web_user = $this->drupalCreateUser([ 'access content', 'access administration pages', 'access content overview', 'edit any page content', 'create page content', 'edit basic_policy content', ]); $this->drupalLogin($web_user); $this->drupalGet('node/' . $node_2->id() . '/edit'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->fieldNotExists('field_text[0][value]'); // Save the node, make sure that it doesn't change the policy. $edit = [ 'title[0][value]' => 'Node 2', ]; $this->submitForm($edit, 'Save'); $this->entityTypeManager->getStorage('node')->resetCache(); $node = $this->drupalGetNodeByTitle('Node 2'); $policy = $this->contentAccessPolicyManager->getAccessPolicy($node); $policy = reset($policy); $this->assertEquals('basic_policy', $policy->id(), 'This policy is incorrect'); } /** * Tests viewing user profile with field observed by access rule. * * This tests multiple field types because some access rules use argument * settings to determine which field to observe. */ public function testCreateAccessRuleUserFieldPermissions() { // Create a list field for user and node. FieldStorageConfig::create([ 'field_name' => 'field_list_string', 'entity_type' => 'node', 'type' => 'list_string', 'cardinality' => 1, 'settings' => [ 'allowed_values' => [ 'foo' => 'Foo', 'bar' => 'Bar', ], ], ])->save(); FieldConfig::create([ 'field_name' => 'field_list_string', 'entity_type' => 'node', 'label' => 'Test options list field', 'bundle' => 'page', ])->save(); FieldStorageConfig::create([ 'field_name' => 'field_list_string', 'entity_type' => 'user', 'type' => 'list_string', 'cardinality' => 1, 'settings' => [ 'allowed_values' => [ 'foo' => 'Foo', 'bar' => 'Bar', ], ], ])->save(); FieldConfig::create([ 'field_name' => 'field_list_string', 'entity_type' => 'user', 'label' => 'Test options list field', 'bundle' => 'user', ])->save(); FieldStorageConfig::create([ 'field_name' => 'field_boolean', 'entity_type' => 'user', 'type' => 'boolean', ])->save(); FieldConfig::create([ 'field_name' => 'field_boolean', 'entity_type' => 'user', 'bundle' => 'user', 'label' => "boolean", 'required' => TRUE, 'settings' => [ 'on_label' => 'On', 'off_label' => 'Off', ], ])->save(); // Add the new field to the edit form. EntityFormDisplay::create([ 'targetEntityType' => 'user', 'bundle' => 'user', 'mode' => 'default', 'status' => TRUE, ]) ->setComponent('field_boolean', [ 'type' => 'boolean_checkbox', ]) ->setComponent('field_list_string', [ 'type' => 'options_select', ]) ->save(); $policy = AccessPolicy::create([ 'id' => 'basic_policy', 'label' => 'Basic policy', 'target_entity_type_id' => 'node', ]); $policy->save(); $access_rule = $this->accessRuleManager->getHandler('user', 'field_boolean'); $policy->addHandler('access_rule', $access_rule); $access_rule = $this->accessRuleManager->getHandler('node', 'match_field_list_string'); $access_rule->setSettings([ 'operator' => 'in', 'value' => ['field' => 'field_list_string'], ]); $policy->addHandler('access_rule', $access_rule); $policy->save(); $web_user = $this->drupalCreateUser([ 'access administration pages', 'access content overview', 'administer access policy entities', ]); $this->drupalLogin($web_user); $this->drupalGet('/user/' . $web_user->id() . '/edit'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->fieldNotExists('field_list_string'); $this->assertSession()->fieldNotExists('field_boolean'); // Create a new user with the edit user information permission. $web_user = $this->drupalCreateUser([ 'access administration pages', 'access content overview', 'administer access policy entities', 'edit basic_policy user information', ]); $this->drupalLogin($web_user); $this->drupalGet('/user/' . $web_user->id() . '/edit'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->fieldExists('field_list_string'); $this->assertSession()->fieldNotExists('field_boolean'); } /** * Tests filtering the allowed values in list fields. * * This tests filtering on list fields when the "Filer allowed values" * checkbox is checked. This only filters results for list text fields * that are being compared with user fields. */ public function testFilterListFieldAllowedValues() { // Create a list field for user and node. FieldStorageConfig::create([ 'field_name' => 'field_list_string', 'entity_type' => 'node', 'type' => 'list_string', 'cardinality' => 1, 'settings' => [ 'allowed_values' => [ 'foo' => 'Foo', 'bar' => 'Bar', ], ], ])->save(); FieldConfig::create([ 'field_name' => 'field_list_string', 'entity_type' => 'node', 'label' => 'Test options list field', 'bundle' => 'page', ])->save(); FieldStorageConfig::create([ 'field_name' => 'field_list_string', 'entity_type' => 'user', 'type' => 'list_string', 'cardinality' => 1, 'settings' => [ 'allowed_values' => [ 'foo' => 'Foo', 'bar' => 'Bar', ], ], ])->save(); FieldConfig::create([ 'field_name' => 'field_list_string', 'entity_type' => 'user', 'label' => 'Test options list field', 'bundle' => 'user', ])->save(); $display = EntityFormDisplay::load('node.page.default'); $display->setComponent('field_list_string', [ 'type' => 'options_select', ]); $display->save(); $policy = AccessPolicy::create([ 'id' => 'basic_policy', 'label' => 'Basic policy', 'target_entity_type_id' => 'node', ]); $policy->save(); $access_rule = $this->accessRuleManager->getHandler('node', 'match_field_list_string'); $access_rule->setSettings([ 'operator' => 'in', 'value' => ['field' => 'field_list_string'], ]); $policy->addHandler('access_rule', $access_rule); $policy->save(); $permissions = [ 'access content', 'access administration pages', 'access content overview', 'edit any page content', 'create page content', ]; $web_user = $this->drupalCreateUser(array_merge($permissions, [ 'administer access policy entities', ])); $web_user->set('field_list_string', ['bar']); $web_user->save(); $this->drupalLogin($web_user); // Edit the access rule, confirm that the setting is visible. $this->drupalGet('/admin/people/access-policies/basic_policy/handler/access_rule/match_field_list_string'); $this->assertSession()->fieldExists('filter_allowed_values'); $this->assertSession()->checkboxNotChecked('filter_allowed_values'); $submit = [ 'filter_allowed_values' => 1, ]; $this->submitForm($submit, 'Save'); $this->drupalGet('/admin/people/access-policies/basic_policy/handler/access_rule/match_field_list_string'); $this->assertSession()->checkboxChecked('filter_allowed_values'); $node = $this->drupalCreateNode([ 'title' => 'Node 1', 'field_list_string' => 'bar', ]); // Log in as a user who doesn't have any values assigned to them. They // should not be able to choose an option. $web_user_2 = $this->drupalCreateUser($permissions); $this->drupalLogin($web_user_2); // Confirm that a new node does not show "bar". $this->drupalGet('/node/add/page'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->fieldExists('field_list_string'); $this->assertSession()->fieldEnabled('field_list_string'); $this->assertSession()->optionNotExists('field_list_string', 'foo'); $this->assertSession()->optionNotExists('field_list_string', 'bar'); // Log in as the other web user with a different list string value. $web_user_3 = $this->drupalCreateUser($permissions); $web_user_3->set('field_list_string', ['foo']); $web_user_3->save(); $this->drupalLogin($web_user_3); $this->drupalGet('/node/add/page'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->fieldExists('field_list_string'); $this->assertSession()->fieldEnabled('field_list_string'); $this->assertSession()->optionExists('field_list_string', 'foo'); $this->assertSession()->optionNotExists('field_list_string', 'bar'); // Edit the existing node, confirm that the value is still there and that // the field is disabled. $this->drupalGet('node/' . $node->id() . '/edit'); $this->assertSession()->fieldExists('field_list_string'); $this->assertSession()->fieldDisabled('field_list_string'); $this->assertSession()->fieldValueEquals('field_list_string', 'bar'); // Log in as a user with bypass access rules permission and doesn't have any // values assigned for field_list_string. The field should still be enabled. $admin_user = $this->drupalCreateUser(array_merge($permissions, [ 'bypass basic_policy access rules', ])); $this->drupalLogin($admin_user); $this->drupalGet('node/' . $node->id() . '/edit'); $this->assertSession()->fieldExists('field_list_string'); $this->assertSession()->fieldEnabled('field_list_string'); $this->assertSession()->fieldValueEquals('field_list_string', 'bar'); } }