#44287 closed enhancement (fixed)
REST API: Declare user capability to perform actions using JSON Hyper Schema `targetSchema`
Reported by: | danielbachhuber | Owned by: | SergeyBiryukov |
---|---|---|---|
Milestone: | 4.9.8 | Priority: | normal |
Severity: | normal | Version: | |
Component: | Role/Capability | Keywords: | has-patch commit fixed-major |
Focuses: | rest-api | Cc: |
Description
There are a variety of operations a WordPress user can only perform if they have the correct capabilities. For instance, a WordPress who can create posts can only change authors on the post if they have the edit_others_posts
capability.
A REST API client should only display UI for one of these operations if the WordPress user can perform the action. Only editors should see the author dropdown, not authors.
However, user capabilities are evaluated at runtime. The result of current_user_can()
can be modified by the map_meta_cap
and user_can
filters. This means we can't expose capabilities directly, but instead need to expose their computed value.
Fortunately, JSON Hyper Schema targetSchema
provides a language for us to communicate this information. To resolve this issue, we'll need to commit a patch prepared from the following pull requests:
- Use `targetSchema` of JSON Hyper Schema to communicate sticky action
- Use `wp:action-assign-author` to indicate if user can assign authors
- Introduce `wp:action-publish`; update corresponding UI to reference
- Ensure contributors can create tags and manage categories
From Avoid direct use of user capabilities in client-side code
Attachments (3)
Change History (29)
This ticket was mentioned in Slack in #core-restapi by danielbachhuber. View the logs.
7 years ago
#3
@
7 years ago
@TimothyBlynJacobs I love the schema-based implementation. Want the honor of preparing a patch?
#5
@
6 years ago
- Keywords has-patch has-unit-tests added; needs-patch needs-unit-tests removed
First pass at a patch.
1) I did some adjusting to the attachments controller to resuse the links definition from the parent response. That way we don't have to repeat ourselves for adding the action links. As far as I can tell, the $post
var isn't adjusted during that method to the links generated should always be the same.
2) I wasn't sure of the best way to structure the unit tests. For the most part they are all just in the posts controller tests with some small unit tests in the attachments controller since it has a separate prepare_item_for_response.
3) I made some minor changes to the text from the Gutenberg version, adding the taxonomy name in the description strings. This matches the description for the main schema document.
#6
@
6 years ago
- Milestone changed from 4.9.8 to 4.9.7
@TimothyBlynJacobs Looks good! I see a couple small nits to be addressed:
- To make
get_available_actions()
more useful for subclassing, let's pass$request
into it too and then perform the'edit' === $request['context']
check withinget_available_actions()
. This ensuresget_available_actions()
always executes, regardless ofcontext
context. - We should avoid variable assignment within conditionals.
This:
if ( $schema_links = $this->get_schema_links() )
Should become:
$schema_links = $this->get_schema_links(); if ( $schema_links )
#7
@
6 years ago
Also, we probably shouldn't include action-publish
for attachments, as explicitly changing attachment status isn't really a UI feature we support.
#8
@
6 years ago
- Makes sense. I'd originally done it to force the links to only be included in the
edit
context but I can see how it'd be helpful for subclassing to make it more open. - Will do.
- Interesting, I'll try blocking the action for attachments in its controller.
Will upload an updated patch shortly.
#10
@
6 years ago
- Keywords commit added
- Owner set to pento
- Status changed from new to assigned
@TimothyBlynJacobs Thanks for updating.
I've tested this patch by:
- Applying the patch locally:
grunt patch:https://core.trac.wordpress.org/attachment/ticket/44287/44287.1.patch grunt build
- Disabling Gutenberg's existing shim:
- add_filter( "rest_prepare_{$post_type}", 'gutenberg_add_target_schema_to_links', 10, 3 ); + // add_filter( "rest_prepare_{$post_type}", 'gutenberg_add_target_schema_to_links', 10, 3 );
- Verifying that the following UI is present when creating a Post as an Administrator:
- Author
- Categories
- Visibility
- Sticky
- Verifying that aforementioned UI isn't present when creating a Post as a Contributor.
I think this is good for commit.
This ticket was mentioned in Slack in #core by jon_bossenger. View the logs.
6 years ago
#14
@
6 years ago
- Keywords fixed-major added
- Resolution fixed deleted
- Status changed from closed to reopened
Re-open for backport to 4.9 branch.
#17
@
6 years ago
- Keywords needs-patch added; has-patch has-unit-tests commit fixed-major removed
- Resolution fixed deleted
- Status changed from closed to reopened
Whee!
#20
@
6 years ago
- Keywords has-patch commit added; needs-refresh removed
43438.2.diff
updates the @since
tags.
#22
@
6 years ago
@pbiron The original patch already been backported to the 4.9
branch. The only change remaining is to have the @since
tags updated on trunk
and 4.9
branch.
#24
@
6 years ago
- Owner set to SergeyBiryukov
- Resolution set to fixed
- Status changed from assigned to closed
In 43490:
So the simplest version of this is using
add_link()
directly in the controllers and adding all the information inline. For example.$response->add_link( 'https://api.w.org/action-sticky', $self, array( 'title' => __( 'The current user can sticky this post.' ), 'targetSchema' => array( 'type' => 'object', 'properties' => array( 'sticky' => array( 'type' => 'boolean', ), ), ), ) );
A concern here is that we would be duplicating information for every item in collection responses. We can alleviate this by adding the bulk of the link details to the schema document for the resource. For example.
// In ::get_item_schema() $schema['links'][] = array( 'rel' => 'https://api.w.org/action-sticky', 'title' => __( 'The current user can sticky this post.' ), 'href' => rest_url( '/wp/v2/posts/{id}' ), 'targetSchema' => array( 'type' => 'object', 'properties' => array( 'sticky' => array( 'type' => 'boolean', ), ), ), );
Then, the response size will be considerably smaller.
$response->add_link( 'https://api.w.org/action-sticky', $self );