Media Library + Layout Builder issue.
To select or upload a media from the media library, user requires administer block content, OR create $bundle block content,access block library.
When using media library widget from within the block content form of a layout builder inline block, where the block content has not yet been
saved, when the user tries to click insert on the modal (select existing), or try to use the uploader, media_library.module's
MediaLibraryFieldWidgetOpener::checkAccess attempts to call createAccess which eventually gets to BlockContentAccessControlHandler::createAccess which checks for administer blocks.
In normal use of LB / Inline block user does not need this administer permission. Granting this permission is not granular enough to consider granting to lesser users.
Ultimately users should be able to select media from the library, or upload new media, without needing an administer permission. Layout builder provides a create and edit custom blocks for using inline blocks without requiring users to have administer.


| Comment | File | Size | Author |
|---|---|---|---|
| Screen Shot 2020-01-14 at 9.24.11 pm.png | 39.13 KB | dpi | |
| Screen Shot 2020-01-14 at 9.24.35 pm.png | 374.77 KB | dpi |
Issue fork drupal-3106315
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:
Comments
Comment #2
dpiComment #3
dpiComment #5
acbramley commentedIt looks like this may be fixable in
layout_builder_block_content_accessThat hook is returning
AccessResult::neutral()when there is no usages for the block yet.Comment #6
komlenic commentedI'm encountering this also. There is no workaround for a user who doesn't have 'administer blocks' permission, and granting that permission most often isn't a viable option, so bumping to major. This looks like a Layout Builder issue as @acbramley noted.
Comment #7
joao sausen commentedI have found the same issue. In my case i fixed it installing block_permissions.
Comment #9
jastraat commentedIt seems somewhat worthless to have the "create and edit custom blocks" permission for adding inline blocks in layout builder if users need the "administer blocks" permission to select media for that inline block.
Comment #10
jastraat commentedFor reference, the error Drupal throws when an editor with the "create and edit custom blocks" permission attempts to select an image for usage in an inline block:
path: /media-library?_wrapper_format=drupal_ajax&ajax_form=1&media_library_opener_id=media_library.opener.field_widget&media_library_allowed_types%5Bimage%5D=image&media_library_selected_type=image&media_library_remaining=1&media_library_opener_parameters%5Bfield_widget_id%5D=[media reference field name]%3A-settings-block_form&media_library_opener_parameters%5Bentity_type_id%5D=block_content&media_library_opener_parameters%5Bbundle%5D=[inline block type]&media_library_opener_parameters%5Bfield_name%5D=[media reference field name]&hash=[hash]&views_display_id=widget&_wrapper_format=drupal_ajax. Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException: The 'administer blocks' permission is required. in Drupal\Core\Routing\AccessAwareRouter->checkAccess() (line 120 of /var/www/html/web/core/lib/Drupal/Core/Routing/AccessAwareRouter.php).
Comment #11
jastraat commentedI believe in addition to implementing hook_block_content_access, layout_builder needs to implement hook_block_content_create_access. We need to be able to determine in MediaLibraryFieldWidgetOpener:checkAccess if the parent form is for a regular block or an inline block. If that could be determined, it could be added to the $context array and then checked by layout_builder_block_content_create_access()
In order to determine the context of the media library, I think MediaLibraryWidget:formElement would need to be modified to add another value for the parent form ($form_state->build_info['form_id'] to $opener_parameters. If it's an inline block, the form_id would be 'layout_builder_add_block' This parameter would be available in the MediaLibraryState $state and could be checked to provide access to users with the 'create and edit custom blocks' permission if the form id matched the layout builder add form.
Comment #12
jastraat commentedAdding related issues
Comment #13
jastraat commentedAs a workaround, we've added the following in a custom module:
The substring check isn't really necessary right now, but in case the core media library widget were to ever add plugin_id as part of the standard $openerParameters (which might simplify media library access problems for multiple use cases), checking the plugin_id would be necessary.
Comment #14
randalv commentedPoking due to having the same issue as well.
I tried #13, and this did not solve it for me personally.
Comment #15
maacl commentedThanks for the snippet! There is a small error:
Should be
Comment #16
liam morlandThe fix in #13 is working for us after applying the change in #15. We also had to add some
usestatements to the file:Comment #17
komlenic commentedConfirmed that the combined fix from #13, #15, and #16 + the addition of another
usestatement, does provide a workaround for this issue. The complete solution is below.Comment #19
kriboogh commentedEncountered the same problem, only we also had this when we edit an existing block. To fix this I changed the form alter function to this:
The condition checks for both the add_block and update_block route.
The plugin_id is no longer fetched from the route_match, but from the component form being altered.
You also need an extra hook_ENTITY_TYPE_access implementation, for dealing with updates (same code as the create_access hook):
Comment #20
amanire commentedI wonder if this is the same issue as https://www.drupal.org/project/drupal/issues/3047022?
Comment #22
akalam commentedI tried the workaround described on #17 and #19 and it worked for me with a small difference. In my case, \Drupal::routeMatch()->getRouteName() is returning null, but removing that check fix the access control on layout builder while the user is still forbidden on accessing to the "block layout" as expected.
Comment #23
kmontyNoting that we've been using the patch mentioned in #20 #3047022: Layout builder fails to assign inline block access dependencies for the overrides section storage on entities with pending revisions for a year now. This permissions issue just cropped up for us -- updating to the latest version of the patch does not resolve the issue.
Comment #24
dripa commented#19 didn't solve it for me. I installed and configured the block_content_permissions module.
Comment #25
goldin commentedThanks @e.ruiter, block_content_permissions solved this for me as well.
Comment #29
larowlan#1975064: Add more granular block content permissions Would have resolved this. You just need the ability to edit the block content type the media is attached to now. This used to require administer blocks, but no longer does.
Comment #30
larowlanComment #31
acbramley commentedWhile we can use the create * block content permissions to get around this, it's a bit strange because a role doesn't need any of these permissions to actually manage block content inside layout builder at all.
This means we need to give roles create permissions for blocks they can create in layout builder, only for media library access. But then they'd have access to create them via block/add/foo as well? Leaning on the side of reopening this one.
Comment #32
acbramley commentedYeah, you also need "access block library" which again may not be desirable.
Comment #33
luke.leberI agree with #31 here.
Our particular use case is that we only want a higher echelon of users to be able to create / edit / delete reusable blocks (due to how far-reaching their usage might be), while allowing lower users to manage inline blocks.
As it stands, even with contrib module helpers, users still seem to need create permission on the block type in order to use the media library for inline blocks. This comes with the nasty side-effect of allowing them to create reusable blocks as well.
Comment #34
johnpitcairn commentedI also agree with #31.
Content editors who should only interact with blocks via layout builder should not see the reusable blocks overview page or be able to create standalone reusable blocks from there.
Comment #35
ammaletu commentedWe just stumbled upon a new variant of this bug (Drupal 10.1.7): Our users have the "administer blocks" permission, but not the new per content block permissions nor the "Access the Content blocks overview page" permission. Everything worked fine for them with Drupal 9. Since the update, they are not able to add media to a block anymore.
The error message which is logged when clicking on the "Insert" button in the media modal (no error shown to the user):
The change record for the new permissions sounded as if they were optional, as long as users have the "administer blocks" permission. Now it seems, this has changed so that you do need the new permissions for adding media items to a block!?
Comment #37
ian.ssu commentedI spent an entire day with the debugger trying to find an elegant solution to this issue. My conclusion is that LayoutBuilder InlineBlock, by adding the Reusable property to BlockContentEntity, creates a separation of concerns problem. This approach couples BlockContent to LayoutBuilder in ways that other modules, like MediaLibrary, shouldn't have to worry about. I've started considering extending BlockContentEntity for InlineBlock as a potential path toward a solution.
Unable to come up with a quick solution, I pivoted back to the workaround for Drupal 10.2.6
https://git.drupalcode.org/issue/drupal-3106315/-/compare/11.x...3106315...
Comment #38
fenstratThe work around in #37 works well. It can also be implemented in a custom module to the same effect.
It's essentially a simplified version of the fixes others have used above.
I'd agree that this is an unfortunate separation of concerns issue. So, as the 'create and edit custom blocks' permissions seems to cover the cases where media is not used on a block, then re-using that permission where media is used seems like a valid work around.
Comment #39
chrisgross commentedI'm running into a similar problem on 10.3.2. However, the suggested solution does not work for me, though my use case is perhaps slightly different.
I am using Block Content Permissions (for some reason core's newer Block Content permissions do not list "create" permissions at all on my site) , but I have chosen not to give any roles "Create new block content" permissions for my various custom block types and this is preventing media from being uploaded to fields on those blocks in Layout Builder. Granting those permissions does fix that and allow media to be added to the library within Layout Builder blocks, however, it also allows users to add new instances of these custom block types under '/block/add', which I do not want. I only want those users to be able to add those blocks in Layout Builder.
The "Create new block content" permissions are not required in order to actually add these custom blocks in Layout Builder at all (which I believe is how it's supposed to work), but they are required in order to add media to fields within those blocks. So I believe this is a variation of this same problem, which is that Layout Builder is using faulty access checks when uploading media to custom blocks.
I'm not sure why the solution in #37 does not work for me.
Update: I wonder if this is because core's newer Block Content permissions somehow left out Create permissions entirely, but it doesn't seem like the fix is considered urgent enough to even make it into 10.4: #3412420: BlockContentAccessControlHandler requires access block library permission for create. So maybe there is really no way to know how any of this is going to work until that fix is merged in and we are able to fully transition away from the Block Content Permissions contrib?
Comment #40
jastraat commentedUpdated work around for 10.4.x:
Comment #41
erik.erskine commentedThe problem really lies with media_library expecting the
create {bundle} block contentpermission. This is described in #3327106: MediaLibraryFieldWidgetOpener is too opinionated.Layout builder doesn't require you have that permission in order to create inline content blocks. Pretending it does under certain circumstances feels like the wrong approach. It also seems strange that the result of
EntityAccessControlHandlerInterface::createAccess()would vary per route.Interestingly, the exact same problem is manifested in the group module (#3071489: Incorrect Access Check on Media Library). This is a very similar scenario: you are allowed to create nodes nodes, but only in a restricted way (as part of a group), and without having full on
create {bundle} contentpermission.