ListBuilders do not check $entity->access() for operation links

Created on 15 January 2016, about 9 years ago
Updated 11 November 2023, about 1 year ago

Problem/Motivation

Some EntityListBuilders do not check whether the user has permission for certain operations (such as enable and disabled) on config entities where the routing for the page that it links does. This can cause links to inaccessible pages.

This issue doesn't seem to present itself in core as the permission for the list page seems to be the same as the permissions for any operation on config entities, but it blocks contrib modules that may change the permissions on a config entity, such as a view.

Proposed resolution

Add the access checks.

Remaining tasks

Decide what, if anything, needs to be done for:

  • \Drupal\taxonomy\VocabularyListBuilder::getDefaultOperations() list (have implemented a best guess) and add
  • \Drupal\field_ui\FieldConfigListBuilder::getDefaultOperations() storage-settings (not sure it needs)
  • \Drupal\image\ImageStyleListBuilder::getDefaultOperations() flush (not sure it needs)
  • \Drupal\responsive_image\ResponsiveImageStyleListBuilder::getDefaultOperations() duplicate (not sure it needs)
  • \Drupal\search\SearchPageListBuilder::getDefaultOperations() default (not sure it needs)

User interface changes

Links that could currently go to access denied pages will no longer be shown.

🐛 Bug report
Status

Needs work

Version

11.0 🔥

Component
Configuration entity 

Last updated 31 minutes ago

Created by

🇬🇧United Kingdom andrewbelcher

Live updates comments and jobs are added and updated live.
  • Contributed project blocker

    It denotes an issue that prevents porting of a contributed project to the stable version of Drupal due to missing APIs, regressions, and so on.

  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇮🇹Italy robertom

    patch updated for branch 10.1.x-dev

    it looks strange to check access before checking that link template exists

    yeah, but it's the same order used in EntityListBuilder::getDefaultOperations

  • Status changed to Needs work about 2 years ago
  • 🇺🇸United States smustgrave

    This issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.

    This will need a test case to show the issue is fixed.

    Did not review code.

  • 🇮🇳India mukhtarm

    $entity->access('permission') has been deprecated since D10 and gives the warning( https://www.drupal.org/node/3201242 ).

    Relying on entity queries to check access by default is deprecated in  
             drupal:9.2.0 and an error will be thrown from drupal:10.0.0. Call      
             \Drupal\Core\Entity\Query\QueryInterface::accessCheck() with TRUE or   
             FALSE to specify whether access should be checked.

    Anyway to check explicit access for the entity in getDefaultOperations?

    for eg:

    public function getDefaultOperations(EntityInterface $entity) {
        $exists = isset($this->templates[$entity->getGathercontentTemplateId()]);
        $operations = [];
        if ($exists && $entity->access('update') && $entity->hasLinkTemplate('edit-form')) {
          $operations['edit'] = [
            'title' => $entity->hasMapping() ? $this->t('Edit') : $this->t('Create'),
            'weight' => 10,
            'url' => $entity->toUrl('edit-form'),
          ];
        }
        if ($entity->access('delete') && $entity->hasLinkTemplate('delete-form')) {
          $operations['delete'] = [
            'title' => $this->t('Delete'),
            'weight' => 100,
            'url' => $entity->toUrl('delete-form'),
          ];
        }
        return $operations;
      }

    here i think its explicitly checking access for 'update' or 'delete'. So the entityQuery->accessCheck(TRUE) would work? as its for the whole access right?

Production build 0.71.5 2024