Problem/Motivation

Bulk operations lists all available actions for the entity without checking access to that action.

web/core/modules/system/src/Plugin/views/field/BulkForm.php:

  /**
   * {@inheritdoc}
   */
  public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
    parent::init($view, $display, $options);

    $entity_type = $this->getEntityType();
    // Filter the actions to only include those for this entity type.
    $this->actions = array_filter($this->actionStorage->loadMultiple(), function ($action) use ($entity_type) {
      return $action->getType() == $entity_type;
    });
  }

This appears to be because the action access is tied to access for the particular entity but not whether or not the user has access to do that type of action in general or not. ActionInterface::access() described here.

For example:

  1. Create a new role 'editor'
  2. Grant editor role 'view user information' but not 'administer users'
  3. Change /admin/people view access to 'view user information'
  4. As an editor, view /admin/people and all actions like cancel user accounts are listed as bulk action options

Proposed resolution

Creating a sample entity of the current type and passing it to the action::access() method to determine whether to show it in the bulk actions. I am not sure if creating a sample entity is a feasible approach.

Alternatively, we could provide a method like bulkAccess() on the action and allow the action to define when it is appropriate to be shown.

Or we could make the assumption that access to the confirm route means show it as a bulk action since we have this information:

@Action(
  id = "user_cancel_user_action",
  label = @Translation("Cancel the selected user accounts"),
  type = "user",
  confirm_form_route_name = "user.multiple_cancel_confirm"
)

Remaining tasks

Decide how to approach this.

User interface changes

Only show bulk action operations that the user has access to.

API changes

None (depending on route chosen to solve this).

Data model changes

None.

CommentFileSizeAuthor
bulk-operations-access.gif4.16 MBscott_euser

Issue fork drupal-2895262

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

scott_euser created an issue. See original summary.

scott_euser’s picture

Issue summary: View changes

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

szeidler’s picture

Wow, I also encountered the issue with a client today. It would be really nice, when we could provide only the actions in the selectbox for which the user actually has access too.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

joachim’s picture

> Creating a sample entity of the current type and passing it to the action::access() method to determine whether to show it in the bulk actions. I am not sure if creating a sample entity is a feasible approach.

That's not really feasible unfortunately. It works with some entity types, but if an entity type expects certain fields to be set when a new one is created, it will fail. State Machine module has this approach -- see #2960370: Views filter will crash with entity types that enforce values other than the bundle for more on the problems this can cause.

> Or we could make the assumption that access to the confirm route means show it as a bulk action since we have this information:

I think that checking access to the action's confirm_form_route_name would be a good start.

If it turns out that it doesn't cover all cases, we'd need to look at adding a permission property to actions.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Jumoke’s picture

Hi all, I encountered this problem as well. Anyone figured or concluded on a solution for this?

penyaskito’s picture

I don't think there is a one-fits-all solution for this use case.
There could be e.g. node grants for nodes preventing the action in some entities, but not all of them. Should we show the bulk action in that case? I think it depends on the context.

The current workaround is editing the view bulk actions and check those that you want to allow to perform, or do it with a form_alter if that depends on the actual user/permission/role.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

mxr576’s picture

mxr576’s picture

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

morvaim made their first commit to this issue’s fork.

morvaim’s picture

I created a work in progress merge request (test coverage is in progress).
The proposed solution is to introduce a new 'execute' operation on actions and add an access check on the BulkForm. And also in views grant access for every authenticated users for the 'execute' operation and later on other modules can also provide their own access check. For example the administerusersbyrole module could handle the access related to user actions.
See: https://git.drupalcode.org/project/administerusersbyrole/-/merge_requests/3

mxr576’s picture

Additional thoughts on #20. We also try to narrow down the scope here. Currently, we have two possible problems to solve, as #13 already started to explain.

The system should be able to decide if an acting user can:

1. Execute an action _on an entity type independently from the current context_. This basically means a global yes or no.
2. Execute an action on a given entity (where the acting user, the given entity, and possibly other meta information are part of the current context) If the acting user can perform the given action on a given entity type (1).

Compared with problem 1 where an action is either explicitly allowed or not (rendered or not), the 2nd problem is also a UX challenge and possibly requires a more reactive UI that we currently have in Drupal core:
1. What should happen if I select Action X? Should we refresh the list of entities and filter out all those entities that the acting user cannot perform Action X for some reason?
2. What should happen when an acting user already selected Entity Y but Action X cannot be performed on that? Should we refresh the list of available actions based on selection?

Of course, we can still allow any combinations and fail at the end of the process with a result like "10/0 action performed successfully selected entities", which would be a bad UX and also DX.

So the suggestion is let's start small and first introduce a new operation "execute", "perform" or other Action config entities. That can be already used to define a global yes or no to perform an action. (See morvaim's Drupal core MR and Administer Users by Role MR)

Fixing problems 1 and 2 also going to be a BC nightmare, unless we move the target to Drupal 10.

mxr576’s picture

@morvaim regarding test coverage, if this logic moves to system.module then \Drupal\Tests\system\Kernel\Action\ActionTest can be also extended to cover the new entity access check.

A related views.module test can be also altered to ensure Views also uses the new access check, for example user_batch_action_test_action action (defined in \Drupal\user_batch_action_test\Plugin\Action\BatchUserAction()) can be only performed by users who has permission X but not others. That action is currently used by \Drupal\Tests\views\Functional\UserBatchActionTest

Although, before we invest a lot of time in extending test coverage, first let's wait for some input from the community for the described and showcased idea.

(We should also change the component to system.module later if everybody agrees with the scope and resultion.)

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.