Make WordPress Core


Ignore:
Timestamp:
07/11/2018 06:22:10 AM (8 years ago)
Author:
pento
Message:

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/rest-api/rest-posts-controller.php

    r43087 r43437  
    36413641        }
    36423642
     3643        public function test_publish_action_ldo_registered() {
     3644
     3645                $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' ) );
     3646                $data     = $response->get_data();
     3647                $schema   = $data['schema'];
     3648
     3649                $this->assertArrayHasKey( 'links', $schema );
     3650                $publish = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-publish' ) );
     3651
     3652                $this->assertCount( 1, $publish, 'LDO found on schema.' );
     3653        }
     3654
     3655        public function test_sticky_action_ldo_registered_for_posts() {
     3656
     3657                $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' ) );
     3658                $data     = $response->get_data();
     3659                $schema   = $data['schema'];
     3660
     3661                $this->assertArrayHasKey( 'links', $schema );
     3662                $publish = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-sticky' ) );
     3663
     3664                $this->assertCount( 1, $publish, 'LDO found on schema.' );
     3665        }
     3666
     3667        public function test_sticky_action_ldo_not_registered_for_non_posts() {
     3668
     3669                $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/pages' ) );
     3670                $data     = $response->get_data();
     3671                $schema   = $data['schema'];
     3672
     3673                $this->assertArrayHasKey( 'links', $schema );
     3674                $publish = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-sticky' ) );
     3675
     3676                $this->assertCount( 0, $publish, 'LDO found on schema.' );
     3677        }
     3678
     3679        public function test_author_action_ldo_registered_for_post_types_with_author_support() {
     3680
     3681                $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' ) );
     3682                $data     = $response->get_data();
     3683                $schema   = $data['schema'];
     3684
     3685                $this->assertArrayHasKey( 'links', $schema );
     3686                $publish = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-assign-author' ) );
     3687
     3688                $this->assertCount( 1, $publish, 'LDO found on schema.' );
     3689        }
     3690
     3691        public function test_author_action_ldo_not_registered_for_post_types_without_author_support() {
     3692
     3693                remove_post_type_support( 'post', 'author' );
     3694
     3695                $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' ) );
     3696                $data     = $response->get_data();
     3697                $schema   = $data['schema'];
     3698
     3699                $this->assertArrayHasKey( 'links', $schema );
     3700                $publish = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-assign-author' ) );
     3701
     3702                $this->assertCount( 0, $publish, 'LDO found on schema.' );
     3703        }
     3704
     3705        public function test_term_action_ldos_registered() {
     3706
     3707                $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' ) );
     3708                $data     = $response->get_data();
     3709                $schema   = $data['schema'];
     3710
     3711                $this->assertArrayHasKey( 'links', $schema );
     3712                $rels = array_flip( wp_list_pluck( $schema['links'], 'rel' ) );
     3713
     3714                $this->assertArrayHasKey( 'https://api.w.org/action-assign-categories', $rels );
     3715                $this->assertArrayHasKey( 'https://api.w.org/action-create-categories', $rels );
     3716                $this->assertArrayHasKey( 'https://api.w.org/action-assign-tags', $rels );
     3717                $this->assertArrayHasKey( 'https://api.w.org/action-create-tags', $rels );
     3718
     3719                $this->assertArrayNotHasKey( 'https://api.w.org/action-assign-post_format', $rels );
     3720                $this->assertArrayNotHasKey( 'https://api.w.org/action-create-post_format', $rels );
     3721                $this->assertArrayNotHasKey( 'https://api.w.org/action-assign-nav_menu', $rels );
     3722                $this->assertArrayNotHasKey( 'https://api.w.org/action-create-nav_menu', $rels );
     3723        }
     3724
     3725        public function test_action_links_only_available_in_edit_context() {
     3726
     3727                wp_set_current_user( self::$author_id );
     3728
     3729                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3730                $this->assertGreaterThan( 0, $post );
     3731
     3732                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3733                $request->set_query_params( array( 'context' => 'view' ) );
     3734
     3735                $response = rest_get_server()->dispatch( $request );
     3736                $links    = $response->get_links();
     3737
     3738                $this->assertArrayNotHasKey( 'https://api.w.org/action-publish', $links );
     3739        }
     3740
     3741        public function test_publish_action_link_exists_for_author() {
     3742
     3743                wp_set_current_user( self::$author_id );
     3744
     3745                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3746                $this->assertGreaterThan( 0, $post );
     3747
     3748                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3749                $request->set_query_params( array( 'context' => 'edit' ) );
     3750
     3751                $response = rest_get_server()->dispatch( $request );
     3752                $links    = $response->get_links();
     3753
     3754                $this->assertArrayHasKey( 'https://api.w.org/action-publish', $links );
     3755        }
     3756
     3757        public function test_publish_action_link_does_not_exist_for_contributor() {
     3758
     3759                wp_set_current_user( self::$contributor_id );
     3760
     3761                $post = self::factory()->post->create( array( 'post_author' => self::$contributor_id ) );
     3762                $this->assertGreaterThan( 0, $post );
     3763
     3764                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3765                $request->set_query_params( array( 'context' => 'edit' ) );
     3766
     3767                $response = rest_get_server()->dispatch( $request );
     3768                $links    = $response->get_links();
     3769
     3770                $this->assertArrayNotHasKey( 'https://api.w.org/action-publish', $links );
     3771        }
     3772
     3773        public function test_sticky_action_exists_for_editor() {
     3774
     3775                wp_set_current_user( self::$editor_id );
     3776
     3777                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3778                $this->assertGreaterThan( 0, $post );
     3779
     3780                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3781                $request->set_query_params( array( 'context' => 'edit' ) );
     3782
     3783                $response = rest_get_server()->dispatch( $request );
     3784                $links    = $response->get_links();
     3785
     3786                $this->assertArrayHasKey( 'https://api.w.org/action-sticky', $links );
     3787        }
     3788
     3789        public function test_sticky_action_does_not_exist_for_author() {
     3790
     3791                wp_set_current_user( self::$author_id );
     3792
     3793                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3794                $this->assertGreaterThan( 0, $post );
     3795
     3796                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3797                $request->set_query_params( array( 'context' => 'edit' ) );
     3798
     3799                $response = rest_get_server()->dispatch( $request );
     3800                $links    = $response->get_links();
     3801
     3802                $this->assertArrayNotHasKey( 'https://api.w.org/action-sticky', $links );
     3803        }
     3804
     3805        public function test_sticky_action_does_not_exist_for_non_post_posts() {
     3806
     3807                wp_set_current_user( self::$editor_id );
     3808
     3809                $post = self::factory()->post->create(
     3810                        array(
     3811                                'post_author' => self::$author_id,
     3812                                'post_type'   => 'page',
     3813                        )
     3814                );
     3815                $this->assertGreaterThan( 0, $post );
     3816
     3817                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3818                $request->set_query_params( array( 'context' => 'edit' ) );
     3819
     3820                $response = rest_get_server()->dispatch( $request );
     3821                $links    = $response->get_links();
     3822
     3823                $this->assertArrayNotHasKey( 'https://api.w.org/action-sticky', $links );
     3824        }
     3825
     3826
     3827        public function test_assign_author_action_exists_for_editor() {
     3828
     3829                wp_set_current_user( self::$editor_id );
     3830
     3831                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3832                $this->assertGreaterThan( 0, $post );
     3833
     3834                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3835                $request->set_query_params( array( 'context' => 'edit' ) );
     3836
     3837                $response = rest_get_server()->dispatch( $request );
     3838                $links    = $response->get_links();
     3839
     3840                $this->assertArrayHasKey( 'https://api.w.org/action-assign-author', $links );
     3841        }
     3842
     3843        public function test_assign_author_action_does_not_exist_for_author() {
     3844
     3845                wp_set_current_user( self::$author_id );
     3846
     3847                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3848                $this->assertGreaterThan( 0, $post );
     3849
     3850                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3851                $request->set_query_params( array( 'context' => 'edit' ) );
     3852
     3853                $response = rest_get_server()->dispatch( $request );
     3854                $links    = $response->get_links();
     3855
     3856                $this->assertArrayNotHasKey( 'https://api.w.org/action-assign-author', $links );
     3857        }
     3858
     3859        public function test_assign_author_action_does_not_exist_for_post_types_without_author_support() {
     3860
     3861                remove_post_type_support( 'post', 'author' );
     3862
     3863                wp_set_current_user( self::$editor_id );
     3864
     3865                $post = self::factory()->post->create();
     3866                $this->assertGreaterThan( 0, $post );
     3867
     3868                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3869                $request->set_query_params( array( 'context' => 'edit' ) );
     3870
     3871                $response = rest_get_server()->dispatch( $request );
     3872                $links    = $response->get_links();
     3873
     3874                $this->assertArrayNotHasKey( 'https://api.w.org/action-assign-author', $links );
     3875        }
     3876
     3877        public function test_create_term_action_exists_for_editor() {
     3878
     3879                wp_set_current_user( self::$editor_id );
     3880
     3881                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3882                $this->assertGreaterThan( 0, $post );
     3883
     3884                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3885                $request->set_query_params( array( 'context' => 'edit' ) );
     3886
     3887                $response = rest_get_server()->dispatch( $request );
     3888                $links    = $response->get_links();
     3889
     3890                $this->assertArrayHasKey( 'https://api.w.org/action-create-categories', $links );
     3891                $this->assertArrayHasKey( 'https://api.w.org/action-create-tags', $links );
     3892                $this->assertArrayNotHasKey( 'https://api.w.org/action-create-post_format', $links );
     3893        }
     3894
     3895        public function test_create_term_action_non_hierarchical_exists_for_author() {
     3896
     3897                wp_set_current_user( self::$author_id );
     3898
     3899                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3900                $this->assertGreaterThan( 0, $post );
     3901
     3902                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3903                $request->set_query_params( array( 'context' => 'edit' ) );
     3904
     3905                $response = rest_get_server()->dispatch( $request );
     3906                $links    = $response->get_links();
     3907
     3908                $this->assertArrayHasKey( 'https://api.w.org/action-create-tags', $links );
     3909        }
     3910
     3911        public function test_create_term_action_hierarchical_does_not_exists_for_author() {
     3912
     3913                wp_set_current_user( self::$author_id );
     3914
     3915                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3916                $this->assertGreaterThan( 0, $post );
     3917
     3918                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3919                $request->set_query_params( array( 'context' => 'edit' ) );
     3920
     3921                $response = rest_get_server()->dispatch( $request );
     3922                $links    = $response->get_links();
     3923
     3924                $this->assertArrayNotHasKey( 'https://api.w.org/action-create-categories', $links );
     3925        }
     3926
     3927        public function test_assign_term_action_exists_for_contributor() {
     3928
     3929                wp_set_current_user( self::$contributor_id );
     3930
     3931                $post = self::factory()->post->create(
     3932                        array(
     3933                                'post_author' => self::$contributor_id,
     3934                                'post_status' => 'draft',
     3935                        )
     3936                );
     3937                $this->assertGreaterThan( 0, $post );
     3938
     3939                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3940                $request->set_query_params( array( 'context' => 'edit' ) );
     3941
     3942                $response = rest_get_server()->dispatch( $request );
     3943                $links    = $response->get_links();
     3944
     3945                $this->assertArrayHasKey( 'https://api.w.org/action-assign-categories', $links );
     3946                $this->assertArrayHasKey( 'https://api.w.org/action-assign-tags', $links );
     3947        }
     3948
    36433949        public function tearDown() {
    36443950                _unregister_post_type( 'youseeeme' );
Note: See TracChangeset for help on using the changeset viewer.