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. git-svn-id: https://develop.svn.wordpress.org/trunk@43979 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
f173141c5b
commit
c0e80b028a
@ -990,7 +990,7 @@ function rest_sanitize_boolean( $value ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Everything else will map nicely to boolean.
|
// Everything else will map nicely to boolean.
|
||||||
return (boolean) $value;
|
return (bool) $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2509,7 +2509,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|||||||
|
|
||||||
$post_type_obj = get_post_type_object( $this->post_type );
|
$post_type_obj = get_post_type_object( $this->post_type );
|
||||||
|
|
||||||
if ( current_user_can( $post_type_obj->cap->edit_posts ) ) {
|
if ( current_user_can( $post_type_obj->cap->edit_posts ) || 'private' === $status && current_user_can( $post_type_obj->cap->read_private_posts ) ) {
|
||||||
$result = rest_validate_request_arg( $status, $request, $parameter );
|
$result = rest_validate_request_arg( $status, $request, $parameter );
|
||||||
if ( is_wp_error( $result ) ) {
|
if ( is_wp_error( $result ) ) {
|
||||||
return $result;
|
return $result;
|
||||||
|
@ -16,6 +16,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
|||||||
protected static $editor_id;
|
protected static $editor_id;
|
||||||
protected static $author_id;
|
protected static $author_id;
|
||||||
protected static $contributor_id;
|
protected static $contributor_id;
|
||||||
|
protected static $private_reader_id;
|
||||||
|
|
||||||
protected static $supported_formats;
|
protected static $supported_formats;
|
||||||
|
|
||||||
@ -47,6 +48,12 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
self::$private_reader_id = $factory->user->create(
|
||||||
|
array(
|
||||||
|
'role' => 'private_reader',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if ( is_multisite() ) {
|
if ( is_multisite() ) {
|
||||||
update_site_option( 'site_admins', array( 'superadmin' ) );
|
update_site_option( 'site_admins', array( 'superadmin' ) );
|
||||||
}
|
}
|
||||||
@ -70,6 +77,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
|||||||
self::delete_user( self::$editor_id );
|
self::delete_user( self::$editor_id );
|
||||||
self::delete_user( self::$author_id );
|
self::delete_user( self::$author_id );
|
||||||
self::delete_user( self::$contributor_id );
|
self::delete_user( self::$contributor_id );
|
||||||
|
self::delete_user( self::$private_reader_id );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
@ -81,6 +89,11 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
|||||||
'show_in_rest' => true,
|
'show_in_rest' => true,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
add_role( 'private_reader', 'Private Reader' );
|
||||||
|
$role = get_role( 'private_reader' );
|
||||||
|
$role->add_cap( 'read_private_posts' );
|
||||||
|
|
||||||
add_filter( 'rest_pre_dispatch', array( $this, 'wpSetUpBeforeRequest' ), 10, 3 );
|
add_filter( 'rest_pre_dispatch', array( $this, 'wpSetUpBeforeRequest' ), 10, 3 );
|
||||||
add_filter( 'posts_clauses', array( $this, 'save_posts_clauses' ), 10, 2 );
|
add_filter( 'posts_clauses', array( $this, 'save_posts_clauses' ), 10, 2 );
|
||||||
}
|
}
|
||||||
@ -592,6 +605,20 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
|||||||
$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
|
$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ticket 43701
|
||||||
|
*/
|
||||||
|
public function test_get_items_multiple_statuses_custom_role_one_invalid_query() {
|
||||||
|
$private_post_id = $this->factory->post->create( array( 'post_status' => 'private' ) );
|
||||||
|
|
||||||
|
wp_set_current_user( self::$private_reader_id );
|
||||||
|
$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
|
||||||
|
$request->set_param( 'status', array( 'private', 'future' ) );
|
||||||
|
|
||||||
|
$response = rest_get_server()->dispatch( $request );
|
||||||
|
$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
|
||||||
|
}
|
||||||
|
|
||||||
public function test_get_items_invalid_status_query() {
|
public function test_get_items_invalid_status_query() {
|
||||||
wp_set_current_user( 0 );
|
wp_set_current_user( 0 );
|
||||||
$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
|
$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
|
||||||
@ -1194,23 +1221,54 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
|||||||
$this->assertContains( '<' . $next_link . '>; rel="next"', $headers['Link'] );
|
$this->assertContains( '<' . $next_link . '>; rel="next"', $headers['Link'] );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_get_items_private_status_query_var() {
|
public function test_get_items_status_draft_permissions() {
|
||||||
// Private query vars inaccessible to unauthorized users
|
|
||||||
wp_set_current_user( 0 );
|
|
||||||
$draft_id = $this->factory->post->create( array( 'post_status' => 'draft' ) );
|
$draft_id = $this->factory->post->create( array( 'post_status' => 'draft' ) );
|
||||||
|
|
||||||
|
// Drafts status query var inaccessible to unauthorized users.
|
||||||
|
wp_set_current_user( 0 );
|
||||||
$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
|
$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
|
||||||
$request->set_param( 'status', 'draft' );
|
$request->set_param( 'status', 'draft' );
|
||||||
$response = rest_get_server()->dispatch( $request );
|
$response = rest_get_server()->dispatch( $request );
|
||||||
$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
|
$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
|
||||||
|
|
||||||
// But they are accessible to authorized users
|
// Users with 'read_private_posts' cap shouldn't also be able to view drafts.
|
||||||
|
wp_set_current_user( self::$private_reader_id );
|
||||||
|
$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
|
||||||
|
$request->set_param( 'status', 'draft' );
|
||||||
|
$response = rest_get_server()->dispatch( $request );
|
||||||
|
$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
|
||||||
|
|
||||||
|
// But drafts are accessible to authorized users.
|
||||||
wp_set_current_user( self::$editor_id );
|
wp_set_current_user( self::$editor_id );
|
||||||
$response = rest_get_server()->dispatch( $request );
|
$response = rest_get_server()->dispatch( $request );
|
||||||
$data = $response->get_data();
|
$data = $response->get_data();
|
||||||
$this->assertCount( 1, $data );
|
|
||||||
$this->assertEquals( $draft_id, $data[0]['id'] );
|
$this->assertEquals( $draft_id, $data[0]['id'] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ticket 43701
|
||||||
|
*/
|
||||||
|
public function test_get_items_status_private_permissions() {
|
||||||
|
$private_post_id = $this->factory->post->create( array( 'post_status' => 'private' ) );
|
||||||
|
|
||||||
|
wp_set_current_user( 0 );
|
||||||
|
$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
|
||||||
|
$request->set_param( 'status', 'private' );
|
||||||
|
$response = rest_get_server()->dispatch( $request );
|
||||||
|
$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
|
||||||
|
|
||||||
|
wp_set_current_user( self::$private_reader_id );
|
||||||
|
$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
|
||||||
|
$request->set_param( 'status', 'private' );
|
||||||
|
|
||||||
|
$response = rest_get_server()->dispatch( $request );
|
||||||
|
$data = $response->get_data();
|
||||||
|
$this->assertEquals( 200, $response->get_status() );
|
||||||
|
$this->assertCount( 1, $data );
|
||||||
|
$this->assertEquals( $private_post_id, $data[0]['id'] );
|
||||||
|
}
|
||||||
|
|
||||||
public function test_get_items_invalid_per_page() {
|
public function test_get_items_invalid_per_page() {
|
||||||
$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
|
$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
|
||||||
$request->set_query_params( array( 'per_page' => -1 ) );
|
$request->set_query_params( array( 'per_page' => -1 ) );
|
||||||
|
Loading…
Reference in New Issue
Block a user