Skip to content

Commit

Permalink
Query for all authors with an unbounded per_page=-1 request (#6627)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielbachhuber authored May 9, 2018
1 parent f961832 commit 8e7ee59
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 9 deletions.
2 changes: 1 addition & 1 deletion core-data/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export async function* getCategories() {
* Requests authors from the REST API.
*/
export async function* getAuthors() {
const users = await apiRequest( { path: '/wp/v2/users/?who=authors' } );
const users = await apiRequest( { path: '/wp/v2/users/?who=authors&per_page=-1' } );
yield receiveUserQuery( 'authors', users );
}

Expand Down
32 changes: 24 additions & 8 deletions lib/rest-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -424,16 +424,24 @@ function gutenberg_ensure_wp_json_has_theme_supports( $response ) {
*/
function gutenberg_handle_early_callback_checks( $response, $handler, $request ) {
if ( '/wp/v2/users' === $request->get_route() ) {
if ( ! empty( $request['who'] ) && 'authors' === $request['who'] ) {
$can_view = false;
$types = get_post_types( array( 'show_in_rest' => true ), 'objects' );
foreach ( $types as $type ) {
if ( post_type_supports( $type->name, 'author' )
&& current_user_can( $type->cap->edit_posts ) ) {
$can_view = true;
$can_view_authors = false;
$can_unbounded_query = false;
$types = get_post_types( array( 'show_in_rest' => true ), 'objects' );
foreach ( $types as $type ) {
if ( current_user_can( $type->cap->edit_posts ) ) {
$can_unbounded_query = true;
if ( post_type_supports( $type->name, 'author' ) ) {
$can_view_authors = true;
}
}
if ( ! $can_view ) {
}
if ( $request['per_page'] < 0 ) {
if ( ! $can_unbounded_query ) {
return new WP_Error( 'rest_forbidden_per_page', __( 'Sorry, you are not allowed make unbounded queries.', 'gutenberg' ), array( 'status' => rest_authorization_required_code() ) );
}
}
if ( ! empty( $request['who'] ) && 'authors' === $request['who'] ) {
if ( ! $can_view_authors ) {
return new WP_Error( 'rest_forbidden_who', __( 'Sorry, you are not allowed to query users by this parameter.', 'gutenberg' ), array( 'status' => rest_authorization_required_code() ) );
}
}
Expand All @@ -446,11 +454,19 @@ function gutenberg_handle_early_callback_checks( $response, $handler, $request )
* Include additional query parameters on the user query endpoint.
*
* @see https://core.trac.wordpress.org/ticket/42202
* @see https://core.trac.wordpress.org/ticket/43998
*
* @param array $query_params JSON Schema-formatted collection parameters.
* @return array
*/
function gutenberg_filter_user_collection_parameters( $query_params ) {
if ( isset( $query_params['per_page'] ) ) {
// Change from '1' to '-1', which means unlimited.
$query_params['per_page']['minimum'] = -1;
// Default sanitize callback is 'absint', which won't work in our case.
$query_params['per_page']['sanitize_callback'] = 'rest_sanitize_request_arg';
}
// Support for 'who' query param.
$query_params['who'] = array(
'description' => __( 'Limit result set to users who are considered authors.', 'gutenberg' ),
'type' => 'string',
Expand Down
18 changes: 18 additions & 0 deletions phpunit/class-gutenberg-rest-api-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,22 @@ public function test_get_items_who_unauthorized_query() {
$data = $response->get_data();
$this->assertEquals( 'rest_forbidden_who', $data['code'] );
}

public function test_get_items_unbounded_per_page() {
wp_set_current_user( $this->author );
$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
$request->set_param( 'per_page', '-1' );
$response = rest_get_server()->dispatch( $request );
$this->assertEquals( 200, $response->get_status() );
}

public function test_get_items_unbounded_per_page_unauthorized() {
wp_set_current_user( $this->subscriber );
$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
$request->set_param( 'per_page', '-1' );
$response = rest_get_server()->dispatch( $request );
$this->assertEquals( 403, $response->get_status() );
$data = $response->get_data();
$this->assertEquals( 'rest_forbidden_per_page', $data['code'] );
}
}

0 comments on commit 8e7ee59

Please sign in to comment.