Commit 1c94124a authored by alexpott's avatar alexpott

Issue #2344151 by larowlan: Comment field access doesn't work if $items isn't present

parent 4243b609
......@@ -57,8 +57,6 @@ protected function checkCreateAccess(AccountInterface $account, array $context,
* {@inheritdoc}
*/
protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
/** @var \Drupal\comment\CommentInterface $entity */
$entity = $items->getEntity();
if ($operation == 'edit') {
// Only users with the "administer comments" permission can edit
// administrative fields.
......@@ -87,13 +85,22 @@ protected function checkFieldAccess($operation, FieldDefinitionInterface $field_
if (in_array($field_definition->getName(), $read_only_fields, TRUE)) {
return AccessResult::forbidden();
}
$commented_entity = $entity->getCommentedEntity();
$anonymous_contact = $commented_entity->get($entity->getFieldName())->getFieldDefinition()->getSetting('anonymous_contact');
// If the field is configured to accept anonymous contact details - admins
// can edit name, homepage and mail. Anonymous users can also fill in the
// fields on comment creation.
if (in_array($field_definition->getName(), ['name', 'mail', 'homepage'], TRUE)) {
if (!$items) {
// We cannot make a decision about access to edit these fields if we
// don't have any items and therefore cannot determine the Comment
// entity. In this case we err on the side of caution and prevent edit
// access.
return AccessResult::forbidden();
}
/** @var \Drupal\comment\CommentInterface $entity */
$entity = $items->getEntity();
$commented_entity = $entity->getCommentedEntity();
$anonymous_contact = $commented_entity->get($entity->getFieldName())->getFieldDefinition()->getSetting('anonymous_contact');
$admin_access = AccessResult::allowedIfHasPermission($account, 'administer comments');
$anonymous_access = AccessResult::allowedIf($entity->isNew() && $account->isAnonymous() && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT && $account->hasPermission('post comments'))
->cachePerRole()
......@@ -105,14 +112,17 @@ protected function checkFieldAccess($operation, FieldDefinitionInterface $field_
}
if ($operation == 'view') {
$entity = $items ? $items->getEntity() : NULL;
// Admins can view any fields except hostname, other users need both the
// "access comments" permission and for the comment to be published. The
// mail field is hidden from non-admins.
$admin_access = AccessResult::allowedIf($account->hasPermission('administer comments') && $field_definition->getName() != 'hostname')
->cachePerRole();
$anonymous_access = AccessResult::allowedIf($account->hasPermission('access comments') && $entity->isPublished() && !in_array($field_definition->getName(), array('mail', 'hostname'), TRUE))
->cacheUntilEntityChanges($entity)
$anonymous_access = AccessResult::allowedIf($account->hasPermission('access comments') && (!$entity || $entity->isPublished()) && !in_array($field_definition->getName(), array('mail', 'hostname'), TRUE))
->cachePerRole();
if ($entity) {
$anonymous_access->cacheUntilEntityChanges($entity);
}
return $admin_access->orIf($anonymous_access);
}
return parent::checkFieldAccess($operation, $field_definition, $account, $items);
......
<?php
/**
* @file
* Contains \Drupal\comment\Tests\Views\CommentRestExportTest.
*/
namespace Drupal\comment\Tests\Views;
use Drupal\Component\Serialization\Json;
/**
* Tests a comment rest export view.
*
* @group comment
*/
class CommentRestExportTest extends CommentTestBase {
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = ['test_comment_rest'];
/**
* {@inheritdoc}
*/
public static $modules = ['node', 'comment', 'comment_test_views', 'rest', 'hal'];
protected function setUp() {
parent::setUp();
// Add another anonymous comment.
$comment = array(
'uid' => 0,
'entity_id' => $this->nodeUserCommented->id(),
'entity_type' => 'node',
'field_name' => 'comment',
'subject' => 'A lot, apparently',
'cid' => '',
'pid' => $this->comment->id(),
'mail' => 'someone@example.com',
'name' => 'bobby tables',
'hostname' => 'public.example.com',
);
$this->comment = entity_create('comment', $comment);
$this->comment->save();
}
/**
* Test comment row.
*/
public function testCommentRestExport() {
$this->drupalGet(sprintf('node/%d/comments', $this->nodeUserCommented->id()), [], ['Accept' => 'application/hal+json']);
$this->assertResponse(200);
$contents = Json::decode($this->getRawContent());
$this->assertEqual($contents[0]['subject'], 'How much wood would a woodchuck chuck');
$this->assertEqual($contents[1]['subject'], 'A lot, apparently');
$this->assertEqual(count($contents), 2);
// Ensure field-level access is respected - user shouldn't be able to see
// mail or hostname fields.
$this->assertNoText('someone@example.com');
$this->assertNoText('public.example.com');
}
}
......@@ -79,9 +79,10 @@ protected function setUp() {
'entity_id' => $this->nodeUserCommented->id(),
'entity_type' => 'node',
'field_name' => 'comment',
'subject' => 'How much wood would a woodchuck chuck',
'cid' => '',
'pid' => '',
'node_type' => '',
'mail' => 'someone@example.com',
);
$this->comment = entity_create('comment', $comment);
$this->comment->save();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment