Loading core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php +6 −2 Original line number Diff line number Diff line Loading @@ -310,13 +310,17 @@ public function validateAndParseContentDispositionHeader(Request $request) { * @param \Drupal\Core\Entity\EntityInterface $entity * (optional) The entity to which the file is to be uploaded, if it exists. * If the entity does not exist and it is not given, create access to the * file will be checked. * entity the file is attached to will be checked. * * @return \Drupal\Core\Access\AccessResultInterface * The file upload access result. */ public static function checkFileUploadAccess(AccountInterface $account, FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL) { assert(is_null($entity) || $field_definition->getTargetEntityTypeId() === $entity->getEntityTypeId() && $field_definition->getTargetBundle() === $entity->bundle()); assert(is_null($entity) || $field_definition->getTargetEntityTypeId() === $entity->getEntityTypeId() && // Base fields do not have target bundles. (is_null($field_definition->getTargetBundle()) || $field_definition->getTargetBundle() === $entity->bundle()) ); $entity_type_manager = \Drupal::entityTypeManager(); $entity_access_control_handler = $entity_type_manager->getAccessControlHandler($field_definition->getTargetEntityTypeId()); $bundle = $entity_type_manager->getDefinition($field_definition->getTargetEntityTypeId())->hasKey('bundle') ? $field_definition->getTargetBundle() : NULL; Loading core/modules/jsonapi/tests/src/Kernel/Controller/TemporaryJsonapiFileFieldUploaderTest.php 0 → 100644 +179 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\jsonapi\Kernel\Controller; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\jsonapi\Controller\TemporaryJsonapiFileFieldUploader; use Drupal\node\Entity\Node; use Drupal\node\Entity\NodeType; use Drupal\Tests\jsonapi\Kernel\JsonapiKernelTestBase; use Drupal\user\Entity\Role; use Drupal\user\Entity\User; /** * @coversDefaultClass \Drupal\jsonapi\Controller\TemporaryJsonapiFileFieldUploader * @group jsonapi */ class TemporaryJsonapiFileFieldUploaderTest extends JsonapiKernelTestBase { /** * {@inheritdoc} */ protected static $modules = [ 'node', 'field', 'jsonapi', 'serialization', 'system', 'user', ]; /** * {@inheritdoc} */ protected function setUp(): void { parent::setUp(); // Add the entity schemas. $this->installEntitySchema('node'); $this->installEntitySchema('user'); // Add the additional table schemas. $this->installSchema('system', ['sequences']); $this->installSchema('node', ['node_access']); $this->installSchema('user', ['users_data']); NodeType::create([ 'type' => 'lorem', ])->save(); $type = NodeType::create([ 'type' => 'article', ]); $type->save(); $type = NodeType::create([ 'type' => 'page', ]); $type->save(); $this->createEntityReferenceField('node', 'article', 'field_relationships', 'Relationship', 'node', 'default', ['target_bundles' => ['article']], FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); Role::create([ 'id' => 'article editor', 'label' => 'article editor', 'permissions' => [ 'access content', 'create article content', 'edit any article content', ], ])->save(); Role::create([ 'id' => 'page editor', 'label' => 'page editor', 'permissions' => [ 'access content', 'create page content', 'edit any page content', ], ])->save(); Role::create([ 'id' => 'editor', 'label' => 'editor', 'permissions' => [ 'bypass node access', ], ])->save(); } /** * @covers ::checkFileUploadAccess */ public function testCheckFileUploadAccessWithBaseField() { // Create a set of users for access testing. $article_editor = User::create([ 'name' => 'article editor', 'mail' => 'article@localhost', 'status' => 1, // Do not use UID 1 as that has access to everything. 'uid' => 2, 'roles' => ['article editor'], ]); $page_editor = User::create([ 'name' => 'page editor', 'mail' => 'page@localhost', 'status' => 1, 'uid' => 3, 'roles' => ['page editor'], ]); $editor = User::create([ 'name' => 'editor', 'mail' => 'editor@localhost', 'status' => 1, 'uid' => 3, 'roles' => ['editor'], ]); $no_access_user = User::create([ 'name' => 'no access', 'mail' => 'user@localhost', 'status' => 1, 'uid' => 4, ]); // Create an entity to test access against. $node = Node::create([ 'title' => 'dummy_title', 'type' => 'article', 'uid' => 1, ]); // While the method is only used to check file fields it should work without // error for any field whether it is a base field or a bundle field. $base_field_definition = $this->container->get('entity_field.manager')->getBaseFieldDefinitions('node')['title']; $bundle_field_definition = $this->container->get('entity_field.manager')->getFieldDefinitions('node', 'article')['field_relationships']; // Tests the expected access result for each user. // The $article_editor account can edit any article. $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($article_editor, $base_field_definition, $node); $this->assertTrue($result->isAllowed()); // The article editor cannot create a node of undetermined type. $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($article_editor, $base_field_definition); $this->assertFalse($result->isAllowed()); // The article editor can edit any article. $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($article_editor, $bundle_field_definition, $node); $this->assertTrue($result->isAllowed()); // The article editor can create an article. The type can be determined // because the field is a bundle field. $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($article_editor, $bundle_field_definition); $this->assertTrue($result->isAllowed()); // The $editor account has the bypass node access permissions and can edit // and create all node types. $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($editor, $base_field_definition, $node); $this->assertTrue($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($editor, $base_field_definition); $this->assertTrue($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($editor, $bundle_field_definition, $node); $this->assertTrue($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($editor, $bundle_field_definition); $this->assertTrue($result->isAllowed()); // The $page_editor account can only edit and create pages therefore has no // access. $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($page_editor, $base_field_definition, $node); $this->assertFalse($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($page_editor, $base_field_definition); $this->assertFalse($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($page_editor, $bundle_field_definition, $node); $this->assertFalse($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($page_editor, $bundle_field_definition); $this->assertFalse($result->isAllowed()); // The $no_access_user account has no access at all. $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($no_access_user, $base_field_definition, $node); $this->assertFalse($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($no_access_user, $base_field_definition); $this->assertFalse($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($no_access_user, $bundle_field_definition, $node); $this->assertFalse($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($no_access_user, $bundle_field_definition); $this->assertFalse($result->isAllowed()); } } Loading
core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php +6 −2 Original line number Diff line number Diff line Loading @@ -310,13 +310,17 @@ public function validateAndParseContentDispositionHeader(Request $request) { * @param \Drupal\Core\Entity\EntityInterface $entity * (optional) The entity to which the file is to be uploaded, if it exists. * If the entity does not exist and it is not given, create access to the * file will be checked. * entity the file is attached to will be checked. * * @return \Drupal\Core\Access\AccessResultInterface * The file upload access result. */ public static function checkFileUploadAccess(AccountInterface $account, FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL) { assert(is_null($entity) || $field_definition->getTargetEntityTypeId() === $entity->getEntityTypeId() && $field_definition->getTargetBundle() === $entity->bundle()); assert(is_null($entity) || $field_definition->getTargetEntityTypeId() === $entity->getEntityTypeId() && // Base fields do not have target bundles. (is_null($field_definition->getTargetBundle()) || $field_definition->getTargetBundle() === $entity->bundle()) ); $entity_type_manager = \Drupal::entityTypeManager(); $entity_access_control_handler = $entity_type_manager->getAccessControlHandler($field_definition->getTargetEntityTypeId()); $bundle = $entity_type_manager->getDefinition($field_definition->getTargetEntityTypeId())->hasKey('bundle') ? $field_definition->getTargetBundle() : NULL; Loading
core/modules/jsonapi/tests/src/Kernel/Controller/TemporaryJsonapiFileFieldUploaderTest.php 0 → 100644 +179 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\jsonapi\Kernel\Controller; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\jsonapi\Controller\TemporaryJsonapiFileFieldUploader; use Drupal\node\Entity\Node; use Drupal\node\Entity\NodeType; use Drupal\Tests\jsonapi\Kernel\JsonapiKernelTestBase; use Drupal\user\Entity\Role; use Drupal\user\Entity\User; /** * @coversDefaultClass \Drupal\jsonapi\Controller\TemporaryJsonapiFileFieldUploader * @group jsonapi */ class TemporaryJsonapiFileFieldUploaderTest extends JsonapiKernelTestBase { /** * {@inheritdoc} */ protected static $modules = [ 'node', 'field', 'jsonapi', 'serialization', 'system', 'user', ]; /** * {@inheritdoc} */ protected function setUp(): void { parent::setUp(); // Add the entity schemas. $this->installEntitySchema('node'); $this->installEntitySchema('user'); // Add the additional table schemas. $this->installSchema('system', ['sequences']); $this->installSchema('node', ['node_access']); $this->installSchema('user', ['users_data']); NodeType::create([ 'type' => 'lorem', ])->save(); $type = NodeType::create([ 'type' => 'article', ]); $type->save(); $type = NodeType::create([ 'type' => 'page', ]); $type->save(); $this->createEntityReferenceField('node', 'article', 'field_relationships', 'Relationship', 'node', 'default', ['target_bundles' => ['article']], FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); Role::create([ 'id' => 'article editor', 'label' => 'article editor', 'permissions' => [ 'access content', 'create article content', 'edit any article content', ], ])->save(); Role::create([ 'id' => 'page editor', 'label' => 'page editor', 'permissions' => [ 'access content', 'create page content', 'edit any page content', ], ])->save(); Role::create([ 'id' => 'editor', 'label' => 'editor', 'permissions' => [ 'bypass node access', ], ])->save(); } /** * @covers ::checkFileUploadAccess */ public function testCheckFileUploadAccessWithBaseField() { // Create a set of users for access testing. $article_editor = User::create([ 'name' => 'article editor', 'mail' => 'article@localhost', 'status' => 1, // Do not use UID 1 as that has access to everything. 'uid' => 2, 'roles' => ['article editor'], ]); $page_editor = User::create([ 'name' => 'page editor', 'mail' => 'page@localhost', 'status' => 1, 'uid' => 3, 'roles' => ['page editor'], ]); $editor = User::create([ 'name' => 'editor', 'mail' => 'editor@localhost', 'status' => 1, 'uid' => 3, 'roles' => ['editor'], ]); $no_access_user = User::create([ 'name' => 'no access', 'mail' => 'user@localhost', 'status' => 1, 'uid' => 4, ]); // Create an entity to test access against. $node = Node::create([ 'title' => 'dummy_title', 'type' => 'article', 'uid' => 1, ]); // While the method is only used to check file fields it should work without // error for any field whether it is a base field or a bundle field. $base_field_definition = $this->container->get('entity_field.manager')->getBaseFieldDefinitions('node')['title']; $bundle_field_definition = $this->container->get('entity_field.manager')->getFieldDefinitions('node', 'article')['field_relationships']; // Tests the expected access result for each user. // The $article_editor account can edit any article. $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($article_editor, $base_field_definition, $node); $this->assertTrue($result->isAllowed()); // The article editor cannot create a node of undetermined type. $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($article_editor, $base_field_definition); $this->assertFalse($result->isAllowed()); // The article editor can edit any article. $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($article_editor, $bundle_field_definition, $node); $this->assertTrue($result->isAllowed()); // The article editor can create an article. The type can be determined // because the field is a bundle field. $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($article_editor, $bundle_field_definition); $this->assertTrue($result->isAllowed()); // The $editor account has the bypass node access permissions and can edit // and create all node types. $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($editor, $base_field_definition, $node); $this->assertTrue($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($editor, $base_field_definition); $this->assertTrue($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($editor, $bundle_field_definition, $node); $this->assertTrue($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($editor, $bundle_field_definition); $this->assertTrue($result->isAllowed()); // The $page_editor account can only edit and create pages therefore has no // access. $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($page_editor, $base_field_definition, $node); $this->assertFalse($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($page_editor, $base_field_definition); $this->assertFalse($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($page_editor, $bundle_field_definition, $node); $this->assertFalse($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($page_editor, $bundle_field_definition); $this->assertFalse($result->isAllowed()); // The $no_access_user account has no access at all. $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($no_access_user, $base_field_definition, $node); $this->assertFalse($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($no_access_user, $base_field_definition); $this->assertFalse($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($no_access_user, $bundle_field_definition, $node); $this->assertFalse($result->isAllowed()); $result = TemporaryJsonapiFileFieldUploader::checkFileUploadAccess($no_access_user, $bundle_field_definition); $this->assertFalse($result->isAllowed()); } }