Chris@0: drupalPlaceBlock('local_tasks_block'); Chris@14: } Chris@14: Chris@14: /** Chris@0: * Test some access control functionality. Chris@0: */ Chris@0: public function testMediaAccess() { Chris@0: $assert_session = $this->assertSession(); Chris@18: $media_type = $this->createMediaType('test'); Chris@0: Chris@18: \Drupal::configFactory() Chris@18: ->getEditable('media.settings') Chris@18: ->set('standalone_url', TRUE) Chris@18: ->save(TRUE); Chris@18: Chris@18: $this->container->get('router.builder')->rebuild(); Chris@0: Chris@0: // Create media. Chris@0: $media = Media::create([ Chris@0: 'bundle' => $media_type->id(), Chris@0: 'name' => 'Unnamed', Chris@0: ]); Chris@0: $media->save(); Chris@0: $user_media = Media::create([ Chris@0: 'bundle' => $media_type->id(), Chris@0: 'name' => 'Unnamed', Chris@0: 'uid' => $this->nonAdminUser->id(), Chris@0: ]); Chris@0: $user_media->save(); Chris@0: Chris@0: // We are logged in as admin, so test 'administer media' permission. Chris@0: $this->drupalGet('media/add/' . $media_type->id()); Chris@0: $this->assertCacheContext('user.permissions'); Chris@0: $assert_session->statusCodeEquals(200); Chris@0: $this->drupalGet('media/' . $user_media->id()); Chris@0: $this->assertCacheContext('user.permissions'); Chris@0: $assert_session->statusCodeEquals(200); Chris@0: $this->drupalGet('media/' . $user_media->id() . '/edit'); Chris@0: $this->assertCacheContext('user.permissions'); Chris@0: $assert_session->statusCodeEquals(200); Chris@0: $this->drupalGet('media/' . $user_media->id() . '/delete'); Chris@0: $this->assertCacheContext('user.permissions'); Chris@0: $assert_session->statusCodeEquals(200); Chris@0: Chris@0: $this->drupalLogin($this->nonAdminUser); Chris@0: /** @var \Drupal\user\RoleInterface $role */ Chris@0: $role = Role::load(RoleInterface::AUTHENTICATED_ID); Chris@0: Chris@0: user_role_revoke_permissions($role->id(), ['view media']); Chris@0: Chris@14: // Test 'create BUNDLE media' permission. Chris@14: $this->drupalGet('media/add/' . $media_type->id()); Chris@14: $this->assertCacheContext('user.permissions'); Chris@14: $assert_session->statusCodeEquals(403); Chris@14: $permissions = ['create ' . $media_type->id() . ' media']; Chris@14: $this->grantPermissions($role, $permissions); Chris@14: $this->drupalGet('media/add/' . $media_type->id()); Chris@14: $this->assertCacheContext('user.permissions'); Chris@14: $assert_session->statusCodeEquals(200); Chris@14: user_role_revoke_permissions($role->id(), $permissions); Chris@14: $role = Role::load(RoleInterface::AUTHENTICATED_ID); Chris@14: Chris@18: // Verify the author can not view the unpublished media item without Chris@18: // 'view own unpublished media' permission. Chris@18: $this->grantPermissions($role, ['view media']); Chris@18: $this->drupalGet('media/' . $user_media->id()); Chris@18: $this->assertNoCacheContext('user'); Chris@18: $this->assertCacheContext('user.permissions'); Chris@18: $assert_session->statusCodeEquals(200); Chris@18: $user_media->setUnpublished()->save(); Chris@18: $this->drupalGet('media/' . $user_media->id()); Chris@18: $this->assertCacheContext('user.permissions'); Chris@18: $assert_session->statusCodeEquals(403); Chris@18: $access_result = $user_media->access('view', NULL, TRUE); Chris@18: $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: $this->grantPermissions($role, ['view own unpublished media']); Chris@18: $this->drupalGet('media/' . $user_media->id()); Chris@18: $this->assertCacheContext('user'); Chris@18: $assert_session->statusCodeEquals(200); Chris@18: Chris@0: // Test 'create media' permission. Chris@0: $this->drupalGet('media/add/' . $media_type->id()); Chris@0: $this->assertCacheContext('user.permissions'); Chris@0: $assert_session->statusCodeEquals(403); Chris@14: $permissions = ['create media']; Chris@14: $this->grantPermissions($role, $permissions); Chris@0: $this->drupalGet('media/add/' . $media_type->id()); Chris@0: $this->assertCacheContext('user.permissions'); Chris@0: $assert_session->statusCodeEquals(200); Chris@14: user_role_revoke_permissions($role->id(), $permissions); Chris@14: $role = Role::load(RoleInterface::AUTHENTICATED_ID); Chris@0: Chris@14: // Test 'edit own BUNDLE media' and 'delete own BUNDLE media' permissions. Chris@0: $this->drupalGet('media/' . $user_media->id() . '/edit'); Chris@14: $this->assertCacheContext('user.permissions'); Chris@0: $assert_session->statusCodeEquals(403); Chris@0: $this->drupalGet('media/' . $user_media->id() . '/delete'); Chris@14: $this->assertCacheContext('user.permissions'); Chris@0: $assert_session->statusCodeEquals(403); Chris@14: $permissions = [ Chris@14: 'edit own ' . $user_media->bundle() . ' media', Chris@14: 'delete own ' . $user_media->bundle() . ' media', Chris@14: ]; Chris@14: $this->grantPermissions($role, $permissions); Chris@0: $this->drupalGet('media/' . $user_media->id() . '/edit'); Chris@0: $this->assertCacheContext('user'); Chris@0: $assert_session->statusCodeEquals(200); Chris@0: $this->drupalGet('media/' . $user_media->id() . '/delete'); Chris@0: $this->assertCacheContext('user'); Chris@0: $assert_session->statusCodeEquals(200); Chris@14: user_role_revoke_permissions($role->id(), $permissions); Chris@14: $role = Role::load(RoleInterface::AUTHENTICATED_ID); Chris@0: Chris@14: // Test 'edit any BUNDLE media' and 'delete any BUNDLE media' permissions. Chris@0: $this->drupalGet('media/' . $media->id() . '/edit'); Chris@14: $this->assertCacheContext('user.permissions'); Chris@0: $assert_session->statusCodeEquals(403); Chris@0: $this->drupalGet('media/' . $media->id() . '/delete'); Chris@14: $this->assertCacheContext('user.permissions'); Chris@0: $assert_session->statusCodeEquals(403); Chris@14: $permissions = [ Chris@14: 'edit any ' . $media->bundle() . ' media', Chris@14: 'delete any ' . $media->bundle() . ' media', Chris@14: ]; Chris@14: $this->grantPermissions($role, $permissions); Chris@0: $this->drupalGet('media/' . $media->id() . '/edit'); Chris@0: $this->assertCacheContext('user.permissions'); Chris@0: $assert_session->statusCodeEquals(200); Chris@0: $this->drupalGet('media/' . $media->id() . '/delete'); Chris@0: $this->assertCacheContext('user.permissions'); Chris@0: $assert_session->statusCodeEquals(200); Chris@0: Chris@0: // Test the 'access media overview' permission. Chris@0: $this->grantPermissions($role, ['access content overview']); Chris@0: $this->drupalGet('admin/content'); Chris@0: $assert_session->linkByHrefNotExists('/admin/content/media'); Chris@0: $this->assertCacheContext('user'); Chris@0: Chris@0: // Create a new role, which implicitly checks if the permission exists. Chris@0: $mediaOverviewRole = $this->createRole(['access content overview', 'access media overview']); Chris@0: $this->nonAdminUser->addRole($mediaOverviewRole); Chris@0: $this->nonAdminUser->save(); Chris@0: Chris@0: $this->drupalGet('admin/content'); Chris@0: $assert_session->linkByHrefExists('/admin/content/media'); Chris@0: $this->clickLink('Media'); Chris@0: $this->assertCacheContext('user.permissions'); Chris@0: $assert_session->statusCodeEquals(200); Chris@0: $assert_session->elementExists('css', '.view-media'); Chris@0: $assert_session->pageTextContains($this->loggedInUser->getDisplayName()); Chris@0: $assert_session->pageTextContains($this->nonAdminUser->getDisplayName()); Chris@0: $assert_session->linkByHrefExists('/media/' . $media->id()); Chris@0: $assert_session->linkByHrefExists('/media/' . $user_media->id()); Chris@0: } Chris@0: Chris@18: /** Chris@18: * Test view access control on the canonical page. Chris@18: */ Chris@18: public function testCanonicalMediaAccess() { Chris@18: $media_type = $this->createMediaType('test'); Chris@18: $assert_session = $this->assertSession(); Chris@18: Chris@18: \Drupal::configFactory() Chris@18: ->getEditable('media.settings') Chris@18: ->set('standalone_url', TRUE) Chris@18: ->save(TRUE); Chris@18: Chris@18: $this->container->get('router.builder')->rebuild(); Chris@18: Chris@18: // Create media. Chris@18: $media = Media::create([ Chris@18: 'bundle' => $media_type->id(), Chris@18: 'name' => 'Unnamed', Chris@18: ]); Chris@18: $media->save(); Chris@18: $user_media = Media::create([ Chris@18: 'bundle' => $media_type->id(), Chris@18: 'name' => 'Unnamed', Chris@18: 'uid' => $this->nonAdminUser->id(), Chris@18: ]); Chris@18: $user_media->save(); Chris@18: Chris@18: $this->drupalLogin($this->nonAdminUser); Chris@18: /** @var \Drupal\user\RoleInterface $role */ Chris@18: $role = Role::load(RoleInterface::AUTHENTICATED_ID); Chris@18: Chris@18: user_role_revoke_permissions($role->id(), ['view media']); Chris@18: Chris@18: $this->drupalGet('media/' . $media->id()); Chris@18: $this->assertCacheContext('user.permissions'); Chris@18: $assert_session->statusCodeEquals(403); Chris@18: $access_result = $media->access('view', NULL, TRUE); Chris@18: $this->assertSame("The 'view media' permission is required when the media item is published.", $access_result->getReason()); Chris@18: $this->grantPermissions($role, ['view media']); Chris@18: $this->drupalGet('media/' . $media->id()); Chris@18: $this->assertCacheContext('user.permissions'); Chris@18: $assert_session->statusCodeEquals(200); Chris@18: } Chris@18: Chris@18: /** Chris@18: * Tests unpublished media access. Chris@18: */ Chris@18: public function testUnpublishedMediaUserAccess() { Chris@18: \Drupal::configFactory() Chris@18: ->getEditable('media.settings') Chris@18: ->set('standalone_url', TRUE) Chris@18: ->save(TRUE); Chris@18: Chris@18: $this->container->get('router.builder')->rebuild(); Chris@18: Chris@18: $assert_session = $this->assertSession(); Chris@18: $media_type = $this->createMediaType('test'); Chris@18: $permissions = [ Chris@18: 'view media', Chris@18: 'view own unpublished media', Chris@18: ]; Chris@18: $user_one = $this->drupalCreateUser($permissions); Chris@18: $user_two = $this->drupalCreateUser($permissions); Chris@18: Chris@18: // Create media as user one. Chris@18: $user_media = Media::create([ Chris@18: 'bundle' => $media_type->id(), Chris@18: 'name' => 'Unnamed', Chris@18: 'uid' => $user_one->id(), Chris@18: ]); Chris@18: $user_media->setUnpublished()->save(); Chris@18: Chris@18: // Make sure user two can't access unpublished media. Chris@18: $this->drupalLogin($user_two); Chris@18: $this->drupalGet('media/' . $user_media->id()); Chris@18: $assert_session->statusCodeEquals(403); Chris@18: $this->assertCacheContext('user'); Chris@18: $this->drupalLogout(); Chris@18: Chris@18: // Make sure user one can access own unpublished media. Chris@18: $this->drupalLogin($user_one); Chris@18: $this->drupalGet('media/' . $user_media->id()); Chris@18: $assert_session->statusCodeEquals(200); Chris@18: $this->assertCacheContext('user'); Chris@18: } Chris@18: Chris@18: /** Chris@18: * Tests media access of anonymous user. Chris@18: */ Chris@18: public function testMediaAnonymousUserAccess() { Chris@18: \Drupal::configFactory() Chris@18: ->getEditable('media.settings') Chris@18: ->set('standalone_url', TRUE) Chris@18: ->save(TRUE); Chris@18: Chris@18: $this->container->get('router.builder')->rebuild(); Chris@18: Chris@18: $assert_session = $this->assertSession(); Chris@18: $media_type = $this->createMediaType('test'); Chris@18: Chris@18: // Create media as anonymous user. Chris@18: $user_media = Media::create([ Chris@18: 'bundle' => $media_type->id(), Chris@18: 'name' => 'Unnamed', Chris@18: 'uid' => 0, Chris@18: ]); Chris@18: $user_media->save(); Chris@18: Chris@18: $role = Role::load(RoleInterface::ANONYMOUS_ID); Chris@18: $this->grantPermissions($role, ['view media', 'view own unpublished media']); Chris@18: $this->drupalLogout(); Chris@18: Chris@18: // Make sure anonymous users can access published media. Chris@18: $user_media->setPublished()->save(); Chris@18: $this->drupalGet('media/' . $user_media->id()); Chris@18: $assert_session->statusCodeEquals(200); Chris@18: Chris@18: // Make sure anonymous users can not access unpublished media Chris@18: // even though role has 'view own unpublished media' permission. Chris@18: $user_media->setUnpublished()->save(); Chris@18: $this->drupalGet('media/' . $user_media->id()); Chris@18: $assert_session->statusCodeEquals(403); Chris@18: $this->assertCacheContext('user'); Chris@18: } Chris@18: Chris@18: /** Chris@18: * Tests access for embedded medias. Chris@18: */ Chris@18: public function testReferencedRendering() { Chris@18: \Drupal::configFactory() Chris@18: ->getEditable('media.settings') Chris@18: ->set('standalone_url', TRUE) Chris@18: ->save(TRUE); Chris@18: Chris@18: $this->container->get('router.builder')->rebuild(); Chris@18: Chris@18: // Create a media type and a entity reference to itself. Chris@18: $media_type = $this->createMediaType('test'); Chris@18: Chris@18: FieldStorageConfig::create([ Chris@18: 'field_name' => 'field_reference', Chris@18: 'entity_type' => 'media', Chris@18: 'type' => 'entity_reference', Chris@18: 'settings' => [ Chris@18: 'target_type' => 'media', Chris@18: ], Chris@18: ])->save(); Chris@18: Chris@18: FieldConfig::create([ Chris@18: 'field_name' => 'field_reference', Chris@18: 'entity_type' => 'media', Chris@18: 'bundle' => $media_type->id(), Chris@18: ])->save(); Chris@18: Chris@18: $author = $this->drupalCreateUser([ Chris@18: 'view media', Chris@18: 'view own unpublished media', Chris@18: ]); Chris@18: $other_user = $this->drupalCreateUser([ Chris@18: 'view media', Chris@18: 'view own unpublished media', Chris@18: ]); Chris@18: $view_user = $this->drupalCreateUser(['view media']); Chris@18: Chris@18: $child_title = 'Child media'; Chris@18: $media_child = Media::create([ Chris@18: 'name' => $child_title, Chris@18: 'bundle' => $media_type->id(), Chris@18: 'uid' => $author->id(), Chris@18: ]); Chris@18: $media_child->setUnpublished()->save(); Chris@18: Chris@18: $media_parent = Media::create([ Chris@18: 'name' => 'Parent media', Chris@18: 'bundle' => $media_type->id(), Chris@18: 'field_reference' => $media_child->id(), Chris@18: ]); Chris@18: $media_parent->save(); Chris@18: Chris@18: entity_get_display('media', $media_type->id(), 'full') Chris@18: ->set('content', []) Chris@18: ->setComponent('title', ['type' => 'string']) Chris@18: ->setComponent('field_reference', [ Chris@18: 'type' => 'entity_reference_label', Chris@18: ]) Chris@18: ->save(); Chris@18: Chris@18: $assert_session = $this->assertSession(); Chris@18: Chris@18: // The author of the child media items should have access to both the parent Chris@18: // and child. Chris@18: $this->drupalLogin($author); Chris@18: $this->drupalGet($media_parent->toUrl()); Chris@18: $this->assertCacheContext('user'); Chris@18: $assert_session->pageTextContains($child_title); Chris@18: Chris@18: // Other users with the 'view own unpublished media' permission should not Chris@18: // be able to see the unpublished child media item. The 'user' cache context Chris@18: // should be added in this case. Chris@18: $this->drupalLogin($other_user); Chris@18: $this->drupalGet($media_parent->toUrl()); Chris@18: $this->assertCacheContext('user'); Chris@18: $assert_session->pageTextNotContains($child_title); Chris@18: Chris@18: // User with just the 'view media' permission should not be able to see the Chris@18: // child media item. The 'user' cache context should not be added in this Chris@18: // case. Chris@18: $this->drupalLogin($view_user); Chris@18: $this->drupalGet($media_parent->toUrl()); Chris@18: $this->assertNoCacheContext('user'); Chris@18: $assert_session->pageTextNotContains($child_title); Chris@18: } Chris@18: Chris@0: }