annotate core/modules/media/tests/src/Functional/MediaAccessTest.php @ 5:12f9dff5fda9 tip

Update to Drupal core 8.7.1
author Chris Cannam
date Thu, 09 May 2019 15:34:47 +0100
parents a9cd425dd02b
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Tests\media\Functional;
Chris@0 4
Chris@5 5 use Drupal\field\Entity\FieldConfig;
Chris@5 6 use Drupal\field\Entity\FieldStorageConfig;
Chris@0 7 use Drupal\media\Entity\Media;
Chris@0 8 use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
Chris@0 9 use Drupal\user\Entity\Role;
Chris@0 10 use Drupal\user\RoleInterface;
Chris@0 11
Chris@0 12 /**
Chris@0 13 * Basic access tests for Media.
Chris@0 14 *
Chris@0 15 * @group media
Chris@0 16 */
Chris@0 17 class MediaAccessTest extends MediaFunctionalTestBase {
Chris@0 18
Chris@0 19 use AssertPageCacheContextsAndTagsTrait;
Chris@0 20
Chris@0 21 /**
Chris@0 22 * {@inheritdoc}
Chris@0 23 */
Chris@0 24 public static $modules = [
Chris@0 25 'block',
Chris@0 26 'media_test_source',
Chris@0 27 ];
Chris@0 28
Chris@0 29 /**
Chris@0 30 * {@inheritdoc}
Chris@0 31 */
Chris@0 32 protected function setUp() {
Chris@0 33 parent::setUp();
Chris@0 34 // This is needed to provide the user cache context for a below assertion.
Chris@0 35 $this->drupalPlaceBlock('local_tasks_block');
Chris@0 36 }
Chris@0 37
Chris@0 38 /**
Chris@0 39 * Test some access control functionality.
Chris@0 40 */
Chris@0 41 public function testMediaAccess() {
Chris@0 42 $assert_session = $this->assertSession();
Chris@5 43 $media_type = $this->createMediaType('test');
Chris@0 44
Chris@5 45 \Drupal::configFactory()
Chris@5 46 ->getEditable('media.settings')
Chris@5 47 ->set('standalone_url', TRUE)
Chris@5 48 ->save(TRUE);
Chris@5 49
Chris@5 50 $this->container->get('router.builder')->rebuild();
Chris@0 51
Chris@0 52 // Create media.
Chris@0 53 $media = Media::create([
Chris@0 54 'bundle' => $media_type->id(),
Chris@0 55 'name' => 'Unnamed',
Chris@0 56 ]);
Chris@0 57 $media->save();
Chris@0 58 $user_media = Media::create([
Chris@0 59 'bundle' => $media_type->id(),
Chris@0 60 'name' => 'Unnamed',
Chris@0 61 'uid' => $this->nonAdminUser->id(),
Chris@0 62 ]);
Chris@0 63 $user_media->save();
Chris@0 64
Chris@0 65 // We are logged in as admin, so test 'administer media' permission.
Chris@0 66 $this->drupalGet('media/add/' . $media_type->id());
Chris@0 67 $this->assertCacheContext('user.permissions');
Chris@0 68 $assert_session->statusCodeEquals(200);
Chris@0 69 $this->drupalGet('media/' . $user_media->id());
Chris@0 70 $this->assertCacheContext('user.permissions');
Chris@0 71 $assert_session->statusCodeEquals(200);
Chris@0 72 $this->drupalGet('media/' . $user_media->id() . '/edit');
Chris@0 73 $this->assertCacheContext('user.permissions');
Chris@0 74 $assert_session->statusCodeEquals(200);
Chris@0 75 $this->drupalGet('media/' . $user_media->id() . '/delete');
Chris@0 76 $this->assertCacheContext('user.permissions');
Chris@0 77 $assert_session->statusCodeEquals(200);
Chris@0 78
Chris@0 79 $this->drupalLogin($this->nonAdminUser);
Chris@0 80 /** @var \Drupal\user\RoleInterface $role */
Chris@0 81 $role = Role::load(RoleInterface::AUTHENTICATED_ID);
Chris@0 82
Chris@0 83 user_role_revoke_permissions($role->id(), ['view media']);
Chris@0 84
Chris@0 85 // Test 'create BUNDLE media' permission.
Chris@0 86 $this->drupalGet('media/add/' . $media_type->id());
Chris@0 87 $this->assertCacheContext('user.permissions');
Chris@0 88 $assert_session->statusCodeEquals(403);
Chris@0 89 $permissions = ['create ' . $media_type->id() . ' media'];
Chris@0 90 $this->grantPermissions($role, $permissions);
Chris@0 91 $this->drupalGet('media/add/' . $media_type->id());
Chris@0 92 $this->assertCacheContext('user.permissions');
Chris@0 93 $assert_session->statusCodeEquals(200);
Chris@0 94 user_role_revoke_permissions($role->id(), $permissions);
Chris@0 95 $role = Role::load(RoleInterface::AUTHENTICATED_ID);
Chris@0 96
Chris@5 97 // Verify the author can not view the unpublished media item without
Chris@5 98 // 'view own unpublished media' permission.
Chris@5 99 $this->grantPermissions($role, ['view media']);
Chris@5 100 $this->drupalGet('media/' . $user_media->id());
Chris@5 101 $this->assertNoCacheContext('user');
Chris@5 102 $this->assertCacheContext('user.permissions');
Chris@5 103 $assert_session->statusCodeEquals(200);
Chris@5 104 $user_media->setUnpublished()->save();
Chris@5 105 $this->drupalGet('media/' . $user_media->id());
Chris@5 106 $this->assertCacheContext('user.permissions');
Chris@5 107 $assert_session->statusCodeEquals(403);
Chris@5 108 $access_result = $user_media->access('view', NULL, TRUE);
Chris@5 109 $this->assertSame("The user must be the owner and the 'view own unpublished media' permission is required when the media item is unpublished.", $access_result->getReason());
Chris@5 110 $this->grantPermissions($role, ['view own unpublished media']);
Chris@5 111 $this->drupalGet('media/' . $user_media->id());
Chris@5 112 $this->assertCacheContext('user');
Chris@5 113 $assert_session->statusCodeEquals(200);
Chris@5 114
Chris@0 115 // Test 'create media' permission.
Chris@0 116 $this->drupalGet('media/add/' . $media_type->id());
Chris@0 117 $this->assertCacheContext('user.permissions');
Chris@0 118 $assert_session->statusCodeEquals(403);
Chris@0 119 $permissions = ['create media'];
Chris@0 120 $this->grantPermissions($role, $permissions);
Chris@0 121 $this->drupalGet('media/add/' . $media_type->id());
Chris@0 122 $this->assertCacheContext('user.permissions');
Chris@0 123 $assert_session->statusCodeEquals(200);
Chris@0 124 user_role_revoke_permissions($role->id(), $permissions);
Chris@0 125 $role = Role::load(RoleInterface::AUTHENTICATED_ID);
Chris@0 126
Chris@0 127 // Test 'edit own BUNDLE media' and 'delete own BUNDLE media' permissions.
Chris@0 128 $this->drupalGet('media/' . $user_media->id() . '/edit');
Chris@0 129 $this->assertCacheContext('user.permissions');
Chris@0 130 $assert_session->statusCodeEquals(403);
Chris@0 131 $this->drupalGet('media/' . $user_media->id() . '/delete');
Chris@0 132 $this->assertCacheContext('user.permissions');
Chris@0 133 $assert_session->statusCodeEquals(403);
Chris@0 134 $permissions = [
Chris@0 135 'edit own ' . $user_media->bundle() . ' media',
Chris@0 136 'delete own ' . $user_media->bundle() . ' media',
Chris@0 137 ];
Chris@0 138 $this->grantPermissions($role, $permissions);
Chris@0 139 $this->drupalGet('media/' . $user_media->id() . '/edit');
Chris@0 140 $this->assertCacheContext('user');
Chris@0 141 $assert_session->statusCodeEquals(200);
Chris@0 142 $this->drupalGet('media/' . $user_media->id() . '/delete');
Chris@0 143 $this->assertCacheContext('user');
Chris@0 144 $assert_session->statusCodeEquals(200);
Chris@0 145 user_role_revoke_permissions($role->id(), $permissions);
Chris@0 146 $role = Role::load(RoleInterface::AUTHENTICATED_ID);
Chris@0 147
Chris@0 148 // Test 'edit any BUNDLE media' and 'delete any BUNDLE media' permissions.
Chris@0 149 $this->drupalGet('media/' . $media->id() . '/edit');
Chris@0 150 $this->assertCacheContext('user.permissions');
Chris@0 151 $assert_session->statusCodeEquals(403);
Chris@0 152 $this->drupalGet('media/' . $media->id() . '/delete');
Chris@0 153 $this->assertCacheContext('user.permissions');
Chris@0 154 $assert_session->statusCodeEquals(403);
Chris@0 155 $permissions = [
Chris@0 156 'edit any ' . $media->bundle() . ' media',
Chris@0 157 'delete any ' . $media->bundle() . ' media',
Chris@0 158 ];
Chris@0 159 $this->grantPermissions($role, $permissions);
Chris@0 160 $this->drupalGet('media/' . $media->id() . '/edit');
Chris@0 161 $this->assertCacheContext('user.permissions');
Chris@0 162 $assert_session->statusCodeEquals(200);
Chris@0 163 $this->drupalGet('media/' . $media->id() . '/delete');
Chris@0 164 $this->assertCacheContext('user.permissions');
Chris@0 165 $assert_session->statusCodeEquals(200);
Chris@0 166
Chris@0 167 // Test the 'access media overview' permission.
Chris@0 168 $this->grantPermissions($role, ['access content overview']);
Chris@0 169 $this->drupalGet('admin/content');
Chris@0 170 $assert_session->linkByHrefNotExists('/admin/content/media');
Chris@0 171 $this->assertCacheContext('user');
Chris@0 172
Chris@0 173 // Create a new role, which implicitly checks if the permission exists.
Chris@0 174 $mediaOverviewRole = $this->createRole(['access content overview', 'access media overview']);
Chris@0 175 $this->nonAdminUser->addRole($mediaOverviewRole);
Chris@0 176 $this->nonAdminUser->save();
Chris@0 177
Chris@0 178 $this->drupalGet('admin/content');
Chris@0 179 $assert_session->linkByHrefExists('/admin/content/media');
Chris@0 180 $this->clickLink('Media');
Chris@0 181 $this->assertCacheContext('user.permissions');
Chris@0 182 $assert_session->statusCodeEquals(200);
Chris@0 183 $assert_session->elementExists('css', '.view-media');
Chris@0 184 $assert_session->pageTextContains($this->loggedInUser->getDisplayName());
Chris@0 185 $assert_session->pageTextContains($this->nonAdminUser->getDisplayName());
Chris@0 186 $assert_session->linkByHrefExists('/media/' . $media->id());
Chris@0 187 $assert_session->linkByHrefExists('/media/' . $user_media->id());
Chris@0 188 }
Chris@0 189
Chris@5 190 /**
Chris@5 191 * Test view access control on the canonical page.
Chris@5 192 */
Chris@5 193 public function testCanonicalMediaAccess() {
Chris@5 194 $media_type = $this->createMediaType('test');
Chris@5 195 $assert_session = $this->assertSession();
Chris@5 196
Chris@5 197 \Drupal::configFactory()
Chris@5 198 ->getEditable('media.settings')
Chris@5 199 ->set('standalone_url', TRUE)
Chris@5 200 ->save(TRUE);
Chris@5 201
Chris@5 202 $this->container->get('router.builder')->rebuild();
Chris@5 203
Chris@5 204 // Create media.
Chris@5 205 $media = Media::create([
Chris@5 206 'bundle' => $media_type->id(),
Chris@5 207 'name' => 'Unnamed',
Chris@5 208 ]);
Chris@5 209 $media->save();
Chris@5 210 $user_media = Media::create([
Chris@5 211 'bundle' => $media_type->id(),
Chris@5 212 'name' => 'Unnamed',
Chris@5 213 'uid' => $this->nonAdminUser->id(),
Chris@5 214 ]);
Chris@5 215 $user_media->save();
Chris@5 216
Chris@5 217 $this->drupalLogin($this->nonAdminUser);
Chris@5 218 /** @var \Drupal\user\RoleInterface $role */
Chris@5 219 $role = Role::load(RoleInterface::AUTHENTICATED_ID);
Chris@5 220
Chris@5 221 user_role_revoke_permissions($role->id(), ['view media']);
Chris@5 222
Chris@5 223 $this->drupalGet('media/' . $media->id());
Chris@5 224 $this->assertCacheContext('user.permissions');
Chris@5 225 $assert_session->statusCodeEquals(403);
Chris@5 226 $access_result = $media->access('view', NULL, TRUE);
Chris@5 227 $this->assertSame("The 'view media' permission is required when the media item is published.", $access_result->getReason());
Chris@5 228 $this->grantPermissions($role, ['view media']);
Chris@5 229 $this->drupalGet('media/' . $media->id());
Chris@5 230 $this->assertCacheContext('user.permissions');
Chris@5 231 $assert_session->statusCodeEquals(200);
Chris@5 232 }
Chris@5 233
Chris@5 234 /**
Chris@5 235 * Tests unpublished media access.
Chris@5 236 */
Chris@5 237 public function testUnpublishedMediaUserAccess() {
Chris@5 238 \Drupal::configFactory()
Chris@5 239 ->getEditable('media.settings')
Chris@5 240 ->set('standalone_url', TRUE)
Chris@5 241 ->save(TRUE);
Chris@5 242
Chris@5 243 $this->container->get('router.builder')->rebuild();
Chris@5 244
Chris@5 245 $assert_session = $this->assertSession();
Chris@5 246 $media_type = $this->createMediaType('test');
Chris@5 247 $permissions = [
Chris@5 248 'view media',
Chris@5 249 'view own unpublished media',
Chris@5 250 ];
Chris@5 251 $user_one = $this->drupalCreateUser($permissions);
Chris@5 252 $user_two = $this->drupalCreateUser($permissions);
Chris@5 253
Chris@5 254 // Create media as user one.
Chris@5 255 $user_media = Media::create([
Chris@5 256 'bundle' => $media_type->id(),
Chris@5 257 'name' => 'Unnamed',
Chris@5 258 'uid' => $user_one->id(),
Chris@5 259 ]);
Chris@5 260 $user_media->setUnpublished()->save();
Chris@5 261
Chris@5 262 // Make sure user two can't access unpublished media.
Chris@5 263 $this->drupalLogin($user_two);
Chris@5 264 $this->drupalGet('media/' . $user_media->id());
Chris@5 265 $assert_session->statusCodeEquals(403);
Chris@5 266 $this->assertCacheContext('user');
Chris@5 267 $this->drupalLogout();
Chris@5 268
Chris@5 269 // Make sure user one can access own unpublished media.
Chris@5 270 $this->drupalLogin($user_one);
Chris@5 271 $this->drupalGet('media/' . $user_media->id());
Chris@5 272 $assert_session->statusCodeEquals(200);
Chris@5 273 $this->assertCacheContext('user');
Chris@5 274 }
Chris@5 275
Chris@5 276 /**
Chris@5 277 * Tests media access of anonymous user.
Chris@5 278 */
Chris@5 279 public function testMediaAnonymousUserAccess() {
Chris@5 280 \Drupal::configFactory()
Chris@5 281 ->getEditable('media.settings')
Chris@5 282 ->set('standalone_url', TRUE)
Chris@5 283 ->save(TRUE);
Chris@5 284
Chris@5 285 $this->container->get('router.builder')->rebuild();
Chris@5 286
Chris@5 287 $assert_session = $this->assertSession();
Chris@5 288 $media_type = $this->createMediaType('test');
Chris@5 289
Chris@5 290 // Create media as anonymous user.
Chris@5 291 $user_media = Media::create([
Chris@5 292 'bundle' => $media_type->id(),
Chris@5 293 'name' => 'Unnamed',
Chris@5 294 'uid' => 0,
Chris@5 295 ]);
Chris@5 296 $user_media->save();
Chris@5 297
Chris@5 298 $role = Role::load(RoleInterface::ANONYMOUS_ID);
Chris@5 299 $this->grantPermissions($role, ['view media', 'view own unpublished media']);
Chris@5 300 $this->drupalLogout();
Chris@5 301
Chris@5 302 // Make sure anonymous users can access published media.
Chris@5 303 $user_media->setPublished()->save();
Chris@5 304 $this->drupalGet('media/' . $user_media->id());
Chris@5 305 $assert_session->statusCodeEquals(200);
Chris@5 306
Chris@5 307 // Make sure anonymous users can not access unpublished media
Chris@5 308 // even though role has 'view own unpublished media' permission.
Chris@5 309 $user_media->setUnpublished()->save();
Chris@5 310 $this->drupalGet('media/' . $user_media->id());
Chris@5 311 $assert_session->statusCodeEquals(403);
Chris@5 312 $this->assertCacheContext('user');
Chris@5 313 }
Chris@5 314
Chris@5 315 /**
Chris@5 316 * Tests access for embedded medias.
Chris@5 317 */
Chris@5 318 public function testReferencedRendering() {
Chris@5 319 \Drupal::configFactory()
Chris@5 320 ->getEditable('media.settings')
Chris@5 321 ->set('standalone_url', TRUE)
Chris@5 322 ->save(TRUE);
Chris@5 323
Chris@5 324 $this->container->get('router.builder')->rebuild();
Chris@5 325
Chris@5 326 // Create a media type and a entity reference to itself.
Chris@5 327 $media_type = $this->createMediaType('test');
Chris@5 328
Chris@5 329 FieldStorageConfig::create([
Chris@5 330 'field_name' => 'field_reference',
Chris@5 331 'entity_type' => 'media',
Chris@5 332 'type' => 'entity_reference',
Chris@5 333 'settings' => [
Chris@5 334 'target_type' => 'media',
Chris@5 335 ],
Chris@5 336 ])->save();
Chris@5 337
Chris@5 338 FieldConfig::create([
Chris@5 339 'field_name' => 'field_reference',
Chris@5 340 'entity_type' => 'media',
Chris@5 341 'bundle' => $media_type->id(),
Chris@5 342 ])->save();
Chris@5 343
Chris@5 344 $author = $this->drupalCreateUser([
Chris@5 345 'view media',
Chris@5 346 'view own unpublished media',
Chris@5 347 ]);
Chris@5 348 $other_user = $this->drupalCreateUser([
Chris@5 349 'view media',
Chris@5 350 'view own unpublished media',
Chris@5 351 ]);
Chris@5 352 $view_user = $this->drupalCreateUser(['view media']);
Chris@5 353
Chris@5 354 $child_title = 'Child media';
Chris@5 355 $media_child = Media::create([
Chris@5 356 'name' => $child_title,
Chris@5 357 'bundle' => $media_type->id(),
Chris@5 358 'uid' => $author->id(),
Chris@5 359 ]);
Chris@5 360 $media_child->setUnpublished()->save();
Chris@5 361
Chris@5 362 $media_parent = Media::create([
Chris@5 363 'name' => 'Parent media',
Chris@5 364 'bundle' => $media_type->id(),
Chris@5 365 'field_reference' => $media_child->id(),
Chris@5 366 ]);
Chris@5 367 $media_parent->save();
Chris@5 368
Chris@5 369 entity_get_display('media', $media_type->id(), 'full')
Chris@5 370 ->set('content', [])
Chris@5 371 ->setComponent('title', ['type' => 'string'])
Chris@5 372 ->setComponent('field_reference', [
Chris@5 373 'type' => 'entity_reference_label',
Chris@5 374 ])
Chris@5 375 ->save();
Chris@5 376
Chris@5 377 $assert_session = $this->assertSession();
Chris@5 378
Chris@5 379 // The author of the child media items should have access to both the parent
Chris@5 380 // and child.
Chris@5 381 $this->drupalLogin($author);
Chris@5 382 $this->drupalGet($media_parent->toUrl());
Chris@5 383 $this->assertCacheContext('user');
Chris@5 384 $assert_session->pageTextContains($child_title);
Chris@5 385
Chris@5 386 // Other users with the 'view own unpublished media' permission should not
Chris@5 387 // be able to see the unpublished child media item. The 'user' cache context
Chris@5 388 // should be added in this case.
Chris@5 389 $this->drupalLogin($other_user);
Chris@5 390 $this->drupalGet($media_parent->toUrl());
Chris@5 391 $this->assertCacheContext('user');
Chris@5 392 $assert_session->pageTextNotContains($child_title);
Chris@5 393
Chris@5 394 // User with just the 'view media' permission should not be able to see the
Chris@5 395 // child media item. The 'user' cache context should not be added in this
Chris@5 396 // case.
Chris@5 397 $this->drupalLogin($view_user);
Chris@5 398 $this->drupalGet($media_parent->toUrl());
Chris@5 399 $this->assertNoCacheContext('user');
Chris@5 400 $assert_session->pageTextNotContains($child_title);
Chris@5 401 }
Chris@5 402
Chris@0 403 }