-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Verify 'upload_files' capability when displaying upload UI in media blocks #4155
Conversation
This comment has been minimized.
This comment has been minimized.
blocks/library/image/index.js
Outdated
@@ -59,6 +59,8 @@ registerBlockType( 'core/image', { | |||
}, | |||
}, | |||
|
|||
capability: 'upload_files', |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for your review @mtias
On one hand I totally agree a contributor should be able to pick an existing media from the WordPress Media Library.
On the other hand, he can't even do that 😢 Being logged in as a contributor, when you click on the button to pick an image, a video or an audio file, you get an empty library as the ajax action that performs the attachments query is checking for the upload_files
capability very early. See /wp-admin/includes/ajax-actions.php.
So today these "media" blocks are pretty useless for contributors, that's why I suggested to remove them as it's an experience that is a bit frustrating 😬
To only allow picking to contributors would require a WordPress core change that would be a bit more difficult than simply allowing uploading and picking just like the other roles, imho. I can think of UI/feature changes to remove the Uploader & the Upload tab of the WordPress Media Editor for instance.
Adding the upload_files
capability to the contributor role would be much easier, but it would probably require some wide communication to WordPress users as I can imagine some are using this role for the users they wan't to restrict from uploading files...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Being logged in as a contributor, when you click on the button to pick an image, a video or an audio file, you get an empty library as the ajax action that performs the attachments query is checking for the upload_files capability very early.
I hadn't realized this, and it's interesting, especially since the new media REST API endpoints don't have the same restriction, it'd be entirely possible to create a media explorer based on the REST API given current permissions checks. This hints to me that perhaps in the interim to get to that point, perhaps these restrictions ought to be loosened (i.e. those in admin-ajax.php
and in the current media library implementation).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense. I think it'd be ok to remove them from the inserter, but how should we handle editing an existing post that has images? Or a post that has an image placeholder?
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aduth This is handled into the PR actually. Images or any other media in existing post will be displayed. Just like in the classic editor the contributor can remove the image from the post content (but not from the Media Library) or edit display attributes (alignment, etc..)
blocks/api/registration.js
Outdated
* @type {Object} | ||
*/ | ||
const currentUser = get( | ||
Object.values( pickBy( window._wpAPIDataPreload, ( value, key ) => key.indexOf( '/wp/v2/users/me' ) !== -1 ) ), |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
blocks/library/image/index.js
Outdated
@@ -59,6 +59,8 @@ registerBlockType( 'core/image', { | |||
}, | |||
}, | |||
|
|||
capability: 'upload_files', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Being logged in as a contributor, when you click on the button to pick an image, a video or an audio file, you get an empty library as the ajax action that performs the attachments query is checking for the upload_files capability very early.
I hadn't realized this, and it's interesting, especially since the new media REST API endpoints don't have the same restriction, it'd be entirely possible to create a media explorer based on the REST API given current permissions checks. This hints to me that perhaps in the interim to get to that point, perhaps these restrictions ought to be loosened (i.e. those in admin-ajax.php
and in the current media library implementation).
FWIW i've tested in the classic editor the situation where a contributor can edit a post containing an image. In this case, the contributor can edit the markup (alignment, caption, link, classes, rel attribute) and can remove the image from the content. When it's a gallery of images, the contributor cannot see it. He sees this placeholder instead Anyway & imho, a possible approach could be to hide the media blocks from the block pickers, so that a contributor cannot be the one who inserts one of these blocks. If another user with the @aduth about WP_REST_Attachments_Controller: creating items checks for the same capability ( |
8844bd6
to
1216849
Compare
In 1216849 I'm using the approach I've described in my previous comment. But instead of not showing the blocks, I'm using the feature that disables them when the property So when the contributor is using the inserter he sees: When another user with an upper role added an image or a gallery and kept the post as pending.. The contributor can see the corresponding block, remove it or modify markup, caption, link, alignment etc.. But he can't use the Edit button to open the WP Media Editor and can't transform it to another type (as the other types also require the I haven't edited the Block autocompleter because i think there's another issue to fix in |
This comment has been minimized.
This comment has been minimized.
1216849
to
738e5d0
Compare
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looping in @noisysocks , who's been working on relevant Inserter refactoring that might overlap with some of the changes proposed here (#4497).
|
||
if ( isLocked || ! allowedBlocks.length ) { | ||
return null; | ||
} | ||
|
||
const userAllowedBlocks = allowedBlocks.filter( b => ! b.capability || userCapabilities[ b.capability ] ); |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
blocks/library/image/index.js
Outdated
@@ -59,6 +59,8 @@ registerBlockType( 'core/image', { | |||
}, | |||
}, | |||
|
|||
capability: 'upload_files', |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
const wrapper = shallow( | ||
<VisualEditorInserter insertBlock={ insertBlock } mostFrequentlyUsedBlocks={ mostFrequentlyUsedBlocks } /> | ||
<VisualEditorInserter insertBlock={ insertBlock } mostFrequentlyUsedBlocks={ mostFrequentlyUsedBlocks } user={ user } /> |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
738e5d0
to
1897ae2
Compare
This comment has been minimized.
This comment has been minimized.
editor/components/inserter/menu.js
Outdated
|
||
if ( ! isDisabled && requiredCapability ) { | ||
isDisabled = ! get( this.props.user.data, [ 'capabilities', requiredCapability ] ); | ||
} |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
1897ae2
to
77e56da
Compare
This comment has been minimized.
This comment has been minimized.
editor/store/selectors.js
Outdated
* make sure he cannot use it disabling it. | ||
*/ | ||
if ( userCapabilities && blockType.capability && ! get( userCapabilities, blockType.capability, false ) ) { | ||
blockType.isDisabled = true; |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
77e56da
to
d43bbb6
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
d43bbb6
to
6612b66
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This is to bring into Gutenberg the improvement @danielbachhuber committed in WordPress 5.0 branch See https://core.trac.wordpress.org/changeset/43833
c6f922c
to
9238c48
Compare
9238c48
to
80ffbf6
Compare
Ouch sorry but I have a very old computer, i can't install docker so i'm not able to see why a e2e test is failing.. |
I think the tests are good now @imath . Maybe someone kicked them off again. I've seen this in some of my PRs. |
Awesome !! Thanks for your comment @antpb. @gziolo @aduth @youknowriad do we have a chance to finally have this fixed after almost a year working on it ? 😊 Or is there anything else that needs to be done ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really great work on this PR 👏
I left some minor comments. And not blocking here but I'd appreciate an e2e test (maybe as a follow-up PR) to ensure we don't regress.
export default withFilters( 'editor.MediaPlaceholder' )( MediaPlaceholder ); | ||
const applyWithSelect = withSelect( ( select ) => { | ||
let hasUploadPermissions = false; | ||
if ( undefined !== select( 'core' ) ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this check is not necessary, to be consistent with other withSelect
usage, we should assume the "core" store to be available as it's a dependency of the editor package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I saw in the comments that it's because of the unit tests. Two suggestions:
- Avoid running this code in unit tests (test the inner component)
- Import the
@wordpress/core-data
in the unit tests to ensure that the store is available.
|
||
export default withSelect( ( select ) => { | ||
let hasUploadPermissions = false; | ||
if ( undefined !== select( 'core' ) ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above.
It had several iterations since the time Andrew reviewed it
Congrats on keeping this PR updated for so long and ensuring it gets merged 💯 Thanks for this contributions. I will address comments raised by Riad in the follow-up PR. |
Thanks a lot for your help everyone 😍🎉 |
This would require some changes to be back-ported in the 5.0 branch (for the preloading changes in PHP). Up for a ticket+commit @gziolo :P |
@youknowriad the preloading part is already in Core thanks to https://core.trac.wordpress.org/changeset/43833 |
Oh good thanks @imath |
Closes #1536
Closes #3672
I've been looking for a way to solve this issue #3672 and I think one possible way is to add a capability attribute to blocks and check the current user has this cap before registering the block.
Description
In the classic editor, the upload button is disabled if the current user does not have the
upload_files
capability (eg: contributor). But when a contributor uses Gutenberg he can use "file" relative blocks. When he tries to use one of them as this role hasn't got theupload_files
capability, the REST reply to site.url/wp-json/wp/v2/media is rest_cannot_create (403).How Has This Been Tested?
I have tested this PR for the contributor role. A contributor does not have the
upload_files
capability and the PR is making sure he can't use blocks involving a file upload (eg: image, core-image, audio, video, gallery).Screenshots (jpeg or gifs if applicable):
See #3672 for a video of the issue.
Types of changes
I think this PR is first a bug fix, but i also think it could be interesting to be able to restrict block usage according to the user's role.
Checklist: