Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Tests\comment\Kernel;
|
Chris@0
|
4
|
Chris@18
|
5 use Drupal\comment\CommentInterface;
|
Chris@0
|
6 use Drupal\comment\Entity\Comment;
|
Chris@0
|
7 use Drupal\comment\Entity\CommentType;
|
Chris@0
|
8 use Drupal\comment\Tests\CommentTestTrait;
|
Chris@17
|
9 use Drupal\Component\Render\FormattableMarkup;
|
Chris@0
|
10 use Drupal\Core\Session\AnonymousUserSession;
|
Chris@0
|
11 use Drupal\entity_test\Entity\EntityTest;
|
Chris@0
|
12 use Drupal\field\Entity\FieldConfig;
|
Chris@0
|
13 use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
|
Chris@0
|
14 use Drupal\Tests\Traits\Core\GeneratePermutationsTrait;
|
Chris@0
|
15 use Drupal\user\Entity\Role;
|
Chris@0
|
16 use Drupal\user\RoleInterface;
|
Chris@0
|
17
|
Chris@0
|
18 /**
|
Chris@0
|
19 * Tests comment field level access.
|
Chris@0
|
20 *
|
Chris@0
|
21 * @group comment
|
Chris@0
|
22 * @group Access
|
Chris@0
|
23 */
|
Chris@0
|
24 class CommentFieldAccessTest extends EntityKernelTestBase {
|
Chris@0
|
25
|
Chris@0
|
26 use CommentTestTrait;
|
Chris@0
|
27 use GeneratePermutationsTrait;
|
Chris@0
|
28
|
Chris@0
|
29 /**
|
Chris@0
|
30 * Modules to install.
|
Chris@0
|
31 *
|
Chris@0
|
32 * @var array
|
Chris@0
|
33 */
|
Chris@0
|
34 public static $modules = ['comment', 'entity_test', 'user'];
|
Chris@0
|
35
|
Chris@0
|
36 /**
|
Chris@0
|
37 * Fields that only users with administer comments permissions can change.
|
Chris@0
|
38 *
|
Chris@0
|
39 * @var array
|
Chris@0
|
40 */
|
Chris@0
|
41 protected $administrativeFields = [
|
Chris@0
|
42 'uid',
|
Chris@0
|
43 'status',
|
Chris@0
|
44 'created',
|
Chris@0
|
45 ];
|
Chris@0
|
46
|
Chris@0
|
47 /**
|
Chris@0
|
48 * These fields are automatically managed and can not be changed by any user.
|
Chris@0
|
49 *
|
Chris@0
|
50 * @var array
|
Chris@0
|
51 */
|
Chris@0
|
52 protected $readOnlyFields = [
|
Chris@0
|
53 'changed',
|
Chris@0
|
54 'hostname',
|
Chris@0
|
55 'cid',
|
Chris@0
|
56 'thread',
|
Chris@0
|
57 ];
|
Chris@0
|
58
|
Chris@0
|
59 /**
|
Chris@0
|
60 * These fields can be edited on create only.
|
Chris@0
|
61 *
|
Chris@0
|
62 * @var array
|
Chris@0
|
63 */
|
Chris@0
|
64 protected $createOnlyFields = [
|
Chris@0
|
65 'uuid',
|
Chris@0
|
66 'pid',
|
Chris@0
|
67 'comment_type',
|
Chris@0
|
68 'entity_id',
|
Chris@0
|
69 'entity_type',
|
Chris@0
|
70 'field_name',
|
Chris@0
|
71 ];
|
Chris@0
|
72
|
Chris@0
|
73 /**
|
Chris@0
|
74 * These fields can only be edited by the admin or anonymous users if allowed.
|
Chris@0
|
75 *
|
Chris@0
|
76 * @var array
|
Chris@0
|
77 */
|
Chris@0
|
78 protected $contactFields = [
|
Chris@0
|
79 'name',
|
Chris@0
|
80 'mail',
|
Chris@0
|
81 'homepage',
|
Chris@0
|
82 ];
|
Chris@0
|
83
|
Chris@0
|
84 /**
|
Chris@0
|
85 * {@inheritdoc}
|
Chris@0
|
86 */
|
Chris@0
|
87 protected function setUp() {
|
Chris@0
|
88 parent::setUp();
|
Chris@0
|
89 $this->installConfig(['user', 'comment']);
|
Chris@0
|
90 $this->installSchema('comment', ['comment_entity_statistics']);
|
Chris@0
|
91 }
|
Chris@0
|
92
|
Chris@0
|
93 /**
|
Chris@0
|
94 * Test permissions on comment fields.
|
Chris@0
|
95 */
|
Chris@0
|
96 public function testAccessToAdministrativeFields() {
|
Chris@0
|
97 // Create a comment type.
|
Chris@0
|
98 $comment_type = CommentType::create([
|
Chris@0
|
99 'id' => 'comment',
|
Chris@0
|
100 'label' => 'Default comments',
|
Chris@0
|
101 'description' => 'Default comment field',
|
Chris@0
|
102 'target_entity_type_id' => 'entity_test',
|
Chris@0
|
103 ]);
|
Chris@0
|
104 $comment_type->save();
|
Chris@0
|
105
|
Chris@0
|
106 // Create a comment against a test entity.
|
Chris@0
|
107 $host = EntityTest::create();
|
Chris@0
|
108 $host->save();
|
Chris@0
|
109
|
Chris@0
|
110 // An administrator user. No user exists yet, ensure that the first user
|
Chris@0
|
111 // does not have UID 1.
|
Chris@0
|
112 $comment_admin_user = $this->createUser(['uid' => 2, 'name' => 'admin'], [
|
Chris@0
|
113 'administer comments',
|
Chris@0
|
114 'access comments',
|
Chris@0
|
115 ]);
|
Chris@0
|
116
|
Chris@0
|
117 // Two comment enabled users, one with edit access.
|
Chris@0
|
118 $comment_enabled_user = $this->createUser(['name' => 'enabled'], [
|
Chris@0
|
119 'post comments',
|
Chris@0
|
120 'skip comment approval',
|
Chris@0
|
121 'edit own comments',
|
Chris@0
|
122 'access comments',
|
Chris@0
|
123 ]);
|
Chris@0
|
124 $comment_no_edit_user = $this->createUser(['name' => 'no edit'], [
|
Chris@0
|
125 'post comments',
|
Chris@0
|
126 'skip comment approval',
|
Chris@0
|
127 'access comments',
|
Chris@0
|
128 ]);
|
Chris@0
|
129
|
Chris@0
|
130 // An unprivileged user.
|
Chris@0
|
131 $comment_disabled_user = $this->createUser(['name' => 'disabled'], ['access content']);
|
Chris@0
|
132
|
Chris@0
|
133 $role = Role::load(RoleInterface::ANONYMOUS_ID);
|
Chris@0
|
134 $role->grantPermission('post comments')
|
Chris@0
|
135 ->save();
|
Chris@0
|
136
|
Chris@0
|
137 $anonymous_user = new AnonymousUserSession();
|
Chris@0
|
138
|
Chris@0
|
139 // Add two fields.
|
Chris@0
|
140 $this->addDefaultCommentField('entity_test', 'entity_test', 'comment');
|
Chris@0
|
141 $this->addDefaultCommentField('entity_test', 'entity_test', 'comment_other');
|
Chris@0
|
142
|
Chris@0
|
143 // Change the second field's anonymous contact setting.
|
Chris@0
|
144 $instance = FieldConfig::loadByName('entity_test', 'entity_test', 'comment_other');
|
Chris@0
|
145 // Default is 'May not contact', for this field - they may contact.
|
Chris@18
|
146 $instance->setSetting('anonymous', CommentInterface::ANONYMOUS_MAY_CONTACT);
|
Chris@0
|
147 $instance->save();
|
Chris@0
|
148
|
Chris@0
|
149 // Create three "Comments". One is owned by our edit-enabled user.
|
Chris@0
|
150 $comment1 = Comment::create([
|
Chris@0
|
151 'entity_type' => 'entity_test',
|
Chris@0
|
152 'name' => 'Tony',
|
Chris@0
|
153 'hostname' => 'magic.example.com',
|
Chris@0
|
154 'mail' => 'tonythemagicalpony@example.com',
|
Chris@0
|
155 'subject' => 'Bruce the Mesopotamian moose',
|
Chris@0
|
156 'entity_id' => $host->id(),
|
Chris@0
|
157 'comment_type' => 'comment',
|
Chris@0
|
158 'field_name' => 'comment',
|
Chris@0
|
159 'pid' => 0,
|
Chris@0
|
160 'uid' => 0,
|
Chris@0
|
161 'status' => 1,
|
Chris@0
|
162 ]);
|
Chris@0
|
163 $comment1->save();
|
Chris@0
|
164 $comment2 = Comment::create([
|
Chris@0
|
165 'entity_type' => 'entity_test',
|
Chris@0
|
166 'hostname' => 'magic.example.com',
|
Chris@0
|
167 'subject' => 'Brian the messed up lion',
|
Chris@0
|
168 'entity_id' => $host->id(),
|
Chris@0
|
169 'comment_type' => 'comment',
|
Chris@0
|
170 'field_name' => 'comment',
|
Chris@0
|
171 'status' => 1,
|
Chris@0
|
172 'pid' => 0,
|
Chris@0
|
173 'uid' => $comment_enabled_user->id(),
|
Chris@0
|
174 ]);
|
Chris@0
|
175 $comment2->save();
|
Chris@0
|
176 $comment3 = Comment::create([
|
Chris@0
|
177 'entity_type' => 'entity_test',
|
Chris@0
|
178 'hostname' => 'magic.example.com',
|
Chris@0
|
179 // Unpublished.
|
Chris@0
|
180 'status' => 0,
|
Chris@0
|
181 'subject' => 'Gail the minky whale',
|
Chris@0
|
182 'entity_id' => $host->id(),
|
Chris@0
|
183 'comment_type' => 'comment',
|
Chris@0
|
184 'field_name' => 'comment_other',
|
Chris@0
|
185 'pid' => $comment2->id(),
|
Chris@0
|
186 'uid' => $comment_no_edit_user->id(),
|
Chris@0
|
187 ]);
|
Chris@0
|
188 $comment3->save();
|
Chris@0
|
189 // Note we intentionally don't save this comment so it remains 'new'.
|
Chris@0
|
190 $comment4 = Comment::create([
|
Chris@0
|
191 'entity_type' => 'entity_test',
|
Chris@0
|
192 'hostname' => 'magic.example.com',
|
Chris@0
|
193 // Unpublished.
|
Chris@0
|
194 'status' => 0,
|
Chris@0
|
195 'subject' => 'Daniel the Cocker-Spaniel',
|
Chris@0
|
196 'entity_id' => $host->id(),
|
Chris@0
|
197 'comment_type' => 'comment',
|
Chris@0
|
198 'field_name' => 'comment_other',
|
Chris@0
|
199 'pid' => 0,
|
Chris@0
|
200 'uid' => $anonymous_user->id(),
|
Chris@0
|
201 ]);
|
Chris@0
|
202
|
Chris@0
|
203 // Generate permutations.
|
Chris@0
|
204 $combinations = [
|
Chris@0
|
205 'comment' => [$comment1, $comment2, $comment3, $comment4],
|
Chris@17
|
206 'user' => [$comment_admin_user, $comment_enabled_user, $comment_no_edit_user, $comment_disabled_user, $anonymous_user],
|
Chris@0
|
207 ];
|
Chris@0
|
208 $permutations = $this->generatePermutations($combinations);
|
Chris@0
|
209
|
Chris@0
|
210 // Check access to administrative fields.
|
Chris@0
|
211 foreach ($this->administrativeFields as $field) {
|
Chris@0
|
212 foreach ($permutations as $set) {
|
Chris@0
|
213 $may_view = $set['comment']->{$field}->access('view', $set['user']);
|
Chris@0
|
214 $may_update = $set['comment']->{$field}->access('edit', $set['user']);
|
Chris@17
|
215 $this->assertTrue($may_view, new FormattableMarkup('User @user can view field @field on comment @comment', [
|
Chris@18
|
216 '@user' => $set['user']->getAccountName(),
|
Chris@0
|
217 '@comment' => $set['comment']->getSubject(),
|
Chris@0
|
218 '@field' => $field,
|
Chris@0
|
219 ]));
|
Chris@17
|
220 $this->assertEqual($may_update, $set['user']->hasPermission('administer comments'), new FormattableMarkup('User @user @state update field @field on comment @comment', [
|
Chris@18
|
221 '@user' => $set['user']->getAccountName(),
|
Chris@0
|
222 '@state' => $may_update ? 'can' : 'cannot',
|
Chris@0
|
223 '@comment' => $set['comment']->getSubject(),
|
Chris@0
|
224 '@field' => $field,
|
Chris@0
|
225 ]));
|
Chris@0
|
226 }
|
Chris@0
|
227 }
|
Chris@0
|
228
|
Chris@0
|
229 // Check access to normal field.
|
Chris@0
|
230 foreach ($permutations as $set) {
|
Chris@0
|
231 $may_update = $set['comment']->access('update', $set['user']) && $set['comment']->subject->access('edit', $set['user']);
|
Chris@17
|
232 $this->assertEqual($may_update, $set['user']->hasPermission('administer comments') || ($set['user']->hasPermission('edit own comments') && $set['user']->id() == $set['comment']->getOwnerId()), new FormattableMarkup('User @user @state update field subject on comment @comment', [
|
Chris@18
|
233 '@user' => $set['user']->getAccountName(),
|
Chris@0
|
234 '@state' => $may_update ? 'can' : 'cannot',
|
Chris@0
|
235 '@comment' => $set['comment']->getSubject(),
|
Chris@0
|
236 ]));
|
Chris@0
|
237 }
|
Chris@0
|
238
|
Chris@0
|
239 // Check read-only fields.
|
Chris@0
|
240 foreach ($this->readOnlyFields as $field) {
|
Chris@0
|
241 // Check view operation.
|
Chris@0
|
242 foreach ($permutations as $set) {
|
Chris@0
|
243 $may_view = $set['comment']->{$field}->access('view', $set['user']);
|
Chris@0
|
244 $may_update = $set['comment']->{$field}->access('edit', $set['user']);
|
Chris@0
|
245 // Nobody has access to view the hostname field.
|
Chris@0
|
246 if ($field === 'hostname') {
|
Chris@0
|
247 $view_access = FALSE;
|
Chris@0
|
248 $state = 'cannot';
|
Chris@0
|
249 }
|
Chris@0
|
250 else {
|
Chris@0
|
251 $view_access = TRUE;
|
Chris@0
|
252 $state = 'can';
|
Chris@0
|
253 }
|
Chris@17
|
254 $this->assertEqual($may_view, $view_access, new FormattableMarkup('User @user @state view field @field on comment @comment', [
|
Chris@18
|
255 '@user' => $set['user']->getAccountName(),
|
Chris@0
|
256 '@comment' => $set['comment']->getSubject(),
|
Chris@0
|
257 '@field' => $field,
|
Chris@0
|
258 '@state' => $state,
|
Chris@0
|
259 ]));
|
Chris@17
|
260 $this->assertFalse($may_update, new FormattableMarkup('User @user @state update field @field on comment @comment', [
|
Chris@18
|
261 '@user' => $set['user']->getAccountName(),
|
Chris@0
|
262 '@state' => $may_update ? 'can' : 'cannot',
|
Chris@0
|
263 '@comment' => $set['comment']->getSubject(),
|
Chris@0
|
264 '@field' => $field,
|
Chris@0
|
265 ]));
|
Chris@0
|
266 }
|
Chris@0
|
267 }
|
Chris@0
|
268
|
Chris@0
|
269 // Check create-only fields.
|
Chris@0
|
270 foreach ($this->createOnlyFields as $field) {
|
Chris@0
|
271 // Check view operation.
|
Chris@0
|
272 foreach ($permutations as $set) {
|
Chris@0
|
273 $may_view = $set['comment']->{$field}->access('view', $set['user']);
|
Chris@0
|
274 $may_update = $set['comment']->{$field}->access('edit', $set['user']);
|
Chris@17
|
275 $this->assertEqual($may_view, TRUE, new FormattableMarkup('User @user can view field @field on comment @comment', [
|
Chris@18
|
276 '@user' => $set['user']->getAccountName(),
|
Chris@0
|
277 '@comment' => $set['comment']->getSubject(),
|
Chris@0
|
278 '@field' => $field,
|
Chris@0
|
279 ]));
|
Chris@17
|
280 $this->assertEqual($may_update, $set['user']->hasPermission('post comments') && $set['comment']->isNew(), new FormattableMarkup('User @user @state update field @field on comment @comment', [
|
Chris@18
|
281 '@user' => $set['user']->getAccountName(),
|
Chris@0
|
282 '@state' => $may_update ? 'can' : 'cannot',
|
Chris@0
|
283 '@comment' => $set['comment']->getSubject(),
|
Chris@0
|
284 '@field' => $field,
|
Chris@0
|
285 ]));
|
Chris@0
|
286 }
|
Chris@0
|
287 }
|
Chris@0
|
288
|
Chris@0
|
289 // Check contact fields.
|
Chris@0
|
290 foreach ($this->contactFields as $field) {
|
Chris@0
|
291 // Check view operation.
|
Chris@0
|
292 foreach ($permutations as $set) {
|
Chris@0
|
293 $may_update = $set['comment']->{$field}->access('edit', $set['user']);
|
Chris@0
|
294 // To edit the 'mail' or 'name' field, either the user has the
|
Chris@0
|
295 // "administer comments" permissions or the user is anonymous and
|
Chris@0
|
296 // adding a new comment using a field that allows contact details.
|
Chris@0
|
297 $this->assertEqual($may_update, $set['user']->hasPermission('administer comments') || (
|
Chris@0
|
298 $set['user']->isAnonymous() &&
|
Chris@0
|
299 $set['comment']->isNew() &&
|
Chris@0
|
300 $set['user']->hasPermission('post comments') &&
|
Chris@0
|
301 $set['comment']->getFieldName() == 'comment_other'
|
Chris@17
|
302 ), new FormattableMarkup('User @user @state update field @field on comment @comment', [
|
Chris@18
|
303 '@user' => $set['user']->getAccountName(),
|
Chris@0
|
304 '@state' => $may_update ? 'can' : 'cannot',
|
Chris@0
|
305 '@comment' => $set['comment']->getSubject(),
|
Chris@0
|
306 '@field' => $field,
|
Chris@0
|
307 ]));
|
Chris@0
|
308 }
|
Chris@0
|
309 }
|
Chris@0
|
310 foreach ($permutations as $set) {
|
Chris@0
|
311 // Check no view-access to mail field for other than admin.
|
Chris@0
|
312 $may_view = $set['comment']->mail->access('view', $set['user']);
|
Chris@0
|
313 $this->assertEqual($may_view, $set['user']->hasPermission('administer comments'));
|
Chris@0
|
314 }
|
Chris@0
|
315 }
|
Chris@0
|
316
|
Chris@0
|
317 }
|