WordPress.org

Make WordPress Core

Changeset 39843


Ignore:
Timestamp:
01/11/17 14:13:48 (3 months ago)
Author:
aaroncampbell
Message:

REST API: Change which users are shown in the users endpoint.

Only show users that have authored a post of a post type that has show_in_rest set to true.

Props rachelbaker, jnylen0.
See #38878.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php

    r39671 r39843  
    250250 
    251251        if ( ! current_user_can( 'list_users' ) ) { 
    252             $prepared_args['has_published_posts'] = true; 
     252            $prepared_args['has_published_posts'] = get_post_types( array( 'show_in_rest' => true ), 'names' ); 
    253253        } 
    254254 
  • trunk/tests/phpunit/tests/rest-api/rest-users-controller.php

    r39660 r39843  
    1414    protected static $user; 
    1515    protected static $editor; 
     16    protected static $editor2; 
     17    protected static $secret_editor; 
     18    protected static $secret_editor2; 
    1619    protected static $site; 
    1720 
     
    2831            'user_email' => 'editor@example.com', 
    2932        ) ); 
     33        self::$editor2 = $factory->user->create( array( 
     34            'role'       => 'editor', 
     35            'user_email' => 'editor2@example.com', 
     36        ) ); 
     37        self::$secret_editor = $factory->user->create( array( 
     38            'role'       => 'editor', 
     39            'user_email' => 'secret_editor@example.com', 
     40        ) ); 
     41        self::$secret_editor2 = $factory->user->create( array( 
     42            'role'       => 'editor', 
     43            'user_email' => 'secret_editor2@example.com', 
     44        ) ); 
    3045 
    3146        if ( is_multisite() ) { 
     
    3853        self::delete_user( self::$user ); 
    3954        self::delete_user( self::$editor ); 
     55        self::delete_user( self::$editor2 ); 
     56        self::delete_user( self::$secret_editor ); 
     57        self::delete_user( self::$secret_editor2 ); 
    4058 
    4159        if ( is_multisite() ) { 
     
    4967    public function setUp() { 
    5068        parent::setUp(); 
     69 
     70        register_post_type( 'rest_public', array( 'public' => true, 'show_in_rest' => true ) ); 
     71        register_post_type( 'secret_public', array( 'public' => true, 'show_in_rest' => false ) ); 
     72        register_post_type( 'secret_hidden', array( 'public' => false, 'show_in_rest' => false ) ); 
     73        register_post_type( 'rest_hidden', array( 'public' => false, 'show_in_rest' => true ) ); 
     74 
    5175        $this->endpoint = new WP_REST_Users_Controller(); 
    5276    } 
     
    145169    } 
    146170 
    147     public function test_get_items_unauthenticated_only_shows_public_users() { 
    148         $request = new WP_REST_Request( 'GET', '/wp/v2/users' ); 
    149         $response = $this->server->dispatch( $request ); 
    150  
    151         $this->assertEquals( array(), $response->get_data() ); 
    152  
    153         $this->factory->post->create( array( 'post_author' => self::$editor ) ); 
    154         $this->factory->post->create( array( 'post_author' => self::$user, 'post_status' => 'draft' ) ); 
     171    public function test_get_items_unauthenticated_includes_authors_of_post_types_shown_in_rest() { 
     172        $created_posts = array(); 
     173        $created_posts[] = $this->factory->post->create( array( 
     174            'post_author' => self::$user, 
     175            'post_status' => 'publish', 
     176        ) ); 
     177        // Expose authors if show_in_rest is true, even if the post_type is not public. 
     178        $created_posts[] = $this->factory->post->create( array( 
     179            'post_type' => 'rest_hidden', 
     180            'post_author' => self::$editor, 
     181            'post_status' => 'publish', 
     182        ) ); 
     183        $created_posts[] = $this->factory->post->create( array( 
     184            'post_type' => 'rest_public', 
     185            'post_author' => self::$editor2, 
     186            'post_status' => 'publish', 
     187        ) ); 
     188        $created_posts[] = $this->factory->post->create( array( 
     189            'post_type' => 'rest_public', 
     190            'post_author' => self::$secret_editor, 
     191            'post_status' => 'draft', 
     192        ) ); 
    155193 
    156194        $request = new WP_REST_Request( 'GET', '/wp/v2/users' ); 
     
    158196        $users = $response->get_data(); 
    159197 
     198        $public_post_types = array_values( get_post_types( array( 'show_in_rest' => true ), 'names' ) ); 
     199 
    160200        foreach ( $users as $user ) { 
    161             $this->assertTrue( count_user_posts( $user['id'] ) > 0 ); 
    162  
    163             // Ensure we don't expose non-public data 
     201            $this->assertTrue( count_user_posts( $user['id'], $public_post_types ) > 0 ); 
     202 
     203            // Ensure we don't expose non-public data. 
    164204            $this->assertArrayNotHasKey( 'capabilities', $user ); 
     205            $this->assertArrayNotHasKey( 'registered_date', $user ); 
     206            $this->assertArrayNotHasKey( 'first_name', $user ); 
     207            $this->assertArrayNotHasKey( 'last_name', $user ); 
     208            $this->assertArrayNotHasKey( 'nickname', $user ); 
     209            $this->assertArrayNotHasKey( 'extra_capabilities', $user ); 
     210            $this->assertArrayNotHasKey( 'username', $user ); 
    165211            $this->assertArrayNotHasKey( 'email', $user ); 
    166212            $this->assertArrayNotHasKey( 'roles', $user ); 
     213            $this->assertArrayNotHasKey( 'locale', $user ); 
     214        } 
     215 
     216        $this->assertTrue( in_array( self::$user, wp_list_pluck( $users, 'id' ), true ) ); 
     217        $this->assertTrue( in_array( self::$editor, wp_list_pluck( $users, 'id' ), true ) ); 
     218        $this->assertTrue( in_array( self::$editor2, wp_list_pluck( $users, 'id' ), true ) ); 
     219 
     220        // Do not include authors of unpublished posts. 
     221        $this->assertFalse( in_array( self::$secret_editor, wp_list_pluck( $users, 'id' ), true ) ); 
     222 
     223        foreach ( $created_posts as $post_id ) { 
     224            wp_delete_post( $post_id, true ); 
     225        } 
     226    } 
     227 
     228    public function test_get_items_unauthenticated_does_not_include_authors_of_post_types_not_shown_in_rest() { 
     229        $created_posts = array(); 
     230        $created_posts[] = $this->factory->post->create( array( 
     231            'post_type' => 'secret_hidden', 
     232            'post_author' => self::$secret_editor, 
     233            'post_status' => 'publish', 
     234        ) ); 
     235        $created_posts[] = $this->factory->post->create( array( 
     236            'post_type' => 'secret_public', 
     237            'post_author' => self::$secret_editor2, 
     238            'post_status' => 'publish', 
     239        ) ); 
     240 
     241        $request = new WP_REST_Request( 'GET', '/wp/v2/users' ); 
     242        $response = $this->server->dispatch( $request ); 
     243        $data = $response->get_data(); 
     244 
     245        $this->assertFalse( in_array( self::$secret_editor, wp_list_pluck( $data, 'id' ), true ) ); 
     246        $this->assertFalse( in_array( self::$secret_editor2, wp_list_pluck( $data, 'id' ), true ) ); 
     247 
     248        foreach ( $created_posts as $post_id ) { 
     249            wp_delete_post( $post_id, true ); 
    167250        } 
    168251    } 
     
    170253    public function test_get_items_pagination_headers() { 
    171254        wp_set_current_user( self::$user ); 
    172         // Start of the index, including the three existing users 
    173         for ( $i = 0; $i < 47; $i++ ) { 
     255        // Start of the index, including the six existing users. 
     256        for ( $i = 0; $i < 44; $i++ ) { 
    174257            $this->factory->user->create( array( 
    175258                'name'   => "User {$i}", 
     
    392475    public function test_get_items_offset() { 
    393476        wp_set_current_user( self::$user ); 
    394         // 2 users created in __construct(), plus default user 
     477        // 5 users created in __construct(), plus default user. 
    395478        $this->factory->user->create(); 
    396479        $request = new WP_REST_Request( 'GET', '/wp/v2/users' ); 
    397480        $request->set_param( 'offset', 1 ); 
    398481        $response = $this->server->dispatch( $request ); 
    399         $this->assertCount( 4, $response->get_data() ); 
     482        $this->assertCount( 7, $response->get_data() ); 
    400483        // 'offset' works with 'per_page' 
    401484        $request->set_param( 'per_page', 2 ); 
     
    20842167 
    20852168    public function tearDown() { 
     2169        _unregister_post_type( 'rest_public' ); 
     2170        _unregister_post_type( 'secret_public' ); 
     2171        _unregister_post_type( 'secret_hidden' ); 
     2172        _unregister_post_type( 'rest_hidden' ); 
     2173 
    20862174        parent::tearDown(); 
    20872175    } 
Note: See TracChangeset for help on using the changeset viewer.