annotate core/modules/media/tests/src/Functional/MediaAccessTest.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Tests\media\Functional;
Chris@0 4
Chris@18 5 use Drupal\field\Entity\FieldConfig;
Chris@18 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@14 17 class MediaAccessTest extends MediaFunctionalTestBase {
Chris@0 18
Chris@0 19 use AssertPageCacheContextsAndTagsTrait;
Chris@0 20
Chris@0 21 /**
Chris@14 22 * {@inheritdoc}
Chris@14 23 */
Chris@14 24 public static $modules = [
Chris@14 25 'block',
Chris@14 26 'media_test_source',
Chris@14 27 ];
Chris@14 28
Chris@14 29 /**
Chris@14 30 * {@inheritdoc}
Chris@14 31 */
Chris@14 32 protected function setUp() {
Chris@14 33 parent::setUp();
Chris@14 34 // This is needed to provide the user cache context for a below assertion.
Chris@14 35 $this->drupalPlaceBlock('local_tasks_block');
Chris@14 36 }
Chris@14 37
Chris@14 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@18 43 $media_type = $this->createMediaType('test');
Chris@0 44
Chris@18 45 \Drupal::configFactory()
Chris@18 46 ->getEditable('media.settings')
Chris@18 47 ->set('standalone_url', TRUE)
Chris@18 48 ->save(TRUE);
Chris@18 49
Chris@18 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@14 85 // Test 'create BUNDLE media' permission.
Chris@14 86 $this->drupalGet('media/add/' . $media_type->id());
Chris@14 87 $this->assertCacheContext('user.permissions');
Chris@14 88 $assert_session->statusCodeEquals(403);
Chris@14 89 $permissions = ['create ' . $media_type->id() . ' media'];
Chris@14 90 $this->grantPermissions($role, $permissions);
Chris@14 91 $this->drupalGet('media/add/' . $media_type->id());
Chris@14 92 $this->assertCacheContext('user.permissions');
Chris@14 93 $assert_session->statusCodeEquals(200);
Chris@14 94 user_role_revoke_permissions($role->id(), $permissions);
Chris@14 95 $role = Role::load(RoleInterface::AUTHENTICATED_ID);
Chris@14 96
Chris@18 97 // Verify the author can not view the unpublished media item without
Chris@18 98 // 'view own unpublished media' permission.
Chris@18 99 $this->grantPermissions($role, ['view media']);
Chris@18 100 $this->drupalGet('media/' . $user_media->id());
Chris@18 101 $this->assertNoCacheContext('user');
Chris@18 102 $this->assertCacheContext('user.permissions');
Chris@18 103 $assert_session->statusCodeEquals(200);
Chris@18 104 $user_media->setUnpublished()->save();
Chris@18 105 $this->drupalGet('media/' . $user_media->id());
Chris@18 106 $this->assertCacheContext('user.permissions');
Chris@18 107 $assert_session->statusCodeEquals(403);
Chris@18 108 $access_result = $user_media->access('view', NULL, TRUE);
Chris@18 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@18 110 $this->grantPermissions($role, ['view own unpublished media']);
Chris@18 111 $this->drupalGet('media/' . $user_media->id());
Chris@18 112 $this->assertCacheContext('user');
Chris@18 113 $assert_session->statusCodeEquals(200);
Chris@18 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@14 119 $permissions = ['create media'];
Chris@14 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@14 124 user_role_revoke_permissions($role->id(), $permissions);
Chris@14 125 $role = Role::load(RoleInterface::AUTHENTICATED_ID);
Chris@0 126
Chris@14 127 // Test 'edit own BUNDLE media' and 'delete own BUNDLE media' permissions.
Chris@0 128 $this->drupalGet('media/' . $user_media->id() . '/edit');
Chris@14 129 $this->assertCacheContext('user.permissions');
Chris@0 130 $assert_session->statusCodeEquals(403);
Chris@0 131 $this->drupalGet('media/' . $user_media->id() . '/delete');
Chris@14 132 $this->assertCacheContext('user.permissions');
Chris@0 133 $assert_session->statusCodeEquals(403);
Chris@14 134 $permissions = [
Chris@14 135 'edit own ' . $user_media->bundle() . ' media',
Chris@14 136 'delete own ' . $user_media->bundle() . ' media',
Chris@14 137 ];
Chris@14 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@14 145 user_role_revoke_permissions($role->id(), $permissions);
Chris@14 146 $role = Role::load(RoleInterface::AUTHENTICATED_ID);
Chris@0 147
Chris@14 148 // Test 'edit any BUNDLE media' and 'delete any BUNDLE media' permissions.
Chris@0 149 $this->drupalGet('media/' . $media->id() . '/edit');
Chris@14 150 $this->assertCacheContext('user.permissions');
Chris@0 151 $assert_session->statusCodeEquals(403);
Chris@0 152 $this->drupalGet('media/' . $media->id() . '/delete');
Chris@14 153 $this->assertCacheContext('user.permissions');
Chris@0 154 $assert_session->statusCodeEquals(403);
Chris@14 155 $permissions = [
Chris@14 156 'edit any ' . $media->bundle() . ' media',
Chris@14 157 'delete any ' . $media->bundle() . ' media',
Chris@14 158 ];
Chris@14 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@18 190 /**
Chris@18 191 * Test view access control on the canonical page.
Chris@18 192 */
Chris@18 193 public function testCanonicalMediaAccess() {
Chris@18 194 $media_type = $this->createMediaType('test');
Chris@18 195 $assert_session = $this->assertSession();
Chris@18 196
Chris@18 197 \Drupal::configFactory()
Chris@18 198 ->getEditable('media.settings')
Chris@18 199 ->set('standalone_url', TRUE)
Chris@18 200 ->save(TRUE);
Chris@18 201
Chris@18 202 $this->container->get('router.builder')->rebuild();
Chris@18 203
Chris@18 204 // Create media.
Chris@18 205 $media = Media::create([
Chris@18 206 'bundle' => $media_type->id(),
Chris@18 207 'name' => 'Unnamed',
Chris@18 208 ]);
Chris@18 209 $media->save();
Chris@18 210 $user_media = Media::create([
Chris@18 211 'bundle' => $media_type->id(),
Chris@18 212 'name' => 'Unnamed',
Chris@18 213 'uid' => $this->nonAdminUser->id(),
Chris@18 214 ]);
Chris@18 215 $user_media->save();
Chris@18 216
Chris@18 217 $this->drupalLogin($this->nonAdminUser);
Chris@18 218 /** @var \Drupal\user\RoleInterface $role */
Chris@18 219 $role = Role::load(RoleInterface::AUTHENTICATED_ID);
Chris@18 220
Chris@18 221 user_role_revoke_permissions($role->id(), ['view media']);
Chris@18 222
Chris@18 223 $this->drupalGet('media/' . $media->id());
Chris@18 224 $this->assertCacheContext('user.permissions');
Chris@18 225 $assert_session->statusCodeEquals(403);
Chris@18 226 $access_result = $media->access('view', NULL, TRUE);
Chris@18 227 $this->assertSame("The 'view media' permission is required when the media item is published.", $access_result->getReason());
Chris@18 228 $this->grantPermissions($role, ['view media']);
Chris@18 229 $this->drupalGet('media/' . $media->id());
Chris@18 230 $this->assertCacheContext('user.permissions');
Chris@18 231 $assert_session->statusCodeEquals(200);
Chris@18 232 }
Chris@18 233
Chris@18 234 /**
Chris@18 235 * Tests unpublished media access.
Chris@18 236 */
Chris@18 237 public function testUnpublishedMediaUserAccess() {
Chris@18 238 \Drupal::configFactory()
Chris@18 239 ->getEditable('media.settings')
Chris@18 240 ->set('standalone_url', TRUE)
Chris@18 241 ->save(TRUE);
Chris@18 242
Chris@18 243 $this->container->get('router.builder')->rebuild();
Chris@18 244
Chris@18 245 $assert_session = $this->assertSession();
Chris@18 246 $media_type = $this->createMediaType('test');
Chris@18 247 $permissions = [
Chris@18 248 'view media',
Chris@18 249 'view own unpublished media',
Chris@18 250 ];
Chris@18 251 $user_one = $this->drupalCreateUser($permissions);
Chris@18 252 $user_two = $this->drupalCreateUser($permissions);
Chris@18 253
Chris@18 254 // Create media as user one.
Chris@18 255 $user_media = Media::create([
Chris@18 256 'bundle' => $media_type->id(),
Chris@18 257 'name' => 'Unnamed',
Chris@18 258 'uid' => $user_one->id(),
Chris@18 259 ]);
Chris@18 260 $user_media->setUnpublished()->save();
Chris@18 261
Chris@18 262 // Make sure user two can't access unpublished media.
Chris@18 263 $this->drupalLogin($user_two);
Chris@18 264 $this->drupalGet('media/' . $user_media->id());
Chris@18 265 $assert_session->statusCodeEquals(403);
Chris@18 266 $this->assertCacheContext('user');
Chris@18 267 $this->drupalLogout();
Chris@18 268
Chris@18 269 // Make sure user one can access own unpublished media.
Chris@18 270 $this->drupalLogin($user_one);
Chris@18 271 $this->drupalGet('media/' . $user_media->id());
Chris@18 272 $assert_session->statusCodeEquals(200);
Chris@18 273 $this->assertCacheContext('user');
Chris@18 274 }
Chris@18 275
Chris@18 276 /**
Chris@18 277 * Tests media access of anonymous user.
Chris@18 278 */
Chris@18 279 public function testMediaAnonymousUserAccess() {
Chris@18 280 \Drupal::configFactory()
Chris@18 281 ->getEditable('media.settings')
Chris@18 282 ->set('standalone_url', TRUE)
Chris@18 283 ->save(TRUE);
Chris@18 284
Chris@18 285 $this->container->get('router.builder')->rebuild();
Chris@18 286
Chris@18 287 $assert_session = $this->assertSession();
Chris@18 288 $media_type = $this->createMediaType('test');
Chris@18 289
Chris@18 290 // Create media as anonymous user.
Chris@18 291 $user_media = Media::create([
Chris@18 292 'bundle' => $media_type->id(),
Chris@18 293 'name' => 'Unnamed',
Chris@18 294 'uid' => 0,
Chris@18 295 ]);
Chris@18 296 $user_media->save();
Chris@18 297
Chris@18 298 $role = Role::load(RoleInterface::ANONYMOUS_ID);
Chris@18 299 $this->grantPermissions($role, ['view media', 'view own unpublished media']);
Chris@18 300 $this->drupalLogout();
Chris@18 301
Chris@18 302 // Make sure anonymous users can access published media.
Chris@18 303 $user_media->setPublished()->save();
Chris@18 304 $this->drupalGet('media/' . $user_media->id());
Chris@18 305 $assert_session->statusCodeEquals(200);
Chris@18 306
Chris@18 307 // Make sure anonymous users can not access unpublished media
Chris@18 308 // even though role has 'view own unpublished media' permission.
Chris@18 309 $user_media->setUnpublished()->save();
Chris@18 310 $this->drupalGet('media/' . $user_media->id());
Chris@18 311 $assert_session->statusCodeEquals(403);
Chris@18 312 $this->assertCacheContext('user');
Chris@18 313 }
Chris@18 314
Chris@18 315 /**
Chris@18 316 * Tests access for embedded medias.
Chris@18 317 */
Chris@18 318 public function testReferencedRendering() {
Chris@18 319 \Drupal::configFactory()
Chris@18 320 ->getEditable('media.settings')
Chris@18 321 ->set('standalone_url', TRUE)
Chris@18 322 ->save(TRUE);
Chris@18 323
Chris@18 324 $this->container->get('router.builder')->rebuild();
Chris@18 325
Chris@18 326 // Create a media type and a entity reference to itself.
Chris@18 327 $media_type = $this->createMediaType('test');
Chris@18 328
Chris@18 329 FieldStorageConfig::create([
Chris@18 330 'field_name' => 'field_reference',
Chris@18 331 'entity_type' => 'media',
Chris@18 332 'type' => 'entity_reference',
Chris@18 333 'settings' => [
Chris@18 334 'target_type' => 'media',
Chris@18 335 ],
Chris@18 336 ])->save();
Chris@18 337
Chris@18 338 FieldConfig::create([
Chris@18 339 'field_name' => 'field_reference',
Chris@18 340 'entity_type' => 'media',
Chris@18 341 'bundle' => $media_type->id(),
Chris@18 342 ])->save();
Chris@18 343
Chris@18 344 $author = $this->drupalCreateUser([
Chris@18 345 'view media',
Chris@18 346 'view own unpublished media',
Chris@18 347 ]);
Chris@18 348 $other_user = $this->drupalCreateUser([
Chris@18 349 'view media',
Chris@18 350 'view own unpublished media',
Chris@18 351 ]);
Chris@18 352 $view_user = $this->drupalCreateUser(['view media']);
Chris@18 353
Chris@18 354 $child_title = 'Child media';
Chris@18 355 $media_child = Media::create([
Chris@18 356 'name' => $child_title,
Chris@18 357 'bundle' => $media_type->id(),
Chris@18 358 'uid' => $author->id(),
Chris@18 359 ]);
Chris@18 360 $media_child->setUnpublished()->save();
Chris@18 361
Chris@18 362 $media_parent = Media::create([
Chris@18 363 'name' => 'Parent media',
Chris@18 364 'bundle' => $media_type->id(),
Chris@18 365 'field_reference' => $media_child->id(),
Chris@18 366 ]);
Chris@18 367 $media_parent->save();
Chris@18 368
Chris@18 369 entity_get_display('media', $media_type->id(), 'full')
Chris@18 370 ->set('content', [])
Chris@18 371 ->setComponent('title', ['type' => 'string'])
Chris@18 372 ->setComponent('field_reference', [
Chris@18 373 'type' => 'entity_reference_label',
Chris@18 374 ])
Chris@18 375 ->save();
Chris@18 376
Chris@18 377 $assert_session = $this->assertSession();
Chris@18 378
Chris@18 379 // The author of the child media items should have access to both the parent
Chris@18 380 // and child.
Chris@18 381 $this->drupalLogin($author);
Chris@18 382 $this->drupalGet($media_parent->toUrl());
Chris@18 383 $this->assertCacheContext('user');
Chris@18 384 $assert_session->pageTextContains($child_title);
Chris@18 385
Chris@18 386 // Other users with the 'view own unpublished media' permission should not
Chris@18 387 // be able to see the unpublished child media item. The 'user' cache context
Chris@18 388 // should be added in this case.
Chris@18 389 $this->drupalLogin($other_user);
Chris@18 390 $this->drupalGet($media_parent->toUrl());
Chris@18 391 $this->assertCacheContext('user');
Chris@18 392 $assert_session->pageTextNotContains($child_title);
Chris@18 393
Chris@18 394 // User with just the 'view media' permission should not be able to see the
Chris@18 395 // child media item. The 'user' cache context should not be added in this
Chris@18 396 // case.
Chris@18 397 $this->drupalLogin($view_user);
Chris@18 398 $this->drupalGet($media_parent->toUrl());
Chris@18 399 $this->assertNoCacheContext('user');
Chris@18 400 $assert_session->pageTextNotContains($child_title);
Chris@18 401 }
Chris@18 402
Chris@0 403 }