Make WordPress Core

Changeset 43979


Ignore:
Timestamp:
12/11/2018 10:29:36 PM (6 years ago)
Author:
desrosj
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.

Moves [43694] from the 5.0 branch to trunk.

Fixes #43701.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api.php

    r42343 r43979  
    991991
    992992    // Everything else will map nicely to boolean.
    993     return (boolean) $value;
     993    return (bool) $value;
    994994}
    995995
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

    r43974 r43979  
    25102510            $post_type_obj = get_post_type_object( $this->post_type );
    25112511
    2512             if ( current_user_can( $post_type_obj->cap->edit_posts ) ) {
     2512            if ( current_user_can( $post_type_obj->cap->edit_posts ) || 'private' === $status && current_user_can( $post_type_obj->cap->read_private_posts ) ) {
    25132513                $result = rest_validate_request_arg( $status, $request, $parameter );
    25142514                if ( is_wp_error( $result ) ) {
  • trunk/tests/phpunit/tests/rest-api/rest-posts-controller.php

    r43974 r43979  
    1717    protected static $author_id;
    1818    protected static $contributor_id;
     19    protected static $private_reader_id;
    1920
    2021    protected static $supported_formats;
     
    4546            array(
    4647                'role' => 'contributor',
     48            )
     49        );
     50
     51        self::$private_reader_id = $factory->user->create(
     52            array(
     53                'role' => 'private_reader',
    4754            )
    4855        );
     
    7178        self::delete_user( self::$author_id );
    7279        self::delete_user( self::$contributor_id );
     80        self::delete_user( self::$private_reader_id );
    7381    }
    7482
     
    8290            )
    8391        );
     92
     93        add_role( 'private_reader', 'Private Reader' );
     94        $role = get_role( 'private_reader' );
     95        $role->add_cap( 'read_private_posts' );
     96
    8497        add_filter( 'rest_pre_dispatch', array( $this, 'wpSetUpBeforeRequest' ), 10, 3 );
    8598        add_filter( 'posts_clauses', array( $this, 'save_posts_clauses' ), 10, 2 );
     
    593606    }
    594607
     608    /**
     609     * @ticket 43701
     610     */
     611    public function test_get_items_multiple_statuses_custom_role_one_invalid_query() {
     612        $private_post_id = $this->factory->post->create( array( 'post_status' => 'private' ) );
     613
     614        wp_set_current_user( self::$private_reader_id );
     615        $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     616        $request->set_param( 'status', array( 'private', 'future' ) );
     617
     618        $response = rest_get_server()->dispatch( $request );
     619        $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     620    }
     621
    595622    public function test_get_items_invalid_status_query() {
    596623        wp_set_current_user( 0 );
     
    11951222    }
    11961223
    1197     public function test_get_items_private_status_query_var() {
    1198         // Private query vars inaccessible to unauthorized users
     1224    public function test_get_items_status_draft_permissions() {
     1225        $draft_id = $this->factory->post->create( array( 'post_status' => 'draft' ) );
     1226
     1227        // Drafts status query var inaccessible to unauthorized users.
    11991228        wp_set_current_user( 0 );
    1200         $draft_id = $this->factory->post->create( array( 'post_status' => 'draft' ) );
    1201         $request  = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     1229        $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
    12021230        $request->set_param( 'status', 'draft' );
    12031231        $response = rest_get_server()->dispatch( $request );
    12041232        $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
    12051233
    1206         // But they are accessible to authorized users
    1207         wp_set_current_user( self::$editor_id );
    1208         $response = rest_get_server()->dispatch( $request );
    1209         $data     = $response->get_data();
     1234        // Users with 'read_private_posts' cap shouldn't also be able to view drafts.
     1235        wp_set_current_user( self::$private_reader_id );
     1236        $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     1237        $request->set_param( 'status', 'draft' );
     1238        $response = rest_get_server()->dispatch( $request );
     1239        $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     1240
     1241        // But drafts are accessible to authorized users.
     1242        wp_set_current_user( self::$editor_id );
     1243        $response = rest_get_server()->dispatch( $request );
     1244        $data     = $response->get_data();
     1245
     1246        $this->assertEquals( $draft_id, $data[0]['id'] );
     1247    }
     1248
     1249    /**
     1250     * @ticket 43701
     1251     */
     1252    public function test_get_items_status_private_permissions() {
     1253        $private_post_id = $this->factory->post->create( array( 'post_status' => 'private' ) );
     1254
     1255        wp_set_current_user( 0 );
     1256        $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     1257        $request->set_param( 'status', 'private' );
     1258        $response = rest_get_server()->dispatch( $request );
     1259        $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     1260
     1261        wp_set_current_user( self::$private_reader_id );
     1262        $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     1263        $request->set_param( 'status', 'private' );
     1264
     1265        $response = rest_get_server()->dispatch( $request );
     1266        $data     = $response->get_data();
     1267        $this->assertEquals( 200, $response->get_status() );
    12101268        $this->assertCount( 1, $data );
    1211         $this->assertEquals( $draft_id, $data[0]['id'] );
     1269        $this->assertEquals( $private_post_id, $data[0]['id'] );
    12121270    }
    12131271
Note: See TracChangeset for help on using the changeset viewer.