diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
index e94601ea28..317780b39a 100644
a
|
b
|
class WP_REST_Posts_Controller extends WP_REST_Controller { |
2498 | 2498 | |
2499 | 2499 | $post_type_obj = get_post_type_object( $this->post_type ); |
2500 | 2500 | |
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 ) ) { |
2502 | 2502 | $result = rest_validate_request_arg( $status, $request, $parameter ); |
2503 | 2503 | if ( is_wp_error( $result ) ) { |
2504 | 2504 | return $result; |
diff --git a/tests/phpunit/tests/rest-api/rest-posts-controller.php b/tests/phpunit/tests/rest-api/rest-posts-controller.php
index 4893cb8470..ec38bd7a85 100644
a
|
b
|
class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te |
16 | 16 | protected static $editor_id; |
17 | 17 | protected static $author_id; |
18 | 18 | protected static $contributor_id; |
| 19 | protected static $private_reader_id; |
19 | 20 | |
20 | 21 | protected static $supported_formats; |
21 | 22 | |
… |
… |
class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te |
39 | 40 | 'role' => 'contributor', |
40 | 41 | ) ); |
41 | 42 | |
| 43 | self::$private_reader_id = $factory->user->create( |
| 44 | array( |
| 45 | 'role' => 'private_reader', |
| 46 | ) |
| 47 | ); |
| 48 | |
42 | 49 | if ( is_multisite() ) { |
43 | 50 | update_site_option( 'site_admins', array( 'superadmin' ) ); |
44 | 51 | } |
… |
… |
class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te |
62 | 69 | self::delete_user( self::$editor_id ); |
63 | 70 | self::delete_user( self::$author_id ); |
64 | 71 | self::delete_user( self::$contributor_id ); |
| 72 | self::delete_user( self::$private_reader_id ); |
65 | 73 | } |
66 | 74 | |
67 | 75 | public function setUp() { |
68 | 76 | parent::setUp(); |
69 | 77 | 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 | |
70 | 83 | add_filter( 'rest_pre_dispatch', array( $this, 'wpSetUpBeforeRequest' ), 10, 3 ); |
71 | 84 | add_filter( 'posts_clauses', array( $this, 'save_posts_clauses' ), 10, 2 ); |
72 | 85 | } |
… |
… |
class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te |
497 | 510 | $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); |
498 | 511 | } |
499 | 512 | |
| 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 | |
500 | 527 | public function test_get_items_invalid_status_query() { |
501 | 528 | wp_set_current_user( 0 ); |
502 | 529 | $request = new WP_REST_Request( 'GET', '/wp/v2/posts' ); |
… |
… |
class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te |
993 | 1020 | $this->assertContains( '<' . $next_link . '>; rel="next"', $headers['Link'] ); |
994 | 1021 | } |
995 | 1022 | |
996 | | public function test_get_items_private_status_query_var() { |
997 | | // Private query vars inaccessible to unauthorized users |
998 | | wp_set_current_user( 0 ); |
| 1023 | public function test_get_items_status_draft_permissions() { |
999 | 1024 | $draft_id = $this->factory->post->create( array( 'post_status' => 'draft' ) ); |
| 1025 | |
| 1026 | // Drafts status query var inaccessible to unauthorized users. |
| 1027 | wp_set_current_user( 0 ); |
| 1028 | $request = new WP_REST_Request( 'GET', '/wp/v2/posts' ); |
| 1029 | $request->set_param( 'status', 'draft' ); |
| 1030 | $response = rest_get_server()->dispatch( $request ); |
| 1031 | $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); |
| 1032 | |
| 1033 | // Users with 'read_private_posts' cap shouldn't also be able to view drafts. |
| 1034 | wp_set_current_user( self::$private_reader_id ); |
1000 | 1035 | $request = new WP_REST_Request( 'GET', '/wp/v2/posts' ); |
1001 | 1036 | $request->set_param( 'status', 'draft' ); |
1002 | | $response = $this->server->dispatch( $request ); |
| 1037 | $response = rest_get_server()->dispatch( $request ); |
1003 | 1038 | $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); |
1004 | 1039 | |
1005 | | // But they are accessible to authorized users |
| 1040 | // But drafts are accessible to authorized users. |
1006 | 1041 | wp_set_current_user( self::$editor_id ); |
1007 | | $response = $this->server->dispatch( $request ); |
1008 | | $data = $response->get_data(); |
1009 | | $this->assertCount( 1, $data ); |
| 1042 | $response = rest_get_server()->dispatch( $request ); |
| 1043 | $data = $response->get_data(); |
| 1044 | |
1010 | 1045 | $this->assertEquals( $draft_id, $data[0]['id'] ); |
1011 | 1046 | } |
1012 | 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() ); |
| 1067 | $this->assertCount( 1, $data ); |
| 1068 | $this->assertEquals( $private_post_id, $data[0]['id'] ); |
| 1069 | } |
| 1070 | |
1013 | 1071 | public function test_get_items_invalid_per_page() { |
1014 | 1072 | $request = new WP_REST_Request( 'GET', '/wp/v2/posts' ); |
1015 | 1073 | $request->set_query_params( array( 'per_page' => -1 ) ); |