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.
Comments
Comment #2
andrewbelcher commentedThis patch fixes the operations I've found. I've not actually checked for others, so not marking as needs review yet.
Comment #3
andrewbelcher commentedSo I think there is only one other that needs something done:
\Drupal\taxonomy\VocabularyListBuilder::getDefaultOperations()addslistandaddwhich I would guess areviewandcreaterespectively?The following I couldn't see an _entity_access set on the route, so I think don't need anything doing:
\Drupal\field_ui\FieldConfigListBuilder::getDefaultOperations()addsstorage-settings. It also alters edit/delete without checking whether they are set. I have fixed the second part, but not sure what to do with the first.\Drupal\image\ImageStyleListBuilder::getDefaultOperations()addsflush.\Drupal\responsive_image\ResponsiveImageStyleListBuilder::getDefaultOperations()addsduplicate.\Drupal\search\SearchPageListBuilder::getDefaultOperations()addsdefault.Comment #4
andrewbelcher commentedComment #5
swentel commentedThis doesn't make sense, they will always be there. There's a complete separate discussion on this at #2274433: Do not allow to alter Locked field via UI, so I'd leave this bit out.
Not sure about the others as there are no dedicated permissions for enable/disable and duplicate in the default access check handler, it falls into the default admin permission. Basically, if you have access to the list, then you're fine. Which doesn't mean we could add more granular checks of course, but currently, this patch simply won't fix anything.
Comment #6
andrewbelcher commentedswentel: Yes, you are correct - in core this is not an issue. However, core does actually use entity level access checks for the routes, even though those access checks come back to the
administer viewspermission. As it uses entity level checks for the routes, the operations should also follow those checks.I encountered this as part of working on Views Tag Access which alters the entity level access checks. I've added the contributed project blocker tag and updated the issue summary to make it clearer.
The reason for the code you quoted is because it assumes
$operations['edit']and$operations['delete']exist. They are created either inside:or by the call to
parent::getDefaultOperations($entity), specifically\Drupal\Core\Entity\EntityListBuilder::getDefaultOperations():So it is assuming that they exist even though the code that creates them may well not create them. However, you are right - the issue you linked does, co-incidentally, fix the same issue. I've attached an updated version of the patch without those changes.
I'm very happy to break this up/target specific bits (e.g.
\Drupal\views_tag_access\ViewListBuilder) if that is preferable?Comment #8
andrewbelcher commentedThere has been no progress at #2274433: Do not allow to alter Locked field via UI. The change made here to the field list builder isn't disruptive and doesn't change any of the work over there (as it replaces the existing code so a simple re-roll will solve it). This doesn't change or break any core behaviour but does fix a bug which limits contrib. Is there anything stopping this from being considered for committal?
Will re-queue the test for 8.1.x to make sure it still applies and passes tests.
Comment #11
andypostComment #12
berdirSee also #2200183: Add ConfigEntityAccessController
Comment #13
claudiu.cristeaWe should expand the check also to the "Add terms" operation. I opened an issue for this in #2845021: Operation 'add terms' on vocabulary list should respect the access policy. I didn't knew about this issue. Closing the other as duplicate.
Comment #17
vacho commentedPatch updated for branch 8.7.x-dev
Comment #18
andypostit looks strange to check access before checking that link template exists
Comment #27
robertom commentedpatch updated for branch 10.1.x-dev
yeah, but it's the same order used in EntityListBuilder::getDefaultOperations
Comment #28
smustgrave commentedThis 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.
Comment #30
mukhtarm commented$entity->access('permission') has been deprecated since D10 and gives the warning(https://www.drupal.org/node/3201242).
Anyway to check explicit access for the entity in
getDefaultOperations?for eg:
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?