Unverified Commit 37b75b1f authored by Lee Rowlands's avatar Lee Rowlands Committed by Lee Rowlands
Browse files

Issue #2907558 by larowlan, kasperg: Do not require administer blocks...

Issue #2907558 by larowlan, kasperg: Do not require administer blocks permission to access creation form
parent c5fb8ac6
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
services:
  block_access.route_subscriber:
    class: Drupal\block_access\Routing\RouteSubscriber
    tags:
      - { name: event_subscriber }
  block_access.access_check:
    class: Drupal\block_access\Access\CreateBlockContentTypeCheck
    tags:
      - { name: access_check, applies_to: _block_content_access_create }
+38 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\block_access\Access;

use Drupal\block_content\BlockContentTypeInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Routing\Access\AccessInterface;
use Drupal\Core\Session\AccountInterface;

/**
 * Access control for creation of specific types of block content.
 */
class CreateBlockContentTypeCheck implements AccessInterface {

  /**
   * Determine if a user is allowed to create a specific type of block content.
   *
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The user attempting to create the content.
   * @param \Drupal\block_content\BlockContentTypeInterface $block_content_type
   *   The type of block content to be created.
   *
   * @return \Drupal\Core\Access\AccessResult
   *   Whether the user is allowed to create the content.
   */
  public function access(AccountInterface $account, BlockContentTypeInterface $block_content_type) {
    return AccessResult::allowedIfHasPermissions(
      $account,
      [
        // Default permission to manage all block content types.
        'administer blocks',
        // This is the new per content type permission we have added.
        sprintf('create %s block_content', $block_content_type->id())
      ],
      'OR'
    );
  }
}
+32 −0
Original line number Diff line number Diff line
<?php

/**
 * @file
 * Contains \Drupal\block_access\Routing\RouteSubscriber.
 */

namespace Drupal\block_access\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Listens to the dynamic route events.
 */
class RouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  public function alterRoutes(RouteCollection $collection) {
    // Replace the default permission check for "administer blocks" with our
    // own which will also support permissions to create individual types of
    // block content.
    if ($route = $collection->get('block_content.add_form')) {
      $requirements = $route->getRequirements();
      unset($requirements['_permission']);
      $requirements['_block_content_access_create'] = 'true';
      $route->setRequirements($requirements);
    }
  }
}
+50 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\Tests\block_access\Functional;

use Drupal\block_content\Entity\BlockContentType;
use Drupal\Tests\BrowserTestBase;

/**
 * Tests access to the block add form.
 *
 * @group block_access
 */
final class BlockAddFormAccessTest extends BrowserTestBase {

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'block_content',
    'block',
    'block_access',
  ];

  /**
   * Test block add form.
   */
  public function testBlockAddForm(): void {
    $block_type = BlockContentType::create([
      'id' => 'foo',
      'label' => 'Foo',
    ]);
    $block_type->save();
    $this->drupalGet('block/add/foo');
    $assert = $this->assertSession();
    $assert->statusCodeEquals(403);
    $this->drupalLogin($this->createUser([
      'create foo block_content',
    ]));
    $this->drupalGet('block/add/foo');
    $assert->statusCodeEquals(200);
  }

}