Commit 60718c0f authored by catch's avatar catch
Browse files

Issue #3048760 by Upchuk, ndobromirov, seanB, hchonov, bkosborne, Berdir:...

Issue #3048760 by Upchuk, ndobromirov, seanB, hchonov, bkosborne, Berdir: EntityCreateAnyAccessCheck::access() too restrictive

(cherry picked from commit ee7aaf22)
parent fba5e54e
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
namespace Drupal\Core\Entity;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Access\AccessResultReasonInterface;
use Drupal\Core\Routing\Access\AccessInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;
@@ -92,11 +93,16 @@ public function access(Route $route, RouteMatchInterface $route_match, AccountIn

    // Check whether an entity of any bundle may be created.
    foreach ($bundles as $bundle) {
      $access = $access->orIf($access_control_handler->createAccess($bundle, $account, [], TRUE));
      // In case there is a least one bundle user can create entities for,
      $bundle_access = $access_control_handler->createAccess($bundle, $account, [], TRUE);
      $access->inheritCacheability($bundle_access);
      if ($bundle_access instanceof AccessResultReasonInterface && $bundle_access->getReason() !== "" && $access->getReason() === "") {
        $access->setReason($bundle_access->getReason());
      }

      // In case there is at least one bundle the user can create entities for,
      // access is allowed.
      if ($access->isAllowed()) {
        break;
      if ($bundle_access->isAllowed()) {
        return AccessResult::allowed()->inheritCacheability($access);
      }
    }

+6 −0
Original line number Diff line number Diff line
@@ -777,6 +777,12 @@ function entity_test_entity_create_access(AccountInterface $account, $context, $
  \Drupal::state()->set('entity_test_entity_create_access', TRUE);
  \Drupal::state()->set('entity_test_entity_create_access_context', $context);

  if ($entity_bundle === 'forbidden_access_bundle') {
    // We need to cover a case in which a bundle is specifically forbidden
    // from creation (as opposed to neutral access).
    return AccessResult::forbidden();
  }

  // No opinion.
  return AccessResult::neutral();
}
+11 −0
Original line number Diff line number Diff line
@@ -92,9 +92,19 @@ public function testAddPageWithBundleEntities() {
      'label' => 'Test3 label',
      'description' => 'My test3 description',
    ])->save();

    // Create a bundle that the user is forbidden from creating (always).
    EntityTestBundle::create([
      'id' => 'forbidden_access_bundle',
      'label' => 'Forbidden to create bundle',
      'description' => 'A bundle that can never be created',
    ])->save();

    $this->drupalGet('/entity_test_with_bundle/add');
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->linkExists('Test label');
    $this->assertSession()->linkExists('Test2 label');
    $this->assertSession()->linkNotExists('Forbidden to create bundle');
    $this->assertSession()->linkNotExists('Test3 label');
    $this->clickLink('Test label');
    $this->assertSession()->statusCodeEquals(200);
@@ -114,6 +124,7 @@ public function testAddPageWithBundleEntities() {
    // does not have bundle specific permissions. The add bundle message is
    // present as the user has bundle create permissions.
    $this->drupalGet('/entity_test_with_bundle/add');
    $this->assertSession()->linkNotExists('Forbidden to create bundle');
    $this->assertSession()->linkNotExists('Test label');
    $this->assertSession()->linkNotExists('Test2 label');
    $this->assertSession()->linkNotExists('Test3 label');