Commit 575a5342 authored by catch's avatar catch
Browse files

Issue #3371464 by larowlan, Berdir, benjifisher, andypost, dokumori, greggles,...

Issue #3371464 by larowlan, Berdir, benjifisher, andypost, dokumori, greggles, smustgrave, zviryatko, Wim Leers, longwave: CommentAccessControlHandler::checkCreateAccess() does not check commented entity's comment field's status property

(cherry picked from commit e9a09ddd)
parent e370dbe9
Loading
Loading
Loading
Loading
+17 −6
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@

namespace Drupal\comment;

use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityAccessControlHandler;
use Drupal\Core\Entity\EntityInterface;
@@ -98,9 +99,22 @@ protected function checkFieldAccess($operation, FieldDefinitionInterface $field_
        'field_name',
        'pid',
      ];
      if ($items && ($entity = $items->getEntity()) && $entity->isNew() && in_array($field_definition->getName(), $create_only_fields, TRUE)) {
        // We are creating a new comment, user can edit create only fields.
        return AccessResult::allowedIfHasPermission($account, 'post comments')->addCacheableDependency($entity);
      /** @var \Drupal\comment\CommentInterface|null $entity */
      $entity = $items ? $items->getEntity() : NULL;
      $commented_entity = $entity ? $entity->getCommentedEntity() : NULL;
      if ($entity && $entity->isNew() && in_array($field_definition->getName(), $create_only_fields, TRUE)) {
        $access_result = AccessResult::allowedIfHasPermission($account, 'post comments')
          ->addCacheableDependency($entity);
        $comment_field_name = $entity->get('field_name')->value;
        if ($commented_entity && $comment_field_name) {
          // We are creating a new comment, user can edit create only fields if
          // commenting is open.
          $commenting_status = (int) $commented_entity->get($comment_field_name)->status;
          $access_result = $access_result
            ->andIf(AccessResult::allowedIf($commenting_status !== CommentItemInterface::CLOSED))
            ->addCacheableDependency($commented_entity);
        }
        return $access_result;
      }
      // We are editing an existing comment - create only fields are now read
      // only.
@@ -121,9 +135,6 @@ protected function checkFieldAccess($operation, FieldDefinitionInterface $field_
          return AccessResult::forbidden();
        }
        $is_name = $field_definition->getName() === 'name';
        /** @var \Drupal\comment\CommentInterface $entity */
        $entity = $items->getEntity();
        $commented_entity = $entity->getCommentedEntity();
        $anonymous_contact = $commented_entity->get($entity->getFieldName())->getFieldDefinition()->getSetting('anonymous');
        $admin_access = AccessResult::allowedIfHasPermission($account, 'administer comments');
        $anonymous_access = AccessResult::allowedIf($entity->isNew() && $account->isAnonymous() && ($anonymous_contact != CommentInterface::ANONYMOUS_MAYNOT_CONTACT || $is_name) && $account->hasPermission('post comments'))
+2 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@

use Drupal\comment\Entity\Comment;
use Drupal\comment\Entity\CommentType;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\comment\Tests\CommentTestTrait;
use Drupal\Core\Cache\Cache;
use Drupal\entity_test\Entity\EntityTest;
@@ -94,6 +95,7 @@ protected function createEntity() {
    $commented_entity = EntityTest::create([
      'name' => 'Camelids',
      'type' => 'bar',
      'comment' => CommentItemInterface::OPEN,
    ]);
    $commented_entity->save();

+28 −7
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
use Drupal\comment\CommentInterface;
use Drupal\comment\Entity\Comment;
use Drupal\comment\Entity\CommentType;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\comment\Tests\CommentTestTrait;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Session\AnonymousUserSession;
@@ -103,10 +104,6 @@ public function testAccessToAdministrativeFields() {
    ]);
    $comment_type->save();

    // Create a comment against a test entity.
    $host = EntityTest::create();
    $host->save();

    // An administrator user. No user exists yet, ensure that the first user
    // does not have UID 1.
    $comment_admin_user = $this->createUser([
@@ -141,6 +138,15 @@ public function testAccessToAdministrativeFields() {
    $this->addDefaultCommentField('entity_test', 'entity_test', 'comment');
    $this->addDefaultCommentField('entity_test', 'entity_test', 'comment_other');

    // Create a comment against a test entity.
    $host = EntityTest::create();
    $host->save();

    $host2 = EntityTest::create();
    $host2->comment->status = CommentItemInterface::CLOSED;
    $host2->comment_other->status = CommentItemInterface::CLOSED;
    $host2->save();

    // Change the second field's anonymous contact setting.
    $instance = FieldConfig::loadByName('entity_test', 'entity_test', 'comment_other');
    // Default is 'May not contact', for this field - they may contact.
@@ -200,10 +206,24 @@ public function testAccessToAdministrativeFields() {
      'pid' => 0,
      'uid' => $anonymous_user->id(),
    ]);
    // Note we intentionally don't save this comment so it remains 'new'.
    $comment5 = Comment::create([
      'entity_type' => 'entity_test',
      'hostname' => 'magic.example.com',
      // Unpublished.
      'status' => 0,
      'subject' => 'Wally the Border Collie',
      // This one is closed for comments.
      'entity_id' => $host2->id(),
      'comment_type' => 'comment',
      'field_name' => 'comment_other',
      'pid' => 0,
      'uid' => $anonymous_user->id(),
    ]);

    // Generate permutations.
    $combinations = [
      'comment' => [$comment1, $comment2, $comment3, $comment4],
      'comment' => [$comment1, $comment2, $comment3, $comment4, $comment5],
      'user' => [$comment_admin_user, $comment_enabled_user, $comment_no_edit_user, $comment_disabled_user, $anonymous_user],
    ];
    $permutations = $this->generatePermutations($combinations);
@@ -278,9 +298,10 @@ public function testAccessToAdministrativeFields() {
          '@comment' => $set['comment']->getSubject(),
          '@field' => $field,
        ]));
        $this->assertEquals($may_update, $set['user']->hasPermission('post comments') && $set['comment']->isNew(), new FormattableMarkup('User @user @state update field @field on comment @comment', [
        $expected = $set['user']->hasPermission('post comments') && $set['comment']->isNew() && (int) $set['comment']->getCommentedEntity()->get($set['comment']->getFieldName())->status !== CommentItemInterface::CLOSED;
        $this->assertEquals($expected, $may_update, new FormattableMarkup('User @user @state update field @field on comment @comment', [
          '@user' => $set['user']->getAccountName(),
          '@state' => $may_update ? 'can' : 'cannot',
          '@state' => $expected ? 'can' : 'cannot',
          '@comment' => $set['comment']->getSubject(),
          '@field' => $field,
        ]));
+2 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@

use Drupal\comment\Entity\Comment;
use Drupal\comment\Entity\CommentType;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\comment\Tests\CommentTestTrait;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\NestedArray;
@@ -114,6 +115,7 @@ protected function createEntity() {
    $this->commentedEntity = EntityTest::create([
      'name' => 'Camelids',
      'type' => 'bar',
      'comment' => CommentItemInterface::OPEN,
    ]);
    $this->commentedEntity->save();