WordPress.org

Make WordPress Core

Changeset 43694


Ignore:
Timestamp:
10/10/2018 08:48:21 PM (9 months ago)
Author:
danielbachhuber
Message:

REST API: Enable users with read_private_posts to query for them.

An authorized request with the read_private_posts capability for a post type should be able to GET /wp/v2/posts for posts of status=private. This query is further sanity-checked by WP_REST_Posts_Controller->check_read_permission(), which is unchanged.

Props rachelbaker, soulseekah, twoelevenjay.
Fixes #43701.

Location:
branches/5.0
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/5.0/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

    r43682 r43694  
    24992499            $post_type_obj = get_post_type_object( $this->post_type );
    25002500
    2501             if ( current_user_can( $post_type_obj->cap->edit_posts ) ) {
     2501            if ( current_user_can( $post_type_obj->cap->edit_posts ) || 'private' === $status && current_user_can( $post_type_obj->cap->read_private_posts ) ) {
    25022502                $result = rest_validate_request_arg( $status, $request, $parameter );
    25032503                if ( is_wp_error( $result ) ) {
  • branches/5.0/tests/phpunit/tests/rest-api/rest-posts-controller.php

    r43682 r43694  
    1717    protected static $author_id;
    1818    protected static $contributor_id;
     19    protected static $private_reader_id;
    1920
    2021    protected static $supported_formats;
     
    3940            'role' => 'contributor',
    4041        ) );
     42
     43        self::$private_reader_id = $factory->user->create(
     44            array(
     45                'role' => 'private_reader',
     46            )
     47        );
    4148
    4249        if ( is_multisite() ) {
     
    6370        self::delete_user( self::$author_id );
    6471        self::delete_user( self::$contributor_id );
     72        self::delete_user( self::$private_reader_id );
    6573    }
    6674
     
    6876        parent::setUp();
    6977        register_post_type( 'youseeme', array( 'supports' => array(), 'show_in_rest' => true ) );
     78
     79        add_role( 'private_reader', 'Private Reader' );
     80        $role = get_role( 'private_reader' );
     81        $role->add_cap( 'read_private_posts' );
     82
    7083        add_filter( 'rest_pre_dispatch', array( $this, 'wpSetUpBeforeRequest' ), 10, 3 );
    7184        add_filter( 'posts_clauses', array( $this, 'save_posts_clauses' ), 10, 2 );
     
    498511    }
    499512
     513    /**
     514     * @ticket 43701
     515     */
     516    public function test_get_items_multiple_statuses_custom_role_one_invalid_query() {
     517        $private_post_id = $this->factory->post->create( array( 'post_status' => 'private' ) );
     518
     519        wp_set_current_user( self::$private_reader_id );
     520        $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     521        $request->set_param( 'status', array( 'private', 'future' ) );
     522
     523        $response = rest_get_server()->dispatch( $request );
     524        $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     525    }
     526
    500527    public function test_get_items_invalid_status_query() {
    501528        wp_set_current_user( 0 );
     
    9941021    }
    9951022
    996     public function test_get_items_private_status_query_var() {
    997         // Private query vars inaccessible to unauthorized users
     1023    public function test_get_items_status_draft_permissions() {
     1024        $draft_id = $this->factory->post->create( array( 'post_status' => 'draft' ) );
     1025
     1026        // Drafts status query var inaccessible to unauthorized users.
    9981027        wp_set_current_user( 0 );
    999         $draft_id = $this->factory->post->create( array( 'post_status' => 'draft' ) );
    1000         $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     1028        $request  = new WP_REST_Request( 'GET', '/wp/v2/posts' );
    10011029        $request->set_param( 'status', 'draft' );
    1002         $response = $this->server->dispatch( $request );
     1030        $response = rest_get_server()->dispatch( $request );
    10031031        $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
    10041032
    1005         // But they are accessible to authorized users
    1006         wp_set_current_user( self::$editor_id );
    1007         $response = $this->server->dispatch( $request );
    1008         $data = $response->get_data();
     1033        // Users with 'read_private_posts' cap shouldn't also be able to view drafts.
     1034        wp_set_current_user( self::$private_reader_id );
     1035        $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     1036        $request->set_param( 'status', 'draft' );
     1037        $response = rest_get_server()->dispatch( $request );
     1038        $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     1039
     1040        // But drafts are accessible to authorized users.
     1041        wp_set_current_user( self::$editor_id );
     1042        $response = rest_get_server()->dispatch( $request );
     1043        $data     = $response->get_data();
     1044
     1045        $this->assertEquals( $draft_id, $data[0]['id'] );
     1046    }
     1047
     1048    /**
     1049     * @ticket 43701
     1050     */
     1051    public function test_get_items_status_private_permissions() {
     1052        $private_post_id = $this->factory->post->create( array( 'post_status' => 'private' ) );
     1053
     1054        wp_set_current_user( 0 );
     1055        $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     1056        $request->set_param( 'status', 'private' );
     1057        $response = rest_get_server()->dispatch( $request );
     1058        $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     1059
     1060        wp_set_current_user( self::$private_reader_id );
     1061        $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     1062        $request->set_param( 'status', 'private' );
     1063
     1064        $response = rest_get_server()->dispatch( $request );
     1065        $data     = $response->get_data();
     1066        $this->assertEquals( 200, $response->get_status() );
    10091067        $this->assertCount( 1, $data );
    1010         $this->assertEquals( $draft_id, $data[0]['id'] );
     1068        $this->assertEquals( $private_post_id, $data[0]['id'] );
    10111069    }
    10121070
Note: See TracChangeset for help on using the changeset viewer.