Issue #3384600 by bsuttis, berdir, spokje, catch, benjifisher, smustgrave: Don't hide permissions local tasks on bundles when no permissions are defined

merge-requests/9429/head^2
catch 2024-09-14 08:35:09 +01:00
parent e9a2e9abfd
commit 7ed93916a6
9 changed files with 65 additions and 12 deletions

View File

@ -25,7 +25,7 @@ use Drupal\comment\CommentTypeInterface;
* "delete" = "Drupal\comment\Form\CommentTypeDeleteForm"
* },
* "route_provider" = {
* "permissions" = "Drupal\user\Entity\EntityPermissionsRouteProviderWithCheck",
* "permissions" = "Drupal\user\Entity\EntityPermissionsRouteProvider",
* },
* "list_builder" = "Drupal\comment\CommentTypeListBuilder"
* },

View File

@ -30,7 +30,7 @@ use Drupal\Core\Url;
* "delete" = "Drupal\Core\Entity\EntityDeleteForm"
* },
* "route_provider" = {
* "permissions" = "Drupal\user\Entity\EntityPermissionsRouteProviderWithCheck",
* "permissions" = "Drupal\user\Entity\EntityPermissionsRouteProvider",
* }
* },
* config_prefix = "form",

View File

@ -13,13 +13,8 @@ use Symfony\Component\Routing\RouteCollection;
/**
* Provides routes for the entity permissions form.
*
* Use this class or EntityPermissionsRouteProviderWithCheck as a route
* provider for an entity type such as Vocabulary. Either one will provide
* routes for the entity permissions form. The
* EntityPermissionsRouteProviderWithCheck class provides a custom access check:
* it denies access if there are no entity-specific permissions. If you know
* that each entity has permissions, or if the check is too expensive, then use
* this class.
* Use this class as a route provider for an entity type such as Vocabulary. It
* will provide routes for the entity permissions form.
*/
class EntityPermissionsRouteProvider implements EntityRouteProviderInterface, EntityHandlerInterface {

View File

@ -14,6 +14,10 @@ use Symfony\Component\Routing\Route;
* access if there are no entity-specific permissions. If you know that each
* entity has permissions, or if the check is too expensive, then use
* EntityPermissionsRouteProvider instead of this class.
*
* @deprecated in drupal:11.1.0 and is removed from drupal:12.0.0. Use
* EntityPermissionsRouteProvider instead.
* @see https://www.drupal.org/node/3384745
*/
class EntityPermissionsRouteProviderWithCheck extends EntityPermissionsRouteProvider {
@ -21,6 +25,7 @@ class EntityPermissionsRouteProviderWithCheck extends EntityPermissionsRouteProv
* {@inheritdoc}
*/
protected function getEntityPermissionsRoute(EntityTypeInterface $entity_type): ?Route {
@trigger_error(__CLASS__ . ' is deprecated in drupal:11.1.0 and is removed from drupal:12.0.0. Use EntityPermissionsRouteProvider instead. See https://www.drupal.org/node/3384745', E_USER_DEPRECATED);
$route = parent::getEntityPermissionsRoute($entity_type);
if ($route) {
$route->setRequirement('_custom_access', '\Drupal\user\Form\EntityPermissionsForm::access');

View File

@ -158,8 +158,13 @@ class EntityPermissionsForm extends UserPermissionsForm {
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*
* @deprecated in drupal:11.1.0 and is removed from drupal:12.0.0. Use
* a permissions check in the route definition instead.
* @see https://www.drupal.org/node/3384745
*/
public function access(Route $route, RouteMatchInterface $route_match, $bundle = NULL): AccessResultInterface {
@trigger_error(__METHOD__ . '() is deprecated in drupal:11.1.0 and is removed from drupal:12.0.0. Use a permissions check on the route definition instead. See https://www.drupal.org/node/3384745', E_USER_DEPRECATED);
$permission = $route->getRequirement('_permission');
if ($permission && !$this->currentUser()->hasPermission($permission)) {
return AccessResult::neutral()->cachePerPermissions();

View File

@ -173,6 +173,7 @@ class UserPermissionsForm extends FormBase {
$form['permissions'] = [
'#type' => 'table',
'#empty' => $this->t('No permissions found.'),
'#header' => [$this->t('Permission')],
'#id' => 'permissions',
'#attributes' => ['class' => ['permissions', 'js-permissions']],

View File

@ -272,7 +272,8 @@ class UserPermissionsTest extends BrowserTestBase {
$this->submitForm($edit, 'Save');
$this->assertSession()->pageTextContains('Contact form ' . $edit['label'] . ' has been added.');
$this->drupalGet('admin/structure/contact/manage/test_contact_type/permissions');
$this->assertSession()->statusCodeEquals(403);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextContains('No permissions found.');
// Permissions can be changed using the bundle-specific pages.
$edit = [];
@ -322,12 +323,13 @@ class UserPermissionsTest extends BrowserTestBase {
$this->drupalGet('/admin/structure/comment/manage/comment/display');
$assert_session->statusCodeEquals(200);
$this->drupalGet('/admin/structure/comment/manage/comment/permissions');
$assert_session->statusCodeEquals(403);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextContains('No permissions found.');
// Ensure there are no warnings in the log.
$this->drupalGet('/admin/reports/dblog');
$assert_session->statusCodeEquals(200);
$assert_session->pageTextContains('access denied');
$assert_session->pageTextContains('Session opened');
$assert_session->pageTextNotContains("Entity view display 'node.article.default': Component");
}

View File

@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
namespace Drupal\Tests\user\Unit\Entity;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Tests\UnitTestCase;
use Drupal\user\Entity\EntityPermissionsRouteProviderWithCheck;
/**
* Tests the route provider deprecation.
*
* @coversDefaultClass \Drupal\user\Entity\EntityPermissionsRouteProviderWithCheck
* @group user
* @group legacy
*/
class EntityPermissionsRouteProviderWithCheckTest extends UnitTestCase {
/**
* Tests the route provider deprecation.
*
* @covers ::getEntityPermissionsRoute
*
* @group legacy
*/
public function testEntityPermissionsRouteProviderWithCheck(): void {
// Mock the constructor parameters.
$prophecy = $this->prophesize(EntityTypeInterface::class);
$entity_type = $prophecy->reveal();
$prophecy = $this->prophesize(EntityTypeManagerInterface::class);
$prophecy->getDefinition('entity_type')
->willReturn($entity_type);
$entity_type_manager = $prophecy->reveal();
$this->expectDeprecation('Drupal\user\Entity\EntityPermissionsRouteProviderWithCheck is deprecated in drupal:11.1.0 and is removed from drupal:12.0.0. Use EntityPermissionsRouteProvider instead. See https://www.drupal.org/node/3384745');
(new EntityPermissionsRouteProviderWithCheck($entity_type_manager))
->getRoutes($entity_type);
}
}

View File

@ -24,6 +24,7 @@ use Symfony\Component\Routing\Route;
*
* @coversDefaultClass \Drupal\user\Form\EntityPermissionsForm
* @group user
* @group legacy
*/
class EntityPermissionsFormTest extends UnitTestCase {
@ -93,6 +94,7 @@ class EntityPermissionsFormTest extends UnitTestCase {
$access_actual = $bundle_form->access($route, $route_match, $bundle);
$this->assertEquals($found ? AccessResult::allowed() : AccessResult::neutral(), $access_actual);
$this->expectDeprecation('Drupal\user\Form\EntityPermissionsForm::access() is deprecated in drupal:11.1.0 and is removed from drupal:12.0.0. Use a permissions check on the route definition instead. See https://www.drupal.org/node/3384745');
}
/**