Make WordPress Core

Opened 7 years ago

Closed 6 years ago

Last modified 6 years ago

#44287 closed enhancement (fixed)

REST API: Declare user capability to perform actions using JSON Hyper Schema `targetSchema`

Reported by: danielbachhuber's profile danielbachhuber Owned by: sergeybiryukov's profile 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:

From Avoid direct use of user capabilities in client-side code

Attachments (3)

44287.patch (20.0 KB) - added by TimothyBlynJacobs 6 years ago.
44287.1.patch (20.1 KB) - added by TimothyBlynJacobs 6 years ago.
43438.2.diff (888 bytes) - added by danielbachhuber 6 years ago.

Download all attachments as: .zip

Change History (29)

This ticket was mentioned in Slack in #core-restapi by danielbachhuber. View the logs.


7 years ago

#2 @TimothyBlynJacobs
7 years ago

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 );

#3 @danielbachhuber
7 years ago

@TimothyBlynJacobs I love the schema-based implementation. Want the honor of preparing a patch?

#4 @TimothyBlynJacobs
7 years ago

Cool! Sure, I'll work on a patch this week.

#5 @TimothyBlynJacobs
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 @danielbachhuber
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:

  1. To make get_available_actions() more useful for subclassing, let's pass $request into it too and then perform the 'edit' === $request['context'] check within get_available_actions(). This ensures get_available_actions() always executes, regardless of context context.
  2. 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 @danielbachhuber
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 @TimothyBlynJacobs
6 years ago

  1. 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.
  2. Will do.
  3. Interesting, I'll try blocking the action for attachments in its controller.

Will upload an updated patch shortly.

#9 @TimothyBlynJacobs
6 years ago

@danielbachhuber Updated.

#10 @danielbachhuber
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:

  1. Applying the patch locally:
grunt patch:https://core.trac.wordpress.org/attachment/ticket/44287/44287.1.patch
grunt build
  1. 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 );
  1. Verifying that the following UI is present when creating a Post as an Administrator:
  • Author
  • Categories
  • Visibility
  • Sticky
  1. Verifying that aforementioned UI isn't present when creating a Post as a Contributor.

I think this is good for commit.

#11 @danielbachhuber
6 years ago

  • Milestone changed from 4.9.7 to 4.9.8

This ticket was mentioned in Slack in #core by jon_bossenger. View the logs.


6 years ago

#13 @pento
6 years ago

  • Resolution set to fixed
  • Status changed from assigned to closed

In 43437:

REST API: Declare user capabilities using JSON Hyper Schema's "targetSchema".

There are a variety of operations a WordPress user can only perform if they have the correct capabilities. A REST API client should only display UI for one of these operations if the WordPress user can perform the operation.

Rather than requiring REST API clients to calculate whether to display UI based on potentially complicated combinations of user capabilities, targetSchema allows us to expose a single flag to show whether the corresponding UI should be displayed.

This change also includes flags on post objects for the following actions:

  • action-publish: The current user can publish this post.
  • action-sticky: The current user can make this post sticky, and the post type supports sticking.
  • `action-assign-author': The current user can change the author on this post.
  • action-assign-{$taxonomy}: The current user can assign terms from the "$taxonomy" taxonomy to this post.
  • action-create-{$taxonomy}: The current user can create terms int the "$taxonomy" taxonomy.

Props TimothyBlynJacobs, danielbachhuber.
Fixes #44287.

#14 @pento
6 years ago

  • Keywords fixed-major added
  • Resolution fixed deleted
  • Status changed from closed to reopened

Re-open for backport to 4.9 branch.

#15 @pento
6 years ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In 43438:

REST API: Declare user capabilities using JSON Hyper Schema's "targetSchema".

There are a variety of operations a WordPress user can only perform if they have the correct capabilities. A REST API client should only display UI for one of these operations if the WordPress user can perform the operation.

Rather than requiring REST API clients to calculate whether to display UI based on potentially complicated combinations of user capabilities, targetSchema allows us to expose a single flag to show whether the corresponding UI should be displayed.

This change also includes flags on post objects for the following actions:

  • action-publish: The current user can publish this post.
  • action-sticky: The current user can make this post sticky, and the post type supports sticking.
  • `action-assign-author': The current user can change the author on this post.
  • action-assign-{$taxonomy}: The current user can assign terms from the "$taxonomy" taxonomy to this post.
  • action-create-{$taxonomy}: The current user can create terms int the "$taxonomy" taxonomy.

Merges [43437] to the 4.9 branch.

Props TimothyBlynJacobs, danielbachhuber.
Fixes #44287.

#16 @ocean90
6 years ago

4.9.7 is already released so the @since tags should probably mention 4.9.8.

#17 @pento
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!

#18 @pento
6 years ago

  • Owner pento deleted
  • Status changed from reopened to assigned

#19 @pbiron
6 years ago

  • Keywords needs-refresh added; needs-patch removed

#20 @danielbachhuber
6 years ago

  • Keywords has-patch commit added; needs-refresh removed

43438.2.diff updates the @since tags.

#21 @pbiron
6 years ago

with that refresh, this is good-to-go for 4.9.8, right?

#22 @danielbachhuber
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.

#23 @pento
6 years ago

  • Keywords fixed-major added

Typoed the commit message in [43463].

#24 @SergeyBiryukov
6 years ago

  • Owner set to SergeyBiryukov
  • Resolution set to fixed
  • Status changed from assigned to closed

In 43490:

REST API: Fix some incorrect @since tags.

[43437] included some new methods, which were incorrectly tagged as being @since 4.9.7. This updates them to 4.9.8.

Props danielbachhuber.
Merges [43463] to the 4.9 branch.
Fixes #44287.

This ticket was mentioned in Slack in #core-restapi by timothybjacobs. View the logs.


6 years ago

This ticket was mentioned in Slack in #core-restapi by timothybjacobs. View the logs.


6 years ago

Note: See TracTickets for help on using tickets.