Make WordPress Core

Changeset 42855


Ignore:
Timestamp:
03/19/2018 08:28:28 PM (7 years ago)
Author:
ocean90
Message:

Users: Use promote_users for role updates in edit_user().

edit_user() can also update user roles but was still using the edit_users capability instead of the newer promote_users capability introduced in [14176].
This makes the role handling consistent with the bulk dropdown menu for role changes.

Props flixos90, johnjamesjacoby, ocean90.
Fixes #42564.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/user.php

    r42827 r42855  
    3131    $wp_roles = wp_roles();
    3232    $user     = new stdClass;
     33    $user_id  = (int) $user_id;
    3334    if ( $user_id ) {
    3435        $update           = true;
    35         $user->ID         = (int) $user_id;
     36        $user->ID         = $user_id;
    3637        $userdata         = get_userdata( $user_id );
    3738        $user->user_login = wp_slash( $userdata->user_login );
     
    5253    }
    5354
    54     if ( isset( $_POST['role'] ) && current_user_can( 'edit_users' ) ) {
    55         $new_role       = sanitize_text_field( $_POST['role'] );
    56         $potential_role = isset( $wp_roles->role_objects[ $new_role ] ) ? $wp_roles->role_objects[ $new_role ] : false;
    57         // Don't let anyone with 'edit_users' (admins) edit their own role to something without it.
    58         // Multisite super admins can freely edit their blog roles -- they possess all caps.
    59         if ( ( is_multisite() && current_user_can( 'manage_sites' ) ) || $user_id != get_current_user_id() || ( $potential_role && $potential_role->has_cap( 'edit_users' ) ) ) {
    60             $user->role = $new_role;
    61         }
    62 
    63         // If the new role isn't editable by the logged-in user die with error
     55    if ( isset( $_POST['role'] ) && current_user_can( 'promote_users' ) && ( ! $user_id || current_user_can( 'promote_user', $user_id ) ) ) {
     56        $new_role = sanitize_text_field( $_POST['role'] );
     57
     58        // If the new role isn't editable by the logged-in user die with error.
    6459        $editable_roles = get_editable_roles();
    6560        if ( ! empty( $new_role ) && empty( $editable_roles[ $new_role ] ) ) {
    6661            wp_die( __( 'Sorry, you are not allowed to give users that role.' ), 403 );
     62        }
     63
     64        $potential_role = isset( $wp_roles->role_objects[ $new_role ] ) ? $wp_roles->role_objects[ $new_role ] : false;
     65
     66        /*
     67         * Don't let anyone with 'promote_users' edit their own role to something without it.
     68         * Multisite super admins can freely edit their roles, they possess all caps.
     69         */
     70        if (
     71            ( is_multisite() && current_user_can( 'manage_network_users' ) ) ||
     72            $user_id !== get_current_user_id() ||
     73            ( $potential_role && $potential_role->has_cap( 'promote_users' ) )
     74        ) {
     75            $user->role = $new_role;
    6776        }
    6877    }
  • trunk/tests/phpunit/tests/user.php

    r42343 r42855  
    15421542        $this->assertNotContains( ''Test' blog's "name" has <html entities> &', $email->subject, 'Email subject does contains HTML entities' );
    15431543    }
     1544
     1545    /**
     1546     * @ticket 42564
     1547     */
     1548    function test_edit_user_role_update() {
     1549        $_POST = $_GET = $_REQUEST = array();
     1550
     1551        $administrator = self::factory()->user->create(
     1552            array(
     1553                'role' => 'administrator',
     1554            )
     1555        );
     1556
     1557        wp_set_current_user( $administrator );
     1558
     1559        // Don't let anyone with 'promote_users' (administrator) edit their own role to something without it (subscriber).
     1560        $_POST['role']     = 'subscriber';
     1561        $_POST['email']    = 'subscriber@subscriber.test';
     1562        $_POST['nickname'] = 'subscriber';
     1563        $this->assertSame(  $administrator, edit_user( $administrator ) );
     1564
     1565        // Should still have the old role.
     1566        $this->assertSame( array( 'administrator' ), get_userdata( $administrator )->roles );
     1567
     1568        // Promote an editor to an administrator.
     1569        $editor = self::factory()->user->create(
     1570            array(
     1571                'role' => 'editor',
     1572            )
     1573        );
     1574
     1575        $_POST['role']     = 'administrator';
     1576        $_POST['email']    = 'administrator@administrator.test';
     1577        $_POST['nickname'] = 'administrator';
     1578        $this->assertSame(  $editor, edit_user( $editor ) );
     1579
     1580        // Should have the new role.
     1581        $this->assertSame( array( 'administrator' ), get_userdata( $editor )->roles );
     1582    }
    15441583}
Note: See TracChangeset for help on using the changeset viewer.