Problem/Motivation
Currently when the media library does access checking on the entity that opened the media library, it does so by loading the entity using a simple \Drupal\Core\Entity\EntityStorageInterface::load. When editing inline blocks and layout builder both of these things are true:
- You aren't guaranteed to be modifying the latest or default revision of an inline block.
- The revision ID of an inline block is very important to it's access control.
Steps to reproduce:
- Enable media_library, layout_builder.
- Add a media field + media library to a custom block type.
- Enable layout builder + per entity overrides on a content type.
- Embed a block with the media library field into a per entity override.
- Create two revisions, modify the inline block in both.
- Go to the "Revisions" tab and revert to the first revision.
- Go back to the layout tab and try to edit and save a new image in the media library.
- AJAX request will come back a 403.
What is happening under the hood:
- The media library has an block content entity ID.
- It loads that entity and checks access against it.
- The inline block's access is based on it's host entity, so it loads the host and confirms the revision ID of the block is used on the layout (
\Drupal\layout_builder\EventSubscriber\SetInlineBlockDependency::isBlockRevisionUsedInEntity). - The media libraries
::loadcall doesn't match the actual revision ID in the layout and the access chain is broken, resulting in an access denied.
Proposed resolution
Pass the host entity's revision ID around, instead of it's ID and load that instead for the purposes of access control.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #27 | interdiff-3124302-23-27.txt | 1.37 KB | acbramley |
| #27 | 3124302-27.patch | 6.75 KB | acbramley |
Comments
Comment #2
sam152 commentedComment #3
sam152 commentedComment #4
sam152 commentedWhat about something like this?
Comment #5
sam152 commentedComment #6
seanbThis seems to make sense to me. Can we add a test for this?
Comment #7
sam152 commentedSure, what about something like this?
Comment #9
seanbWe already have a MediaLibraryAccessTest. Might make sense to put this in there?
Not really sure if we need to build the widget, in MediaLibraryAccessTest we simply create a state ourselves and check access. Which should be sufficient.
I know we do this a lot, but a comment that this is to make sure our uid is not 1 would be nice I think.
Comment #10
sam152 commentedThe new test class and building the widget ensures this part of the patch is covered.
Comment #12
sam152 commentedAddressing #9.3.
@seanB, are you happy with the explanation in #10. I think covering the additional code in the widget is worthwhile splitting out a new test class.
Comment #14
sam152 commentedComment #15
sanjayk commentedComment #16
sanjayk commentedI have test on d9 patch apply and test executed successfully but when I try to reproduce the issue I got below js issue please see below issue
EntityToolbarView.js?v=9.1.0-dev:145 Uncaught TypeError: Cannot read property 'get' of null
at r.position (EntityToolbarView.js?v=9.1.0-dev:145)
at render (EntityToolbarView.js?v=9.1.0-dev:51)
at p (backbone.js:337)
at v (backbone.js:322)
at u (backbone.js:110)
at r.a.trigger (backbone.js:312)
at r.set (backbone.js:525)
at r.set (BaseModel.js?v=9.1.0-dev:29)
at r.success (EntityModel.js?v=9.1.0-dev:175)
at Drupal.AjaxCommands.entitySaverAjax.commands.quickeditEntitySaved (EntityModel.js?v=9.1.0-dev:234)
Comment #17
sam152 commentedI don't think a JS error in the toolbar module has anything to do with this patch.
Comment #18
seanbThe reason I was a bit triggered by the class name
MediaLibraryWidgetTestis because we had #3087227: [META] Split up and refactor MediaLibraryTest where we split up all kinds of widget related tests that were in 1 class (which became unmaintainable). So that is why I'm trying to see if we can have smaller, more specifically named classes.Besides that, since this is already specifically named for widget related tests, it is good enough for me.
Comment #19
sam152 commentedAh, fair enough. Thanks for following up.
Comment #20
alexpottCommitted and pushed d901cf487b to 9.1.x and 49f78bc356 to 9.0.x. Thanks!
Fixed coding standards on commit.
Leaving open for backport to 8.9.x as this is bug there. The test set up method will need fixing to not typehint.
Comment #23
sam152 commentedThanks for committing, adding the backport.
Comment #24
sam152 commentedComment #26
acbramley commentedRando fail
Comment #27
acbramley commentedWoops, there was actually some phpcs issues. Fixed those.
Comment #28
sam152 commentedComment #29
phenaproximaComment #31
phenaproximaThere was a random failure. Restoring RTBC.
Comment #32
alexpottCommitted d89941f and pushed to 8.9.x. Thanks!
Comment #35
pameeela commentedAdding the error that I got when hitting this, for searchability:
Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException: Non-reusable blocks must set an access dependency for access control. in Drupal\Core\Routing\AccessAwareRouter->checkAccess() (line 120 of /app/site/web/core/lib/Drupal/Core/Routing/AccessAwareRouter.php)Comment #36
maskedjellybeanI received the same error as @pameeela recently on 8.9.13 when editing a Layout Builder block that contains a Media field with Media Library enabled. The only solution I could find was to manually delete the block from Layout Builder and recreate/readd it. Based on comment #33, shouldn't this have been resolved long before 8.9.13? How could we still be experiencing this error?
Comment #37
pameeela commentedHmm you're right, I hadn't checked versions yet, but my site also has the fix from this issue already. We just deleted the blocks and recreated them as you suggested in the other ticket.
But I don't have steps to reproduce this, it only occurred on one node on a staging site, have not had any other reports.
Comment #38
imalabyaThis issue exists in Drupal 9.5 with entity clone
Steps to reproduce:
Non-reusable blocks must set an access dependency for access control.Comment #39
permanaj commentedI have similar case with @imalabya
I get error `Non-reusable blocks must set an access dependency for access control.` after uploading the image for the second time
Steps to reproduce:
I test this on simplytest.me using Drupal 10.3.6 and 10.3.9 with Entity clone module version 2.1.x.