/** * Tests comment approval functionality through the node interface. */ function testApprovalNodeInterface() { // Set anonymous comments to require approval. user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array('access comments' => TRUE, 'post comments' => TRUE, 'skip comment approval' => FALSE)); $this->drupalLogin($this->admin_user); $this->setCommentAnonymous('0'); // Ensure that doesn't require contact info. $this->drupalLogout(); // Post anonymous comment without contact info. $subject = $this->randomMachineName(); $body = $this->randomMachineName(); $this->postComment($this->node, $body, $subject, TRUE); // Set $contact to true so that it won't check for id and message. $this->assertText(t('Your comment has been queued for review by site administrators and will be published after approval.'), 'Comment requires approval.'); // Get unapproved comment id. $this->drupalLogin($this->admin_user); $anonymous_comment4 = $this->getUnapprovedComment($subject); $anonymous_comment4 = entity_create('comment', array('cid' => $anonymous_comment4, 'subject' => $subject, 'comment_body' => $body, 'entity_id' => $this->node->id(), 'entity_type' => 'node', 'field_name' => 'comment')); $this->drupalLogout(); $this->assertFalse($this->commentExists($anonymous_comment4), 'Anonymous comment was not published.'); // Approve comment. $this->drupalLogin($this->admin_user); $this->drupalGet('comment/1/approve'); $this->assertResponse(403, 'Forged comment approval was denied.'); $this->drupalGet('comment/1/approve', array('query' => array('token' => 'forged'))); $this->assertResponse(403, 'Forged comment approval was denied.'); $this->drupalGet('comment/1/edit'); $this->assertFieldChecked('edit-status-0'); $this->drupalGet('node/' . $this->node->id()); $this->clickLink(t('Approve')); $this->drupalLogout(); $this->drupalGet('node/' . $this->node->id()); $this->assertTrue($this->commentExists($anonymous_comment4), 'Anonymous comment visible.'); }
/** * Tests responsive image formatters on node display for private files. */ public function testResponsiveImageFieldFormattersPrivate() { $this->addTestImageStyleMappings(); // Remove access content permission from anonymous users. user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array('access content' => FALSE)); $this->doTestResponsiveImageFieldFormatters('private'); }
/** * Tests the node comment statistics. */ function testCommentNodeCommentStatistics() { $node_storage = $this->container->get('entity.manager')->getStorage('node'); // Set comments to have subject and preview disabled. $this->drupalLogin($this->adminUser); $this->setCommentPreview(DRUPAL_DISABLED); $this->setCommentForm(TRUE); $this->setCommentSubject(FALSE); $this->setCommentSettings('default_mode', CommentManagerInterface::COMMENT_MODE_THREADED, 'Comment paging changed.'); $this->drupalLogout(); // Checks the initial values of node comment statistics with no comment. $node = $node_storage->load($this->node->id()); $this->assertEqual($node->get('comment')->last_comment_timestamp, $this->node->getCreatedTime(), 'The initial value of node last_comment_timestamp is the node created date.'); $this->assertEqual($node->get('comment')->last_comment_name, NULL, 'The initial value of node last_comment_name is NULL.'); $this->assertEqual($node->get('comment')->last_comment_uid, $this->webUser->id(), 'The initial value of node last_comment_uid is the node uid.'); $this->assertEqual($node->get('comment')->comment_count, 0, 'The initial value of node comment_count is zero.'); // Post comment #1 as web_user2. $this->drupalLogin($this->webUser2); $comment_text = $this->randomMachineName(); $this->postComment($this->node, $comment_text); // Checks the new values of node comment statistics with comment #1. // The node cache needs to be reset before reload. $node_storage->resetCache(array($this->node->id())); $node = $node_storage->load($this->node->id()); $this->assertEqual($node->get('comment')->last_comment_name, NULL, 'The value of node last_comment_name is NULL.'); $this->assertEqual($node->get('comment')->last_comment_uid, $this->webUser2->id(), 'The value of node last_comment_uid is the comment #1 uid.'); $this->assertEqual($node->get('comment')->comment_count, 1, 'The value of node comment_count is 1.'); // Prepare for anonymous comment submission (comment approval enabled). $this->drupalLogin($this->adminUser); user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array('access comments' => TRUE, 'post comments' => TRUE, 'skip comment approval' => FALSE)); // Ensure that the poster can leave some contact info. $this->setCommentAnonymous('1'); $this->drupalLogout(); // Post comment #2 as anonymous (comment approval enabled). $this->drupalGet('comment/reply/node/' . $this->node->id() . '/comment'); $anonymous_comment = $this->postComment($this->node, $this->randomMachineName(), '', TRUE); // Checks the new values of node comment statistics with comment #2 and // ensure they haven't changed since the comment has not been moderated. // The node needs to be reloaded with the cache reset. $node_storage->resetCache(array($this->node->id())); $node = $node_storage->load($this->node->id()); $this->assertEqual($node->get('comment')->last_comment_name, NULL, 'The value of node last_comment_name is still NULL.'); $this->assertEqual($node->get('comment')->last_comment_uid, $this->webUser2->id(), 'The value of node last_comment_uid is still the comment #1 uid.'); $this->assertEqual($node->get('comment')->comment_count, 1, 'The value of node comment_count is still 1.'); // Prepare for anonymous comment submission (no approval required). $this->drupalLogin($this->adminUser); user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array('access comments' => TRUE, 'post comments' => TRUE, 'skip comment approval' => TRUE)); $this->drupalLogout(); // Post comment #3 as anonymous. $this->drupalGet('comment/reply/node/' . $this->node->id() . '/comment'); $anonymous_comment = $this->postComment($this->node, $this->randomMachineName(), '', array('name' => $this->randomMachineName())); $comment_loaded = Comment::load($anonymous_comment->id()); // Checks the new values of node comment statistics with comment #3. // The node needs to be reloaded with the cache reset. $node_storage->resetCache(array($this->node->id())); $node = $node_storage->load($this->node->id()); $this->assertEqual($node->get('comment')->last_comment_name, $comment_loaded->getAuthorName(), 'The value of node last_comment_name is the name of the anonymous user.'); $this->assertEqual($node->get('comment')->last_comment_uid, 0, 'The value of node last_comment_uid is zero.'); $this->assertEqual($node->get('comment')->comment_count, 2, 'The value of node comment_count is 2.'); }
public function setUp() { parent::setUp(); // Enables anonymous user comments. user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array('access comments' => TRUE, 'post comments' => TRUE, 'skip comment approval' => TRUE)); // Allows anonymous to leave their contact information. $this->setCommentAnonymous(COMMENT_ANONYMOUS_MAY_CONTACT); $this->setCommentPreview(DRUPAL_OPTIONAL); $this->setCommentForm(TRUE); $this->setCommentSubject(TRUE); $this->setCommentSettings('comment_default_mode', CommentManagerInterface::COMMENT_MODE_THREADED, 'Comment paging changed.'); // Prepares commonly used URIs. $this->base_uri = url('<front>', array('absolute' => TRUE)); $this->node_uri = url('node/' . $this->node->id(), array('absolute' => TRUE)); // Set relation between node and comment. $article_mapping = rdf_get_mapping('node', 'article'); $comment_count_mapping = array('properties' => array('sioc:num_replies'), 'datatype' => 'xsd:integer', 'datatype_callback' => array('callable' => 'Drupal\\rdf\\CommonDataConverter::rawValue')); $article_mapping->setFieldMapping('comment_count', $comment_count_mapping)->save(); // Save user mapping. $user_mapping = rdf_get_mapping('user', 'user'); $username_mapping = array('properties' => array('foaf:name')); $user_mapping->setFieldMapping('name', $username_mapping)->save(); $user_mapping->setFieldMapping('homepage', array('properties' => array('foaf:page'), 'mapping_type' => 'rel'))->save(); // Save comment mapping. $mapping = rdf_get_mapping('comment', 'comment'); $mapping->setBundleMapping(array('types' => array('sioc:Post', 'sioct:Comment')))->save(); $field_mappings = array('subject' => array('properties' => array('dc:title')), 'created' => array('properties' => array('dc:date', 'dc:created'), 'datatype' => 'xsd:dateTime', 'datatype_callback' => array('callable' => 'date_iso8601')), 'changed' => array('properties' => array('dc:modified'), 'datatype' => 'xsd:dateTime', 'datatype_callback' => array('callable' => 'date_iso8601')), 'comment_body' => array('properties' => array('content:encoded')), 'pid' => array('properties' => array('sioc:reply_of'), 'mapping_type' => 'rel'), 'uid' => array('properties' => array('sioc:has_creator'), 'mapping_type' => 'rel'), 'name' => array('properties' => array('foaf:name'))); // Iterate over shared field mappings and save. foreach ($field_mappings as $field_name => $field_mapping) { $mapping->setFieldMapping($field_name, $field_mapping)->save(); } }
/** * Tests that comment links are output and can be hidden. */ public function testCommentLinks() { // Bartik theme alters comment links, so use a different theme. \Drupal::service('theme_handler')->install(array('stark')); \Drupal::config('system.theme')->set('default', 'stark')->save(); // Remove additional user permissions from $this->web_user added by setUp(), // since this test is limited to anonymous and authenticated roles only. $roles = $this->web_user->getRoles(); entity_delete_multiple('user_role', array(reset($roles))); // Create a comment via CRUD API functionality, since // $this->postComment() relies on actual user permissions. $comment = entity_create('comment', array('cid' => NULL, 'entity_id' => $this->node->id(), 'entity_type' => 'node', 'field_name' => 'comment', 'pid' => 0, 'uid' => 0, 'status' => CommentInterface::PUBLISHED, 'subject' => $this->randomMachineName(), 'hostname' => '127.0.0.1', 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, 'comment_body' => array(LanguageInterface::LANGCODE_NOT_SPECIFIED => array($this->randomMachineName())))); $comment->save(); $this->comment = $comment; // Change comment settings. $this->setCommentSettings('form_location', CommentItemInterface::FORM_BELOW, 'Set comment form location'); $this->setCommentAnonymous(TRUE); $this->node->comment = CommentItemInterface::OPEN; $this->node->save(); // Change user permissions. $perms = array('access comments' => 1, 'post comments' => 1, 'skip comment approval' => 1, 'edit own comments' => 1); user_role_change_permissions(DRUPAL_ANONYMOUS_RID, $perms); $nid = $this->node->id(); // Assert basic link is output, actual functionality is unit-tested in // \Drupal\comment\Tests\CommentLinkBuilderTest. foreach (array('node', "node/{$nid}") as $path) { $this->drupalGet($path); // In teaser view, a link containing the comment count is always // expected. if ($path == 'node') { $this->assertLink(t('1 comment')); } $this->assertLink('Add new comment'); } // Make sure we can hide node links. entity_get_display('node', $this->node->bundle(), 'default')->removeComponent('links')->save(); $this->drupalGet($this->node->url()); $this->assertNoLink('1 comment'); $this->assertNoLink('Add new comment'); // Visit the full node, make sure there are links for the comment. $this->drupalGet('node/' . $this->node->id()); $this->assertText($comment->getSubject()); $this->assertLink('Reply'); // Make sure we can hide comment links. entity_get_display('comment', 'comment', 'default')->removeComponent('links')->save(); $this->drupalGet('node/' . $this->node->id()); $this->assertText($comment->getSubject()); $this->assertNoLink('Reply'); }
/** * Tests authorization. */ public function testAuthorize() { // Create a user with limited permissions. We can't use // $this->drupalCreateUser here because we need to to set a specific user // name. $edit = array('name' => 'Poor user', 'mail' => '*****@*****.**', 'pass' => user_password(), 'status' => 1); $account = user_save(drupal_anonymous_user(), $edit); // // Adding a mapping to the user_name will invoke authorization. $this->addMappings('comment', array(5 => array('source' => 'mail', 'target' => 'user_mail'))); $url = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds_comment_processor') . '/tests/test.csv'; $nid = $this->createFeedNode('comment', $url, 'Comment test'); $this->assertText('Failed importing 1 comment'); $this->assertText('User ' . $account->name . ' is not permitted to post comments.'); $this->assertEqual(0, db_query("SELECT COUNT(*) FROM {comment}")->fetchField()); user_role_change_permissions(2, array('post comments' => TRUE)); $this->drupalPost("node/{$nid}/import", array(), 'Import'); $this->assertText('Created 1 comment.'); $this->assertEqual(1, db_query("SELECT COUNT(*) FROM {comment}")->fetchField()); $comment = comment_load(1); $this->assertEqual(0, $comment->status); }
/** * Tests anonymous comment functionality. */ function testCommentFunctionality() { $limited_user = $this->drupalCreateUser(array('administer entity_test fields')); $this->drupalLogin($limited_user); // Test that default field exists. $this->drupalGet('entity_test/structure/entity_test/fields'); $this->assertText(t('Comments')); $this->assertLinkByHref('entity_test/structure/entity_test/fields/entity_test.entity_test.comment'); // Test widget hidden option is not visible when there's no comments. $this->drupalGet('entity_test/structure/entity_test/fields/entity_test.entity_test.comment'); $this->assertResponse(200); $this->assertNoField('edit-default-value-input-comment-und-0-status-0'); // Test that field to change cardinality is not available. $this->drupalGet('entity_test/structure/entity_test/fields/entity_test.entity_test.comment/storage'); $this->assertResponse(200); $this->assertNoField('cardinality_number'); $this->assertNoField('cardinality'); $this->drupalLogin($this->adminUser); // Test breadcrumb on comment add page. $this->drupalGet('comment/reply/entity_test/' . $this->entity->id() . '/comment'); $xpath = '//nav[@class="breadcrumb"]/ol/li[last()]/a'; $this->assertEqual(current($this->xpath($xpath)), $this->entity->label(), 'Last breadcrumb item is equal to node title on comment reply page.'); // Post a comment. /** @var \Drupal\comment\CommentInterface $comment1 */ $comment1 = $this->postComment($this->entity, $this->randomMachineName(), $this->randomMachineName()); $this->assertTrue($this->commentExists($comment1), 'Comment on test entity exists.'); // Test breadcrumb on comment reply page. $this->drupalGet('comment/reply/entity_test/' . $this->entity->id() . '/comment/' . $comment1->id()); $xpath = '//nav[@class="breadcrumb"]/ol/li[last()]/a'; $this->assertEqual(current($this->xpath($xpath)), $comment1->getSubject(), 'Last breadcrumb item is equal to comment title on comment reply page.'); // Test breadcrumb on comment edit page. $this->drupalGet('comment/' . $comment1->id() . '/edit'); $xpath = '//nav[@class="breadcrumb"]/ol/li[last()]/a'; $this->assertEqual(current($this->xpath($xpath)), $comment1->getSubject(), 'Last breadcrumb item is equal to comment subject on edit page.'); // Test breadcrumb on comment delete page. $this->drupalGet('comment/' . $comment1->id() . '/delete'); $xpath = '//nav[@class="breadcrumb"]/ol/li[last()]/a'; $this->assertEqual(current($this->xpath($xpath)), $comment1->getSubject(), 'Last breadcrumb item is equal to comment subject on delete confirm page.'); // Unpublish the comment. $this->performCommentOperation($comment1, 'unpublish'); $this->drupalGet('admin/content/comment/approval'); $this->assertRaw('comments[' . $comment1->id() . ']', 'Comment was unpublished.'); // Publish the comment. $this->performCommentOperation($comment1, 'publish', TRUE); $this->drupalGet('admin/content/comment'); $this->assertRaw('comments[' . $comment1->id() . ']', 'Comment was published.'); // Delete the comment. $this->performCommentOperation($comment1, 'delete'); $this->drupalGet('admin/content/comment'); $this->assertNoRaw('comments[' . $comment1->id() . ']', 'Comment was deleted.'); // Post another comment. $comment1 = $this->postComment($this->entity, $this->randomMachineName(), $this->randomMachineName()); $this->assertTrue($this->commentExists($comment1), 'Comment on test entity exists.'); // Check that the comment was found. $this->drupalGet('admin/content/comment'); $this->assertRaw('comments[' . $comment1->id() . ']', 'Comment was published.'); // Check that entity access applies to administrative page. $this->assertText($this->entity->label(), 'Name of commented account found.'); $limited_user = $this->drupalCreateUser(array('administer comments')); $this->drupalLogin($limited_user); $this->drupalGet('admin/content/comment'); $this->assertNoText($this->entity->label(), 'No commented account name found.'); $this->drupalLogout(); // Deny anonymous users access to comments. user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array('access comments' => FALSE, 'post comments' => FALSE, 'skip comment approval' => FALSE, 'view test entity' => TRUE)); // Attempt to view comments while disallowed. $this->drupalGet('entity-test/' . $this->entity->id()); $this->assertNoPattern('@<h2[^>]*>Comments</h2>@', 'Comments were not displayed.'); $this->assertNoLink('Add new comment', 'Link to add comment was found.'); // Attempt to view test entity comment form while disallowed. $this->drupalGet('comment/reply/entity_test/' . $this->entity->id() . '/comment'); $this->assertResponse(403); $this->assertNoFieldByName('subject[0][value]', '', 'Subject field not found.'); $this->assertNoFieldByName('comment_body[0][value]', '', 'Comment field not found.'); user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array('access comments' => TRUE, 'post comments' => FALSE, 'view test entity' => TRUE, 'skip comment approval' => FALSE)); $this->drupalGet('entity_test/' . $this->entity->id()); $this->assertPattern('@<h2[^>]*>Comments</h2>@', 'Comments were displayed.'); $this->assertLink('Log in', 0, 'Link to log in was found.'); $this->assertLink('register', 0, 'Link to register was found.'); $this->assertNoFieldByName('subject[0][value]', '', 'Subject field not found.'); $this->assertNoFieldByName('comment_body[0][value]', '', 'Comment field not found.'); // Test the combination of anonymous users being able to post, but not view // comments, to ensure that access to post comments doesn't grant access to // view them. user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array('access comments' => FALSE, 'post comments' => TRUE, 'skip comment approval' => TRUE, 'view test entity' => TRUE)); $this->drupalGet('entity_test/' . $this->entity->id()); $this->assertNoPattern('@<h2[^>]*>Comments</h2>@', 'Comments were not displayed.'); $this->assertFieldByName('subject[0][value]', '', 'Subject field found.'); $this->assertFieldByName('comment_body[0][value]', '', 'Comment field found.'); $this->drupalGet('comment/reply/entity_test/' . $this->entity->id() . '/comment/' . $comment1->id()); $this->assertResponse(403); $this->assertNoText($comment1->getSubject(), 'Comment not displayed.'); // Test comment field widget changes. $limited_user = $this->drupalCreateUser(array('administer entity_test fields', 'view test entity', 'administer entity_test content')); $this->drupalLogin($limited_user); $this->drupalGet('entity_test/structure/entity_test/fields/entity_test.entity_test.comment'); $this->assertNoFieldChecked('edit-default-value-input-comment-0-status-0'); $this->assertNoFieldChecked('edit-default-value-input-comment-0-status-1'); $this->assertFieldChecked('edit-default-value-input-comment-0-status-2'); // Test comment option change in field settings. $edit = array('default_value_input[comment][0][status]' => CommentItemInterface::CLOSED, 'settings[anonymous]' => COMMENT_ANONYMOUS_MAY_CONTACT); $this->drupalPostForm(NULL, $edit, t('Save settings')); $this->drupalGet('entity_test/structure/entity_test/fields/entity_test.entity_test.comment'); $this->assertNoFieldChecked('edit-default-value-input-comment-0-status-0'); $this->assertFieldChecked('edit-default-value-input-comment-0-status-1'); $this->assertNoFieldChecked('edit-default-value-input-comment-0-status-2'); $this->assertFieldByName('settings[anonymous]', COMMENT_ANONYMOUS_MAY_CONTACT); // Add a new comment-type. $bundle = CommentType::create(array('id' => 'foobar', 'label' => 'Foobar', 'description' => '', 'target_entity_type_id' => 'entity_test')); $bundle->save(); // Add a new comment field. $storage_edit = array('settings[comment_type]' => 'foobar'); $this->fieldUIAddNewField('entity_test/structure/entity_test', 'foobar', 'Foobar', 'comment', $storage_edit); // Add a third comment field. $this->fieldUIAddNewField('entity_test/structure/entity_test', 'barfoo', 'BarFoo', 'comment', $storage_edit); // Check the field contains the correct comment type. $field_storage = FieldStorageConfig::load('entity_test.field_barfoo'); $this->assertTrue($field_storage); $this->assertEqual($field_storage->getSetting('comment_type'), 'foobar'); $this->assertEqual($field_storage->getCardinality(), 1); // Test the new entity commenting inherits default. $random_label = $this->randomMachineName(); $data = array('bundle' => 'entity_test', 'name' => $random_label); $new_entity = entity_create('entity_test', $data); $new_entity->save(); $this->drupalGet('entity_test/manage/' . $new_entity->id()); $this->assertNoFieldChecked('edit-field-foobar-0-status-1'); $this->assertFieldChecked('edit-field-foobar-0-status-2'); $this->assertNoField('edit-field-foobar-0-status-0'); // @todo Check proper url and form https://www.drupal.org/node/2458323 $this->drupalGet('comment/reply/entity_test/comment/' . $new_entity->id()); $this->assertNoFieldByName('subject[0][value]', '', 'Subject field found.'); $this->assertNoFieldByName('comment_body[0][value]', '', 'Comment field found.'); // Test removal of comment_body field. $limited_user = $this->drupalCreateUser(array('administer entity_test fields', 'post comments', 'administer comment fields', 'administer comment types')); $this->drupalLogin($limited_user); $this->drupalGet('comment/reply/entity_test/' . $this->entity->id() . '/comment'); $this->assertFieldByName('comment_body[0][value]', '', 'Comment body field found.'); $this->fieldUIDeleteField('admin/structure/comment/manage/comment', 'comment.comment.comment_body', 'Comment', 'Comment settings'); $this->drupalGet('comment/reply/entity_test/' . $this->entity->id() . '/comment'); $this->assertNoFieldByName('comment_body[0][value]', '', 'Comment body field not found.'); // Set subject field to autogenerate it. $edit = ['subject[0][value]' => '']; $this->drupalPostForm(NULL, $edit, t('Save')); }
/** * Re-configures the environment, module settings, and user permissions. * * @param $info * An associative array describing the environment to setup: * - Environment conditions: * - authenticated: Boolean whether to test with $this->web_user or * anonymous. * - comment count: Boolean whether to test with a new/unread comment on * $this->node or no comments. * - Configuration settings: * - form: COMMENT_FORM_BELOW or COMMENT_FORM_SEPARATE_PAGE. * - user_register: USER_REGISTER_ADMINISTRATORS_ONLY or * USER_REGISTER_VISITORS. * - contact: COMMENT_ANONYMOUS_MAY_CONTACT or * COMMENT_ANONYMOUS_MAYNOT_CONTACT. * - comments: CommentItemInterface::OPEN, CommentItemInterface::CLOSED or * CommentItemInterface::HIDDEN. * - User permissions: * These are granted or revoked for the user, according to the * 'authenticated' flag above. Pass 0 or 1 as parameter values. See * user_role_change_permissions(). * - access comments * - post comments * - skip comment approval * - edit own comments */ function setEnvironment(array $info) { static $current; // Apply defaults to initial environment. if (!isset($current)) { $current = array('authenticated' => FALSE, 'comment count' => FALSE, 'form' => COMMENT_FORM_BELOW, 'user_register' => USER_REGISTER_VISITORS, 'contact' => COMMENT_ANONYMOUS_MAY_CONTACT, 'comments' => CommentItemInterface::OPEN, 'access comments' => 0, 'post comments' => 0, 'skip comment approval' => 1, 'edit own comments' => 0); } // Complete new environment with current environment. $info = array_merge($current, $info); // Change environment conditions. if ($current['authenticated'] != $info['authenticated']) { if ($this->loggedInUser) { $this->drupalLogout(); } else { $this->drupalLogin($this->web_user); } } if ($current['comment count'] != $info['comment count']) { if ($info['comment count']) { // Create a comment via CRUD API functionality, since // $this->postComment() relies on actual user permissions. $comment = entity_create('comment', array('cid' => NULL, 'entity_id' => $this->node->id(), 'entity_type' => 'node', 'field_name' => 'comment', 'pid' => 0, 'uid' => 0, 'status' => CommentInterface::PUBLISHED, 'subject' => $this->randomMachineName(), 'hostname' => '127.0.0.1', 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, 'comment_body' => array(LanguageInterface::LANGCODE_NOT_SPECIFIED => array($this->randomMachineName())))); $comment->save(); $this->comment = $comment; } else { $cids = db_query("SELECT cid FROM {comment}")->fetchCol(); entity_delete_multiple('comment', $cids); unset($this->comment); } } // Change comment settings. $this->setCommentSettings('form_location', $info['form'], 'Set comment form location'); $this->setCommentAnonymous($info['contact']); if ($this->node->comment->status != $info['comments']) { $this->node->comment = $info['comments']; $this->node->save(); } // Change user settings. \Drupal::config('user.settings')->set('register', $info['user_register'])->save(); // Change user permissions. $rid = $this->loggedInUser ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID; $perms = array_intersect_key($info, array('access comments' => 1, 'post comments' => 1, 'skip comment approval' => 1, 'edit own comments' => 1)); user_role_change_permissions($rid, $perms); // Output verbose debugging information. // @see \Drupal\simpletest\TestBase::error() $t_form = array(COMMENT_FORM_BELOW => 'below', COMMENT_FORM_SEPARATE_PAGE => 'separate page'); $t_contact = array(COMMENT_ANONYMOUS_MAY_CONTACT => 'optional', COMMENT_ANONYMOUS_MAYNOT_CONTACT => 'disabled', COMMENT_ANONYMOUS_MUST_CONTACT => 'required'); $t_comments = array(CommentItemInterface::OPEN => 'open', CommentItemInterface::CLOSED => 'closed', CommentItemInterface::HIDDEN => 'hidden'); $verbose = $info; $verbose['form'] = $t_form[$info['form']]; $verbose['contact'] = $t_contact[$info['contact']]; $verbose['comments'] = $t_comments[$info['comments']]; $message = t('Changed environment:<pre>@verbose</pre>', array('@verbose' => var_export($verbose, TRUE))); $this->assert('debug', $message, 'Debug'); // Update current environment. $current = $info; return $info; }
/** * {@inheritdoc} */ public function postSave(EntityStorageInterface $storage_controller, $update = TRUE) { parent::postSave($storage_controller, $update); // Set bypass permissions. $roles = $this->getBypassRoles(); $permission = $this->getPermissionName(); if ($roles && $permission) { foreach (user_roles() as $rid => $name) { $enabled = in_array($rid, $roles, TRUE); user_role_change_permissions($rid, array($permission => $enabled)); } } }
/** * Set permissions for role. */ function setRolePermissions($rid, $access_comments = FALSE, $search_content = TRUE) { $permissions = array('access comments' => $access_comments, 'search content' => $search_content); user_role_change_permissions($rid, $permissions); }
/** * {@inheritdoc} */ public function postSave(EntityStorageInterface $storage, $update = TRUE) { parent::postSave($storage, $update); // Clear the static caches of filter_formats() and others. filter_formats_reset(); if (!$update && !$this->isSyncing()) { // Default configuration of modules and installation profiles is allowed // to specify a list of user roles to grant access to for the new format; // apply the defined user role permissions when a new format is inserted // and has a non-empty $roles property. // Note: user_role_change_permissions() triggers a call chain back into // \Drupal\filter\FilterPermissions::permissions() and lastly // filter_formats(), so its cache must be reset upfront. if (($roles = $this->get('roles')) && ($permission = $this->getPermissionName())) { foreach (user_roles() as $rid => $name) { $enabled = in_array($rid, $roles, TRUE); user_role_change_permissions($rid, array($permission => $enabled)); } } } }
/** * @see content_translation_translate_access() */ public function testContentTranslationOverviewAccess() { $access_control_handler = \Drupal::entityManager()->getAccessControlHandler('node'); $user = $this->createUser(['create content translations', 'access content']); $this->drupalLogin($user); $node = $this->drupalCreateNode(['status' => FALSE, 'type' => 'article']); $this->assertFalse(content_translation_translate_access($node)->isAllowed()); $access_control_handler->resetCache(); $node->setPublished(TRUE); $node->save(); $this->assertTrue(content_translation_translate_access($node)->isAllowed()); $access_control_handler->resetCache(); user_role_change_permissions(Role::AUTHENTICATED_ID, ['access content' => FALSE]); $user = $this->createUser(['create content translations']); $this->drupalLogin($user); $this->assertFalse(content_translation_translate_access($node)->isAllowed()); $access_control_handler->resetCache(); }
/** * Test image formatters on node display. */ function _testImageFieldFormatters($scheme) { /** @var \Drupal\Core\Render\RendererInterface $renderer */ $renderer = $this->container->get('renderer'); $node_storage = $this->container->get('entity.manager')->getStorage('node'); $field_name = strtolower($this->randomMachineName()); $field_settings = array('alt_field_required' => 0); $instance = $this->createImageField($field_name, 'article', array('uri_scheme' => $scheme), $field_settings); // Go to manage display page. $this->drupalGet("admin/structure/types/manage/article/display"); // Test for existence of link to image styles configuration. $this->drupalPostAjaxForm(NULL, array(), "{$field_name}_settings_edit"); $this->assertLinkByHref(\Drupal::url('entity.image_style.collection'), 0, 'Link to image styles configuration is found'); // Remove 'administer image styles' permission from testing admin user. $admin_user_roles = $this->adminUser->getRoles(TRUE); user_role_change_permissions(reset($admin_user_roles), array('administer image styles' => FALSE)); // Go to manage display page again. $this->drupalGet("admin/structure/types/manage/article/display"); // Test for absence of link to image styles configuration. $this->drupalPostAjaxForm(NULL, array(), "{$field_name}_settings_edit"); $this->assertNoLinkByHref(\Drupal::url('entity.image_style.collection'), 'Link to image styles configuration is absent when permissions are insufficient'); // Restore 'administer image styles' permission to testing admin user user_role_change_permissions(reset($admin_user_roles), array('administer image styles' => TRUE)); // Create a new node with an image attached. $test_image = current($this->drupalGetTestFiles('image')); // Ensure that preview works. $this->previewNodeImage($test_image, $field_name, 'article'); // After previewing, make the alt field required. It cannot be required // during preview because the form validation will fail. $instance->setSetting('alt_field_required', 1); $instance->save(); // Create alt text for the image. $alt = $this->randomMachineName(); // Save node. $nid = $this->uploadNodeImage($test_image, $field_name, 'article', $alt); $node_storage->resetCache(array($nid)); $node = $node_storage->load($nid); // Test that the default formatter is being used. $file = $node->{$field_name}->entity; $image_uri = $file->getFileUri(); $image = array('#theme' => 'image', '#uri' => $image_uri, '#width' => 40, '#height' => 20, '#alt' => $alt); $default_output = str_replace("\n", NULL, $renderer->renderRoot($image)); $this->assertRaw($default_output, 'Default formatter displaying correctly on full node view.'); // Test the image linked to file formatter. $display_options = array('type' => 'image', 'settings' => array('image_link' => 'file')); $display = entity_get_display('node', $node->getType(), 'default'); $display->setComponent($field_name, $display_options)->save(); $image = array('#theme' => 'image', '#uri' => $image_uri, '#width' => 40, '#height' => 20, '#alt' => $alt); $default_output = '<a href="' . file_create_url($image_uri) . '">' . $renderer->renderRoot($image) . '</a>'; $this->drupalGet('node/' . $nid); $this->assertCacheTag($file->getCacheTags()[0]); $cache_tags_header = $this->drupalGetHeader('X-Drupal-Cache-Tags'); $this->assertTrue(!preg_match('/ image_style\\:/', $cache_tags_header), 'No image style cache tag found.'); $this->assertRaw($default_output, 'Image linked to file formatter displaying correctly on full node view.'); // Verify that the image can be downloaded. $this->assertEqual(file_get_contents($test_image->uri), $this->drupalGet(file_create_url($image_uri)), 'File was downloaded successfully.'); if ($scheme == 'private') { // Only verify HTTP headers when using private scheme and the headers are // sent by Drupal. $this->assertEqual($this->drupalGetHeader('Content-Type'), 'image/png', 'Content-Type header was sent.'); $this->assertTrue(strstr($this->drupalGetHeader('Cache-Control'), 'private') !== FALSE, 'Cache-Control header was sent.'); // Log out and try to access the file. $this->drupalLogout(); $this->drupalGet(file_create_url($image_uri)); $this->assertResponse('403', 'Access denied to original image as anonymous user.'); // Log in again. $this->drupalLogin($this->adminUser); } // Test the image linked to content formatter. $display_options['settings']['image_link'] = 'content'; $display->setComponent($field_name, $display_options)->save(); $image = array('#theme' => 'image', '#uri' => $image_uri, '#width' => 40, '#height' => 20); $this->drupalGet('node/' . $nid); $this->assertCacheTag($file->getCacheTags()[0]); $cache_tags_header = $this->drupalGetHeader('X-Drupal-Cache-Tags'); $this->assertTrue(!preg_match('/ image_style\\:/', $cache_tags_header), 'No image style cache tag found.'); $elements = $this->xpath('//a[@href=:path]/img[@src=:url and @alt=:alt and @width=:width and @height=:height]', array(':path' => $node->url(), ':url' => file_create_url($image['#uri']), ':width' => $image['#width'], ':height' => $image['#height'], ':alt' => $alt)); $this->assertEqual(count($elements), 1, 'Image linked to content formatter displaying correctly on full node view.'); // Test the image style 'thumbnail' formatter. $display_options['settings']['image_link'] = ''; $display_options['settings']['image_style'] = 'thumbnail'; $display->setComponent($field_name, $display_options)->save(); // Ensure the derivative image is generated so we do not have to deal with // image style callback paths. $this->drupalGet(ImageStyle::load('thumbnail')->buildUrl($image_uri)); $image_style = array('#theme' => 'image_style', '#uri' => $image_uri, '#width' => 40, '#height' => 20, '#style_name' => 'thumbnail', '#alt' => $alt); $default_output = $renderer->renderRoot($image_style); $this->drupalGet('node/' . $nid); $image_style = ImageStyle::load('thumbnail'); $this->assertCacheTag($image_style->getCacheTags()[0]); $this->assertRaw($default_output, 'Image style thumbnail formatter displaying correctly on full node view.'); if ($scheme == 'private') { // Log out and try to access the file. $this->drupalLogout(); $this->drupalGet(ImageStyle::load('thumbnail')->buildUrl($image_uri)); $this->assertResponse('403', 'Access denied to image style thumbnail as anonymous user.'); } }
/** * Tests exploiting the temporary file removal for anonymous users using fid. */ public function testTemporaryFileRemovalExploitAnonymous() { // Set up an anonymous victim user. $victim_user = User::getAnonymousUser(); // Set up an anonymous attacker user. $attacker_user = User::getAnonymousUser(); // Set up permissions for anonymous attacker user. user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array('access content' => TRUE, 'create article content' => TRUE, 'edit any article content' => TRUE)); // Log out so as to be the anonymous attacker user. $this->drupalLogout(); // Perform tests using the newly set up anonymous users. $this->doTestTemporaryFileRemovalExploit($victim_user, $attacker_user); }
/** * Tests anonymous comment functionality. */ function testCommentFunctionality() { $limited_user = $this->drupalCreateUser(array('administer entity_test fields')); $this->drupalLogin($limited_user); // Test that default field exists. $this->drupalGet('entity_test/structure/entity_test/fields'); $this->assertText(t('Comment settings')); $this->assertLinkByHref('entity_test/structure/entity_test/fields/entity_test.entity_test.comment'); // Test widget hidden option is not visible when there's no comments. $this->drupalGet('entity_test/structure/entity_test/entity-test/fields/entity_test.entity_test.comment'); $this->assertNoField('edit-default-value-input-comment-und-0-status-0'); $this->drupalLogin($this->admin_user); // Post a comment. $comment1 = $this->postComment($this->entity, $this->randomName(), $this->randomName()); $this->assertTrue($this->commentExists($comment1), 'Comment on test entity exists.'); // Assert the breadcrumb is valid. $this->drupalGet('comment/reply/entity_test/' . $this->entity->id() . '/comment'); $this->assertLink($this->entity->label()); // Unpublish the comment. $this->performCommentOperation($comment1, 'unpublish'); $this->drupalGet('admin/content/comment/approval'); $this->assertRaw('comments[' . $comment1->id() . ']', 'Comment was unpublished.'); // Publish the comment. $this->performCommentOperation($comment1, 'publish', TRUE); $this->drupalGet('admin/content/comment'); $this->assertRaw('comments[' . $comment1->id() . ']', 'Comment was published.'); // Delete the comment. $this->performCommentOperation($comment1, 'delete'); $this->drupalGet('admin/content/comment'); $this->assertNoRaw('comments[' . $comment1->id() . ']', 'Comment was deleted.'); // Post another comment. $comment1 = $this->postComment($this->entity, $this->randomName(), $this->randomName()); $this->assertTrue($this->commentExists($comment1), 'Comment on test entity exists.'); // Check that the comment was found. $this->drupalGet('admin/content/comment'); $this->assertRaw('comments[' . $comment1->id() . ']', 'Comment was published.'); // Check that entity access applies to administrative page. $this->assertText($this->entity->label(), 'Name of commented account found.'); $limited_user = $this->drupalCreateUser(array('administer comments')); $this->drupalLogin($limited_user); $this->drupalGet('admin/content/comment'); $this->assertNoText($this->entity->label(), 'No commented account name found.'); $this->drupalLogout(); // Deny anonymous users access to comments. user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array('access comments' => FALSE, 'post comments' => FALSE, 'skip comment approval' => FALSE, 'view test entity' => TRUE)); // Attempt to view comments while disallowed. $this->drupalGet('entity-test/' . $this->entity->id()); $this->assertNoPattern('@<h2[^>]*>Comments</h2>@', 'Comments were not displayed.'); $this->assertNoLink('Add new comment', 'Link to add comment was found.'); // Attempt to view test entity comment form while disallowed. $this->drupalGet('comment/reply/entity_test/' . $this->entity->id() . '/comment'); $this->assertText('You are not authorized to post comments', 'Error attempting to post comment.'); $this->assertNoFieldByName('subject[0][value]', '', 'Subject field not found.'); $this->assertNoFieldByName('comment_body[0][value]', '', 'Comment field not found.'); user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array('access comments' => TRUE, 'post comments' => FALSE, 'view test entity' => TRUE, 'skip comment approval' => FALSE)); $this->drupalGet('entity_test/' . $this->entity->id()); $this->assertPattern('@<h2[^>]*>Comments</h2>@', 'Comments were displayed.'); $this->assertLink('Log in', 0, 'Link to log in was found.'); $this->assertLink('register', 0, 'Link to register was found.'); $this->assertNoFieldByName('subject[0][value]', '', 'Subject field not found.'); $this->assertNoFieldByName('comment_body[0][value]', '', 'Comment field not found.'); // Test the combination of anonymous users being able to post, but not view // comments, to ensure that access to post comments doesn't grant access to // view them. user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array('access comments' => FALSE, 'post comments' => TRUE, 'skip comment approval' => TRUE, 'view test entity' => TRUE)); $this->drupalGet('entity_test/' . $this->entity->id()); $this->assertNoPattern('@<h2[^>]*>Comments</h2>@', 'Comments were not displayed.'); $this->assertFieldByName('subject[0][value]', '', 'Subject field found.'); $this->assertFieldByName('comment_body[0][value]', '', 'Comment field found.'); $this->drupalGet('comment/reply/entity_test/' . $this->entity->id() . '/comment/' . $comment1->id()); $this->assertText('You are not authorized to view comments'); $this->assertNoText($comment1->getSubject(), 'Comment not displayed.'); // Test comment field widget changes. $limited_user = $this->drupalCreateUser(array('administer entity_test fields', 'view test entity', 'administer entity_test content')); $this->drupalLogin($limited_user); $this->drupalGet('entity_test/structure/entity_test/fields/entity_test.entity_test.comment'); $this->assertNoFieldChecked('edit-default-value-input-comment-0-status-0'); $this->assertNoFieldChecked('edit-default-value-input-comment-0-status-1'); $this->assertFieldChecked('edit-default-value-input-comment-0-status-2'); // Test comment option change in field settings. $edit = array('default_value_input[comment][0][status]' => CommentItemInterface::CLOSED); $this->drupalPostForm(NULL, $edit, t('Save settings')); $this->drupalGet('entity_test/structure/entity_test/fields/entity_test.entity_test.comment'); $this->assertNoFieldChecked('edit-default-value-input-comment-0-status-0'); $this->assertFieldChecked('edit-default-value-input-comment-0-status-1'); $this->assertNoFieldChecked('edit-default-value-input-comment-0-status-2'); // Add a new comment-type. $bundle = CommentType::create(array('id' => 'foobar', 'label' => 'Foobar', 'description' => '', 'target_entity_type_id' => 'entity_test')); $bundle->save(); // Add a new comment field. $this->drupalGet('entity_test/structure/entity_test/fields'); $edit = array('fields[_add_new_field][label]' => 'Foobar', 'fields[_add_new_field][field_name]' => 'foobar', 'fields[_add_new_field][type]' => 'comment'); $this->drupalPostForm(NULL, $edit, t('Save')); $this->drupalPostForm(NULL, array('field[settings][comment_type]' => 'foobar'), t('Save field settings')); $this->drupalPostForm(NULL, array(), t('Save settings')); $this->assertRaw(t('Saved %name configuration', array('%name' => 'Foobar'))); // Add a third comment field. $this->drupalGet('entity_test/structure/entity_test/fields'); $edit = array('fields[_add_new_field][label]' => 'Barfoo', 'fields[_add_new_field][field_name]' => 'barfoo', 'fields[_add_new_field][type]' => 'comment'); $this->drupalPostForm(NULL, $edit, t('Save')); // Re-use another comment type. $this->drupalPostForm(NULL, array('field[settings][comment_type]' => 'foobar'), t('Save field settings')); $this->drupalPostForm(NULL, array(), t('Save settings')); $this->assertRaw(t('Saved %name configuration', array('%name' => 'Barfoo'))); // Check the field contains the correct comment type. $field_storage = entity_load('field_storage_config', 'entity_test.field_barfoo'); $this->assertTrue($field_storage); $this->assertEqual($field_storage->getSetting('comment_type'), 'foobar'); // Test the new entity commenting inherits default. $random_label = $this->randomName(); $data = array('bundle' => 'entity_test', 'name' => $random_label); $new_entity = entity_create('entity_test', $data); $new_entity->save(); $this->drupalGet('entity_test/manage/' . $new_entity->id()); $this->assertNoFieldChecked('edit-field-foobar-0-status-1'); $this->assertFieldChecked('edit-field-foobar-0-status-2'); $this->assertNoField('edit-field-foobar-0-status-0'); $this->drupalGet('comment/reply/entity_test/comment/' . $new_entity->id()); $this->assertNoFieldByName('subject[0][value]', '', 'Subject field found.'); $this->assertNoFieldByName('comment_body[0][value]', '', 'Comment field found.'); }
/** * Implements Drupal\configuration\Config\Configuration::saveToActiveStore(). */ public function saveToActiveStore(ConfigIteratorSettings &$settings) { node_types_rebuild(); $exist = FALSE; $roles = static::get_roles(); $permissions_by_role = static::get_permissions(FALSE); $map = user_permission_get_modules(); $permission = $this->getData(); $perm = $permission['permission']; foreach ($roles as $role) { if (isset($map[$perm])) { $exist = TRUE; if (in_array($role, $permission['roles'])) { $permissions_by_role[$role][$perm] = TRUE; } else { $permissions_by_role[$role][$perm] = FALSE; } } } if (!$exist) { drupal_set_message(t('Configuration Management: Permission %permission does not exist and can not be set.', array('%permission' => $perm)), 'error'); } // Write the updated permissions. foreach ($roles as $rid => $role) { if (isset($permissions_by_role[$role])) { user_role_change_permissions($rid, $permissions_by_role[$role]); } } $settings->addInfo('imported', $this->getUniqueId()); }
/** * {@inheritdoc} */ public function save(array $form, FormStateInterface $form_state) { /** @var EFormType $type */ $type = $this->entity; $type->type = trim($type->id()); $type->name = trim($type->name); $status = $type->save(); foreach ($form_state->getValue('roles') as $rid => $enabled) { user_role_change_permissions($rid, array($type->getPermission() => $enabled)); } $context = array('%name' => $type->label()); if ($status == SAVED_UPDATED) { drupal_set_message($this->t('The EForm type %name has been updated.', $context)); } elseif ($status == SAVED_NEW) { drupal_set_message(t('The EForm type %name has been added.', $context)); $this->logger('eform')->notice('Added EForm type %name.', $context); } $form_state->setRedirectUrl($type->urlInfo('collection')); }
/** * Tests the ability to alter form actions. * * Uses the comment form, since it has an #action set. */ function _testFormAlter() { variable_set('securepages_switch', TRUE); // Enable anonymous user comments. user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array('access comments' => TRUE, 'post comments' => TRUE, 'skip comment approval' => TRUE)); $this->web_user = $this->drupalCreateUser(array('access comments', 'post comments', 'skip comment approval')); $node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1)); foreach (array('anonymous', 'authenticated') as $mode) { if ($mode == 'authenticated') { $this->drupalLogin($this->web_user); } // Test plain HTTP posting to HTTPS. variable_set('securepages_pages', "comment/reply/*\nuser*"); $this->drupalGet('node/' . $node->nid, array('https' => FALSE)); $this->assertFieldByXPath('//form[@class="comment-form" and starts-with(@action, "https:")]', NULL, "The {$mode} comment form action is https."); $this->drupalPost(NULL, array('comment_body[und][0][value]' => 'test comment'), t('Save')); $this->assertRaw(t('Your comment has been posted.')); // Test HTTPS posting to plain HTTP. variable_set('securepages_pages', "node/*\nuser*"); $this->drupalGet('node/' . $node->nid, array('https' => TRUE)); $this->assertUrl(url('node/' . $node->nid, array('https' => TRUE, 'absolute' => TRUE))); $this->assertFieldByXPath('//form[@class="comment-form" and starts-with(@action, "http:")]', NULL, "The {$mode} comment form action is http."); $this->drupalPost(NULL, array('comment_body[und][0][value]' => 'test'), t('Save')); $this->assertRaw(t('Your comment has been posted.')); } $this->drupalLogout(); // Test the user login block. $this->drupalGet(''); $edit = array('name' => $this->web_user->name, 'pass' => $this->web_user->pass_raw); $this->drupalPost(NULL, $edit, t('Log in')); $this->drupalGet('user/' . $this->web_user->uid . '/edit'); $this->assertResponse(200); // Clean up $this->drupalLogout(); variable_del('securepages_pages'); variable_del('securepages_switch'); }
/** * Test responsive image formatters on node display for private files. */ public function testResponsiveImageFieldFormattersPrivate() { // Remove access content permission from anonymous users. user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array('access content' => FALSE)); $this->_testResponsiveImageFieldFormatters('private'); }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { parent::submitForm($form, $form_state); // Add the submitted form values to the text format, and save it. $format = $this->entity; foreach ($form_state->getValues() as $key => $value) { if ($key != 'filters') { $format->set($key, $value); } else { foreach ($value as $instance_id => $config) { $format->setFilterConfig($instance_id, $config); } } } $format->save(); // Save user permissions. if ($permission = $format->getPermissionName()) { foreach ($form_state->getValue('roles') as $rid => $enabled) { user_role_change_permissions($rid, array($permission => $enabled)); } } $form_state->setRedirect('filter.admin_overview'); return $this->entity; }
/** * {@inheritdoc} */ public static function participateUserRoles(Workflow $workflow) { $type_id = $workflow->id(); foreach (user_roles() as $rid => $role) { $perms = array("create {$type_id} workflow_transition" => 1); user_role_change_permissions($rid, $perms); // <=== Enable Roles. } }
/** * {@inheritdoc} */ function submitForm(array &$form, array &$form_state) { foreach ($form_state['values']['role_names'] as $role_name => $name) { user_role_change_permissions($role_name, $form_state['values'][$role_name]); } drupal_set_message($this->t('The changes have been saved.')); }
/** * {@inheritdoc} */ function submitForm(array &$form, FormStateInterface $form_state) { foreach ($form_state->getValue('role_names') as $role_name => $name) { user_role_change_permissions($role_name, (array) $form_state->getValue($role_name)); } drupal_set_message($this->t('The changes have been saved.')); }
/** * Tests anonymous comment functionality. */ function testAnonymous() { $this->drupalLogin($this->adminUser); $this->setCommentAnonymous(COMMENT_ANONYMOUS_MAYNOT_CONTACT); $this->drupalLogout(); // Post anonymous comment without contact info. $anonymous_comment1 = $this->postComment($this->node, $this->randomMachineName(), $this->randomMachineName()); $this->assertTrue($this->commentExists($anonymous_comment1), 'Anonymous comment without contact info found.'); // Allow contact info. $this->drupalLogin($this->adminUser); $this->setCommentAnonymous(COMMENT_ANONYMOUS_MAY_CONTACT); // Attempt to edit anonymous comment. $this->drupalGet('comment/' . $anonymous_comment1->id() . '/edit'); $edited_comment = $this->postComment(NULL, $this->randomMachineName(), $this->randomMachineName()); $this->assertTrue($this->commentExists($edited_comment, FALSE), 'Modified reply found.'); $this->drupalLogout(); // Post anonymous comment with contact info (optional). $this->drupalGet('comment/reply/node/' . $this->node->id() . '/comment'); $this->assertTrue($this->commentContactInfoAvailable(), 'Contact information available.'); // Check the presence of expected cache tags. $this->assertCacheTag('config:field.field.node.article.comment'); $this->assertCacheTag('config:user.settings'); $anonymous_comment2 = $this->postComment($this->node, $this->randomMachineName(), $this->randomMachineName()); $this->assertTrue($this->commentExists($anonymous_comment2), 'Anonymous comment with contact info (optional) found.'); // Ensure anonymous users cannot post in the name of registered users. $edit = array('name' => $this->adminUser->getUsername(), 'mail' => $this->randomMachineName() . '@example.com', 'subject[0][value]' => $this->randomMachineName(), 'comment_body[0][value]' => $this->randomMachineName()); $this->drupalPostForm('comment/reply/node/' . $this->node->id() . '/comment', $edit, t('Save')); $this->assertRaw(t('The name you used (%name) belongs to a registered user.', ['%name' => $this->adminUser->getUsername()])); // Require contact info. $this->drupalLogin($this->adminUser); $this->setCommentAnonymous(COMMENT_ANONYMOUS_MUST_CONTACT); $this->drupalLogout(); // Try to post comment with contact info (required). $this->drupalGet('comment/reply/node/' . $this->node->id() . '/comment'); $this->assertTrue($this->commentContactInfoAvailable(), 'Contact information available.'); $anonymous_comment3 = $this->postComment($this->node, $this->randomMachineName(), $this->randomMachineName(), TRUE); // Name should have 'Anonymous' for value by default. $this->assertText(t('Email field is required.'), 'Email required.'); $this->assertFalse($this->commentExists($anonymous_comment3), 'Anonymous comment with contact info (required) not found.'); // Post comment with contact info (required). $author_name = $this->randomMachineName(); $author_mail = $this->randomMachineName() . '@example.com'; $anonymous_comment3 = $this->postComment($this->node, $this->randomMachineName(), $this->randomMachineName(), array('name' => $author_name, 'mail' => $author_mail)); $this->assertTrue($this->commentExists($anonymous_comment3), 'Anonymous comment with contact info (required) found.'); // Make sure the user data appears correctly when editing the comment. $this->drupalLogin($this->adminUser); $this->drupalGet('comment/' . $anonymous_comment3->id() . '/edit'); $this->assertRaw($author_name, "The anonymous user's name is correct when editing the comment."); $this->assertFieldByName('uid', '', 'The author field is empty (i.e. anonymous) when editing the comment.'); $this->assertRaw($author_mail, "The anonymous user's email address is correct when editing the comment."); // Unpublish comment. $this->performCommentOperation($anonymous_comment3, 'unpublish'); $this->drupalGet('admin/content/comment/approval'); $this->assertRaw('comments[' . $anonymous_comment3->id() . ']', 'Comment was unpublished.'); // Publish comment. $this->performCommentOperation($anonymous_comment3, 'publish', TRUE); $this->drupalGet('admin/content/comment'); $this->assertRaw('comments[' . $anonymous_comment3->id() . ']', 'Comment was published.'); // Delete comment. $this->performCommentOperation($anonymous_comment3, 'delete'); $this->drupalGet('admin/content/comment'); $this->assertNoRaw('comments[' . $anonymous_comment3->id() . ']', 'Comment was deleted.'); $this->drupalLogout(); // Comment 3 was deleted. $this->drupalGet('comment/reply/node/' . $this->node->id() . '/comment/' . $anonymous_comment3->id()); $this->assertResponse(403); // Reset. user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array('access comments' => FALSE, 'post comments' => FALSE, 'skip comment approval' => FALSE)); // Attempt to view comments while disallowed. // NOTE: if authenticated user has permission to post comments, then a // "Login or register to post comments" type link may be shown. $this->drupalGet('node/' . $this->node->id()); $this->assertNoPattern('@<h2[^>]*>Comments</h2>@', 'Comments were not displayed.'); $this->assertNoLink('Add new comment', 'Link to add comment was found.'); // Attempt to view node-comment form while disallowed. $this->drupalGet('comment/reply/node/' . $this->node->id() . '/comment'); $this->assertResponse(403); user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array('access comments' => TRUE, 'post comments' => FALSE, 'skip comment approval' => FALSE)); $this->drupalGet('node/' . $this->node->id()); $this->assertPattern('@<h2[^>]*>Comments</h2>@', 'Comments were displayed.'); $this->assertLink('Log in', 1, 'Link to log in was found.'); $this->assertLink('register', 1, 'Link to register was found.'); user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array('access comments' => FALSE, 'post comments' => TRUE, 'skip comment approval' => TRUE)); $this->drupalGet('node/' . $this->node->id()); $this->assertNoPattern('@<h2[^>]*>Comments</h2>@', 'Comments were not displayed.'); $this->assertFieldByName('subject[0][value]', '', 'Subject field found.'); $this->assertFieldByName('comment_body[0][value]', '', 'Comment field found.'); $this->drupalGet('comment/reply/node/' . $this->node->id() . '/comment/' . $anonymous_comment2->id()); $this->assertResponse(403); }
/** * Verify proper permission changes by user_role_change_permissions(). */ function testUserRoleChangePermissions() { $permissions_hash_generator = $this->container->get('user_permissions_hash_generator'); $rid = $this->rid; $account = $this->adminUser; $previous_permissions_hash = $permissions_hash_generator->generate($account); // Verify current permissions. $this->assertFalse($account->hasPermission('administer users'), 'User does not have "administer users" permission.'); $this->assertTrue($account->hasPermission('access user profiles'), 'User has "access user profiles" permission.'); $this->assertTrue($account->hasPermission('administer site configuration'), 'User has "administer site configuration" permission.'); // Change permissions. $permissions = array('administer users' => 1, 'access user profiles' => 0); user_role_change_permissions($rid, $permissions); // Verify proper permission changes. $this->assertTrue($account->hasPermission('administer users'), 'User now has "administer users" permission.'); $this->assertFalse($account->hasPermission('access user profiles'), 'User no longer has "access user profiles" permission.'); $this->assertTrue($account->hasPermission('administer site configuration'), 'User still has "administer site configuration" permission.'); // Verify the permissions hash has changed. $current_permissions_hash = $permissions_hash_generator->generate($account); $this->assertNotEqual($previous_permissions_hash, $current_permissions_hash, 'Permissions hash has changed.'); }
/** * Tests the recent comments block. */ public function testRecentNodeBlock() { $this->drupalLogin($this->adminUser); // Disallow anonymous users to view content. user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array('access content' => FALSE)); // Enable the recent content block with two items. $block = $this->drupalPlaceBlock('views_block:content_recent-block_1', array('id' => 'test_block', 'items_per_page' => 2)); // Test that block is not visible without nodes. $this->drupalGet(''); $this->assertText(t('No content available.'), 'Block with "No content available." found.'); // Add some test nodes. $default_settings = array('uid' => $this->webUser->id(), 'type' => 'article'); $node1 = $this->drupalCreateNode($default_settings); $node2 = $this->drupalCreateNode($default_settings); $node3 = $this->drupalCreateNode($default_settings); // Change the changed time for node so that we can test ordering. db_update('node_field_data')->fields(array('changed' => $node1->getChangedTime() + 100))->condition('nid', $node2->id())->execute(); db_update('node_field_data')->fields(array('changed' => $node1->getChangedTime() + 200))->condition('nid', $node3->id())->execute(); // Test that a user without the 'access content' permission cannot // see the block. $this->drupalLogout(); $this->drupalGet(''); $this->assertNoText($block->label(), 'Block was not found.'); // Test that only the 2 latest nodes are shown. $this->drupalLogin($this->webUser); $this->assertNoText($node1->label(), 'Node not found in block.'); $this->assertText($node2->label(), 'Node found in block.'); $this->assertText($node3->label(), 'Node found in block.'); // Check to make sure nodes are in the right order. $this->assertTrue($this->xpath('//div[@id="block-test-block"]//table/tbody/tr[position() = 1]/td/a[text() = "' . $node3->label() . '"]'), 'Nodes were ordered correctly in block.'); $this->drupalLogout(); $this->drupalLogin($this->adminUser); // Verify that the More link is shown and leads to the admin content page. $this->drupalGet(''); $this->clickLink('More'); $this->assertResponse('200'); $this->assertUrl('admin/content'); // Set the number of recent nodes to show to 10. $block->getPlugin()->setConfigurationValue('items_per_page', 10); $block->save(); // Post an additional node. $node4 = $this->drupalCreateNode($default_settings); // Test that all four nodes are shown. $this->drupalGet(''); $this->assertText($node1->label(), 'Node found in block.'); $this->assertText($node2->label(), 'Node found in block.'); $this->assertText($node3->label(), 'Node found in block.'); $this->assertText($node4->label(), 'Node found in block.'); // Enable the "Powered by Drupal" block only on article nodes. $edit = ['id' => strtolower($this->randomMachineName()), 'region' => 'sidebar_first', 'visibility[node_type][bundles][article]' => 'article']; $theme = \Drupal::service('theme_handler')->getDefault(); $this->drupalPostForm("admin/structure/block/add/system_powered_by_block/{$theme}", $edit, t('Save block')); $block = Block::load($edit['id']); $visibility = $block->getVisibility(); $this->assertTrue(isset($visibility['node_type']['bundles']['article']), 'Visibility settings were saved to configuration'); // Create a page node. $node5 = $this->drupalCreateNode(array('uid' => $this->adminUser->id(), 'type' => 'page')); $this->drupalLogout(); $this->drupalLogin($this->webUser); // Verify visibility rules. $this->drupalGet(''); $label = $block->label(); $this->assertNoText($label, 'Block was not displayed on the front page.'); $this->drupalGet('node/add/article'); $this->assertText($label, 'Block was displayed on the node/add/article page.'); $this->drupalGet('node/' . $node1->id()); $this->assertText($label, 'Block was displayed on the node/N when node is of type article.'); $this->drupalGet('node/' . $node5->id()); $this->assertNoText($label, 'Block was not displayed on nodes of type page.'); $this->drupalLogin($this->adminUser); $this->drupalGet('admin/structure/block'); $this->assertText($label, 'Block was displayed on the admin/structure/block page.'); $this->assertLinkByHref($block->url()); }
/** * Given information, update or insert a new workflow. * * This also handles importing, rebuilding, reverting from Features, * as defined in workflow.features.inc. * todo: reverting does not refresh States and transitions, since no * machine_name was present. As of 7.x-2.3, the machine_name exists in * Workflow and WorkflowConfigTransition, so rebuilding is possible. * * When changing this function, test with the following situations: * - maintain Workflow in Admin UI; * - clone Workflow in Admin UI; * - create/revert/rebuild Workflow with Features; @see workflow.features.inc * - save Workflow programmatically; */ public function save($create_creation_state = TRUE) { // Are we saving a new Workflow? $is_new = !empty($this->is_new); // Are we rebuilding, reverting a new Workflow? @see workflow.features.inc $is_rebuild = !empty($this->is_rebuild); $is_reverted = !empty($this->is_reverted); // If rebuild by Features, make some conversions. if (!$is_rebuild && !$is_reverted) { // Avoid troubles with features clone/revert/.. unset($this->module); } else { $role_map = isset($this->system_roles) ? $this->system_roles : array(); if ($role_map) { // Remap roles. They can come from another system with shifted role IDs. // See also https://drupal.org/node/1702626 . $this->tab_roles = _workflow_rebuild_roles($this->tab_roles, $role_map); foreach ($this->transitions as &$transition) { $transition['roles'] = _workflow_rebuild_roles($transition['roles'], $role_map); } } // Insert the type_map when building from Features. if ($this->typeMap) { foreach ($this->typeMap as $node_type) { workflow_insert_workflow_type_map($node_type, $this->wid); } } } // After update.php or import feature, label might be empty. @todo: remove in D8. if (empty($this->label)) { $this->label = $this->name; } $return = parent::save(); // If a workflow is cloned in Admin UI, it contains data from original workflow. // Redetermine the keys. if ($is_new && $this->states) { foreach ($this->states as $state) { // Can be array when cloning or with features. $state = is_array($state) ? new WorkflowState($state) : $state; // Set up a conversion table, while saving the states. $old_sid = $state->sid; $state->wid = $this->wid; // @todo: setting sid to FALSE should be done by entity_ui_clone_entity(). $state->sid = FALSE; $state->save(); $sid_conversion[$old_sid] = $state->sid; } // Reset state cache. $this->getStates(TRUE, TRUE); foreach ($this->transitions as &$transition) { // Can be array when cloning or with features. $transition = is_array($transition) ? new WorkflowConfigTransition($transition, 'WorkflowConfigTransition') : $transition; // Convert the old sids of each transitions before saving. // @todo: is this be done in 'clone $transition'? // (That requires a list of transitions without tid and a wid-less conversion table.) if (isset($sid_conversion[$transition->sid])) { $transition->tid = FALSE; $transition->sid = $sid_conversion[$transition->sid]; $transition->target_sid = $sid_conversion[$transition->target_sid]; $transition->save(); } } } // Make sure a Creation state exists. if ($is_new) { $state = $this->getCreationState(); } // Make sure the default roles are permitted in transitions for better UX. if ($is_new && count(workflow_load_multiple()) == 1) { foreach (user_roles() as $rid => $name) { $perms = array('participate in workflow' => 1); user_role_change_permissions($rid, $perms); // <=== Enable Roles } } workflow_reset_cache($this->wid); return $return; }
/** * {@inheritdoc} */ protected function setUp() { parent::setUp(); // Set up permissions for anonymous attacker user. user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array('create article content' => TRUE, 'access content' => TRUE)); }
/** * Set roles for the specified text format. * * @param string $format_name * Text format machine name. * @param array $roles * Roles array keyed by the role ID. * * @return bool * TRUE / FALSE when filter name is invalid. */ public function setFormatRoles($format_name, $roles) { $format = $this->getFormat($format_name); // Save user permissions. if ($permission = filter_permission_name($format)) { foreach ($roles as $rid => $enabled) { user_role_change_permissions($rid, array($permission => $enabled)); } return TRUE; } return FALSE; }