WordPress.org

Make WordPress Core

Changeset 39219


Ignore:
Timestamp:
11/14/2016 07:12:31 AM (3 years ago)
Author:
rmccue
Message:

REST API: Improve validation for usernames and passwords.

Also improves the slashing of user data in the REST API to avoid data loss.

Props jnylen0.
Fixes #38739.

Location:
trunk
Files:
3 edited

Legend:

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

    r39177 r39219  
    418418
    419419            if ( is_wp_error( $ret['errors'] ) && ! empty( $ret['errors']->errors ) ) {
    420                 return $ret['errors'];
     420                $error = new WP_Error( 'rest_invalid_param', __( 'Invalid user parameter(s).' ), array( 'status' => 400 ) );
     421                foreach ( $ret['errors']->errors as $code => $messages ) {
     422                    foreach ( $messages as $message ) {
     423                        $error->add( $code, $message );
     424                    }
     425                    if ( $error_data = $error->get_error_data( $code ) ) {
     426                        $error->add_data( $error_data, $code );
     427                    }
     428                }
     429                return $error;
    421430            }
    422431        }
     
    430439
    431440            $user->ID = $user_id;
    432             $user_id  = wp_update_user( $user );
     441            $user_id  = wp_update_user( wp_slash( (array) $user ) );
    433442
    434443            if ( is_wp_error( $user_id ) ) {
     
    438447            add_user_to_blog( get_site()->id, $user_id, '' );
    439448        } else {
    440             $user_id = wp_insert_user( $user );
     449            $user_id = wp_insert_user( wp_slash( (array) $user ) );
    441450
    442451            if ( is_wp_error( $user_id ) ) {
     
    553562        $user->ID = $id;
    554563
    555         $user_id = wp_update_user( $user );
     564        $user_id = wp_update_user( wp_slash( (array) $user ) );
    556565
    557566        if ( is_wp_error( $user_id ) ) {
     
    9951004
    9961005        return true;
     1006    }
     1007
     1008    /**
     1009     * Check a username for the REST API.
     1010     *
     1011     * Performs a couple of checks like edit_user() in wp-admin/includes/user.php.
     1012     *
     1013     * @since 4.7.0
     1014     *
     1015     * @param  mixed            $value   The username submitted in the request.
     1016     * @param  WP_REST_Request  $request Full details about the request.
     1017     * @param  string           $param   The parameter name.
     1018     * @return WP_Error|string The sanitized username, if valid, otherwise an error.
     1019     */
     1020    public function check_username( $value, $request, $param ) {
     1021        $username = (string) rest_sanitize_value_from_schema( $value, $request, $param );
     1022
     1023        if ( ! validate_username( $username ) ) {
     1024            return new WP_Error( 'rest_user_invalid_username', __( 'Username contains invalid characters.' ), array( 'status' => 400 ) );
     1025        }
     1026
     1027        /** This filter is documented in wp-includes/user.php */
     1028        $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
     1029
     1030        if ( in_array( strtolower( $username ), array_map( 'strtolower', $illegal_logins ) ) ) {
     1031            return new WP_Error( 'rest_user_invalid_username', __( 'Sorry, that username is not allowed.' ), array( 'status' => 400 ) );
     1032        }
     1033
     1034        return $username;
     1035    }
     1036
     1037    /**
     1038     * Check a user password for the REST API.
     1039     *
     1040     * Performs a couple of checks like edit_user() in wp-admin/includes/user.php.
     1041     *
     1042     * @since 4.7.0
     1043     *
     1044     * @param  mixed            $value   The password submitted in the request.
     1045     * @param  WP_REST_Request  $request Full details about the request.
     1046     * @param  string           $param   The parameter name.
     1047     * @return WP_Error|string The sanitized password, if valid, otherwise an error.
     1048     */
     1049    public function check_user_password( $value, $request, $param ) {
     1050        $password = (string) rest_sanitize_value_from_schema( $value, $request, $param );
     1051
     1052        if ( empty( $password ) ) {
     1053            return new WP_Error( 'rest_user_invalid_password', __( 'Passwords cannot be empty.' ), array( 'status' => 400 ) );
     1054        }
     1055
     1056        if ( false !== strpos( $password, "\\" ) ) {
     1057            return new WP_Error( 'rest_user_invalid_password', __( 'Passwords cannot contain the "\\" character.' ), array( 'status' => 400 ) );
     1058        }
     1059
     1060        return $password;
    9971061    }
    9981062
     
    10231087                    'required'    => true,
    10241088                    'arg_options' => array(
    1025                         'sanitize_callback' => 'sanitize_user',
     1089                        'sanitize_callback' => array( $this, 'check_username' ),
    10261090                    ),
    10271091                ),
     
    10671131                    'type'        => 'string',
    10681132                    'context'     => array( 'embed', 'view', 'edit' ),
    1069                     'arg_options' => array(
    1070                         'sanitize_callback' => 'wp_filter_post_kses',
    1071                     ),
    10721133                ),
    10731134                'link'        => array(
     
    11201181                    'context'     => array(), // Password is never displayed.
    11211182                    'required'    => true,
     1183                    'arg_options' => array(
     1184                        'sanitize_callback' => array( $this, 'check_user_password' ),
     1185                    ),
    11221186                ),
    11231187                'capabilities'    => array(
  • trunk/tests/phpunit/includes/functions.php

    r38907 r39219  
    162162    return $uploads;
    163163}
     164
     165// Skip `setcookie` calls in auth_cookie functions due to warning:
     166// Cannot modify header information - headers already sent by ...
     167
     168function wp_set_auth_cookie( $user_id, $remember = false, $secure = '', $token = '' ) {
     169    $auth_cookie = null;
     170    $expire = null;
     171    $expiration = null;
     172    $user_id = null;
     173    $scheme = null;
     174    /** This action is documented in wp-inclues/pluggable.php */
     175    do_action( 'set_auth_cookie', $auth_cookie, $expire, $expiration, $user_id, $scheme );
     176    $logged_in_cookie = null;
     177    /** This action is documented in wp-inclues/pluggable.php */
     178    do_action( 'set_logged_in_cookie', $logged_in_cookie, $expire, $expiration, $user_id, 'logged_in' );
     179}
     180
     181function wp_clear_auth_cookie() {
     182    /** This action is documented in wp-inclues/pluggable.php */
     183    do_action( 'clear_auth_cookie' );
     184}
  • trunk/tests/phpunit/tests/rest-api/rest-users-controller.php

    r39177 r39219  
    1111 */
    1212class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase {
     13    protected static $superadmin;
    1314    protected static $user;
    1415    protected static $editor;
     
    1617
    1718    public static function wpSetUpBeforeClass( $factory ) {
     19        self::$superadmin = $factory->user->create( array(
     20            'role'       => 'administrator',
     21            'user_login' => 'superadmin',
     22        ) );
    1823        self::$user = $factory->user->create( array(
    1924            'role' => 'administrator',
     
    2631        if ( is_multisite() ) {
    2732            self::$site = $factory->blog->create( array( 'domain' => 'rest.wordpress.org', 'path' => '/' ) );
     33            update_site_option( 'site_admins', array( 'superadmin' ) );
    2834        }
    2935    }
     
    176182        $response = $this->server->dispatch( $request );
    177183        $headers = $response->get_headers();
    178         $this->assertEquals( 50, $headers['X-WP-Total'] );
    179         $this->assertEquals( 5, $headers['X-WP-TotalPages'] );
     184        $this->assertEquals( 51, $headers['X-WP-Total'] );
     185        $this->assertEquals( 6, $headers['X-WP-TotalPages'] );
    180186        $next_link = add_query_arg( array(
    181187            'page'    => 2,
     
    191197        $response = $this->server->dispatch( $request );
    192198        $headers = $response->get_headers();
    193         $this->assertEquals( 51, $headers['X-WP-Total'] );
     199        $this->assertEquals( 52, $headers['X-WP-Total'] );
    194200        $this->assertEquals( 6, $headers['X-WP-TotalPages'] );
    195201        $prev_link = add_query_arg( array(
     
    206212        $response = $this->server->dispatch( $request );
    207213        $headers = $response->get_headers();
    208         $this->assertEquals( 51, $headers['X-WP-Total'] );
     214        $this->assertEquals( 52, $headers['X-WP-Total'] );
    209215        $this->assertEquals( 6, $headers['X-WP-TotalPages'] );
    210216        $prev_link = add_query_arg( array(
     
    218224        $response = $this->server->dispatch( $request );
    219225        $headers = $response->get_headers();
    220         $this->assertEquals( 51, $headers['X-WP-Total'] );
     226        $this->assertEquals( 52, $headers['X-WP-Total'] );
    221227        $this->assertEquals( 6, $headers['X-WP-TotalPages'] );
    222228        $prev_link = add_query_arg( array(
     
    394400        $request->set_param( 'offset', 1 );
    395401        $response = $this->server->dispatch( $request );
    396         $this->assertCount( 3, $response->get_data() );
     402        $this->assertCount( 4, $response->get_data() );
    397403        // 'offset' works with 'per_page'
    398404        $request->set_param( 'per_page', 2 );
     
    716722    }
    717723
     724    public function test_create_item_invalid_username() {
     725        $this->allow_user_to_manage_multisite();
     726        wp_set_current_user( self::$user );
     727
     728        $params = array(
     729            'username'    => '¯\_(ツ)_/¯',
     730            'password'    => 'testpassword',
     731            'email'       => 'test@example.com',
     732            'name'        => 'Test User',
     733            'nickname'    => 'testuser',
     734            'slug'        => 'test-user',
     735            'roles'       => array( 'editor' ),
     736            'description' => 'New API User',
     737            'url'         => 'http://example.com',
     738        );
     739
     740        // Username rules are different (more strict) for multisite; see `wpmu_validate_user_signup`
     741        if ( is_multisite() ) {
     742            $params['username'] = 'no-dashes-allowed';
     743        }
     744
     745        $request = new WP_REST_Request( 'POST', '/wp/v2/users' );
     746        $request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
     747        $request->set_body_params( $params );
     748
     749        $response = $this->server->dispatch( $request );
     750        $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     751
     752        $data = $response->get_data();
     753        if ( is_multisite() ) {
     754            $this->assertInternalType( 'array', $data['additional_errors'] );
     755            $this->assertCount( 1, $data['additional_errors'] );
     756            $error = $data['additional_errors'][0];
     757            $this->assertEquals( 'user_name', $error['code'] );
     758            $this->assertEquals( 'Usernames can only contain lowercase letters (a-z) and numbers.', $error['message'] );
     759        } else {
     760            $this->assertInternalType( 'array', $data['data']['params'] );
     761            $errors = $data['data']['params'];
     762            $this->assertInternalType( 'string', $errors['username'] );
     763            $this->assertEquals( 'Username contains invalid characters.', $errors['username'] );
     764        }
     765    }
     766
     767    function get_illegal_user_logins() {
     768        return array( 'nope' );
     769    }
     770
     771    public function test_create_item_illegal_username() {
     772        $this->allow_user_to_manage_multisite();
     773        wp_set_current_user( self::$user );
     774
     775        add_filter( 'illegal_user_logins', array( $this, 'get_illegal_user_logins' ) );
     776
     777        $params = array(
     778            'username'    => 'nope',
     779            'password'    => 'testpassword',
     780            'email'       => 'test@example.com',
     781            'name'        => 'Test User',
     782            'nickname'    => 'testuser',
     783            'slug'        => 'test-user',
     784            'roles'       => array( 'editor' ),
     785            'description' => 'New API User',
     786            'url'         => 'http://example.com',
     787        );
     788
     789        $request = new WP_REST_Request( 'POST', '/wp/v2/users' );
     790        $request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
     791        $request->set_body_params( $params );
     792
     793        $response = $this->server->dispatch( $request );
     794
     795        remove_filter( 'illegal_user_logins', array( $this, 'get_illegal_user_logins' ) );
     796
     797        $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     798
     799        $data = $response->get_data();
     800        $this->assertInternalType( 'array', $data['data']['params'] );
     801        $errors = $data['data']['params'];
     802        $this->assertInternalType( 'string', $errors['username'] );
     803        $this->assertEquals( 'Sorry, that username is not allowed.', $errors['username'] );
     804    }
     805
    718806    public function test_create_new_network_user_on_site_does_not_add_user_to_sub_site() {
    719807        if ( ! is_multisite() ) {
     
    811899        wpmu_delete_user( $user_id );
    812900
    813         $this->assertErrorResponse( 'user_name', $switched_response );
     901        $this->assertErrorResponse( 'rest_invalid_param', $switched_response, 400 );
     902        $data = $switched_response->get_data();
     903        $this->assertInternalType( 'array', $data['additional_errors'] );
     904        $this->assertCount( 2, $data['additional_errors'] );
     905        $errors = $data['additional_errors'];
     906        foreach ( $errors as $error ) {
     907            // Check the code matches one we know.
     908            $this->assertContains( $error['code'], array( 'user_name', 'user_email' ) );
     909            if ( 'user_name' === $error['code'] ) {
     910                $this->assertEquals( 'Sorry, that username already exists!', $error['message'] );
     911            } else {
     912                $this->assertEquals( 'Sorry, that email address is already used!', $error['message'] );
     913            }
     914        }
    814915    }
    815916
     
    13041405
    13051406        $this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 );
     1407    }
     1408
     1409    public function test_update_item_invalid_password() {
     1410        $this->allow_user_to_manage_multisite();
     1411        wp_set_current_user( self::$user );
     1412
     1413        $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', self::$editor ) );
     1414
     1415        $request->set_param( 'password', 'no\\backslashes\\allowed' );
     1416        $response = $this->server->dispatch( $request );
     1417        $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     1418
     1419        $request->set_param( 'password', '' );
     1420        $response = $this->server->dispatch( $request );
     1421        $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     1422    }
     1423
     1424    public function verify_user_roundtrip( $input = array(), $expected_output = array() ) {
     1425        if ( isset( $input['id'] ) ) {
     1426            // Existing user; don't try to create one
     1427            $user_id = $input['id'];
     1428        } else {
     1429            // Create a new user
     1430            $request = new WP_REST_Request( 'POST', '/wp/v2/users' );
     1431            foreach ( $input as $name => $value ) {
     1432                $request->set_param( $name, $value );
     1433            }
     1434            $request->set_param( 'email', 'cbg@androidsdungeon.com' );
     1435            $response = $this->server->dispatch( $request );
     1436            $this->assertEquals( 201, $response->get_status() );
     1437            $actual_output = $response->get_data();
     1438
     1439            // Compare expected API output to actual API output
     1440            $this->assertEquals( $expected_output['username']   , $actual_output['username'] );
     1441            $this->assertEquals( $expected_output['name']       , $actual_output['name'] );
     1442            $this->assertEquals( $expected_output['first_name'] , $actual_output['first_name'] );
     1443            $this->assertEquals( $expected_output['last_name']  , $actual_output['last_name'] );
     1444            $this->assertEquals( $expected_output['url']        , $actual_output['url'] );
     1445            $this->assertEquals( $expected_output['description'], $actual_output['description'] );
     1446            $this->assertEquals( $expected_output['nickname']   , $actual_output['nickname'] );
     1447
     1448            // Compare expected API output to WP internal values
     1449            $user = get_userdata( $actual_output['id'] );
     1450            $this->assertEquals( $expected_output['username']   , $user->user_login );
     1451            $this->assertEquals( $expected_output['name']       , $user->display_name );
     1452            $this->assertEquals( $expected_output['first_name'] , $user->first_name );
     1453            $this->assertEquals( $expected_output['last_name']  , $user->last_name );
     1454            $this->assertEquals( $expected_output['url']        , $user->user_url );
     1455            $this->assertEquals( $expected_output['description'], $user->description );
     1456            $this->assertEquals( $expected_output['nickname']   , $user->nickname );
     1457            $this->assertTrue( wp_check_password( addslashes( $expected_output['password'] ), $user->user_pass ) );
     1458
     1459            $user_id = $actual_output['id'];
     1460        }
     1461
     1462        // Update the user
     1463        $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $user_id ) );
     1464        foreach ( $input as $name => $value ) {
     1465            if ( 'username' !== $name ) {
     1466                $request->set_param( $name, $value );
     1467            }
     1468        }
     1469        $response = $this->server->dispatch( $request );
     1470        $this->assertEquals( 200, $response->get_status() );
     1471        $actual_output = $response->get_data();
     1472
     1473        // Compare expected API output to actual API output
     1474        if ( isset( $expected_output['username'] ) ) {
     1475            $this->assertEquals( $expected_output['username'], $actual_output['username'] );
     1476        }
     1477        $this->assertEquals( $expected_output['name']       , $actual_output['name'] );
     1478        $this->assertEquals( $expected_output['first_name'] , $actual_output['first_name'] );
     1479        $this->assertEquals( $expected_output['last_name']  , $actual_output['last_name'] );
     1480        $this->assertEquals( $expected_output['url']        , $actual_output['url'] );
     1481        $this->assertEquals( $expected_output['description'], $actual_output['description'] );
     1482        $this->assertEquals( $expected_output['nickname']   , $actual_output['nickname'] );
     1483
     1484        // Compare expected API output to WP internal values
     1485        $user = get_userdata( $actual_output['id'] );
     1486        if ( isset( $expected_output['username'] ) ) {
     1487            $this->assertEquals( $expected_output['username'], $user->user_login );
     1488        }
     1489        $this->assertEquals( $expected_output['name']       , $user->display_name );
     1490        $this->assertEquals( $expected_output['first_name'] , $user->first_name );
     1491        $this->assertEquals( $expected_output['last_name']  , $user->last_name );
     1492        $this->assertEquals( $expected_output['url']        , $user->user_url );
     1493        $this->assertEquals( $expected_output['description'], $user->description );
     1494        $this->assertEquals( $expected_output['nickname']   , $user->nickname );
     1495        $this->assertTrue( wp_check_password( addslashes( $expected_output['password'] ), $user->user_pass ) );
     1496    }
     1497
     1498    public function test_user_roundtrip_as_editor() {
     1499        wp_set_current_user( self::$editor );
     1500        $this->assertEquals( ! is_multisite(), current_user_can( 'unfiltered_html' ) );
     1501        $this->verify_user_roundtrip( array(
     1502            'id'          => self::$editor,
     1503            'name'        => '\o/ ¯\_(ツ)_/¯',
     1504            'first_name'  => '\o/ ¯\_(ツ)_/¯',
     1505            'last_name'   => '\o/ ¯\_(ツ)_/¯',
     1506            'url'         => '\o/ ¯\_(ツ)_/¯',
     1507            'description' => '\o/ ¯\_(ツ)_/¯',
     1508            'nickname'    => '\o/ ¯\_(ツ)_/¯',
     1509            'password'    => 'o/ ¯_(ツ)_/¯ \'"',
     1510        ), array(
     1511            'name'        => '\o/ ¯\_(ツ)_/¯',
     1512            'first_name'  => '\o/ ¯\_(ツ)_/¯',
     1513            'last_name'   => '\o/ ¯\_(ツ)_/¯',
     1514            'url'         => 'http://o/%20¯_(ツ)_/¯',
     1515            'description' => '\o/ ¯\_(ツ)_/¯',
     1516            'nickname'    => '\o/ ¯\_(ツ)_/¯',
     1517            'password'    => 'o/ ¯_(ツ)_/¯ \'"',
     1518        ) );
     1519    }
     1520
     1521    public function test_user_roundtrip_as_editor_html() {
     1522        wp_set_current_user( self::$editor );
     1523        if ( is_multisite() ) {
     1524            $this->assertFalse( current_user_can( 'unfiltered_html' ) );
     1525            $this->verify_user_roundtrip( array(
     1526                'id'          => self::$editor,
     1527                'name'        => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1528                'first_name'  => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1529                'last_name'   => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1530                'url'         => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1531                'description' => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1532                'nickname'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1533                'password'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1534            ), array(
     1535                'name'        => 'div strong',
     1536                'first_name'  => 'div strong',
     1537                'last_name'   => 'div strong',
     1538                'url'         => 'http://divdiv/div%20strongstrong/strong%20scriptoh%20noes/script',
     1539                'description' => 'div <strong>strong</strong> oh noes',
     1540                'nickname'    => 'div strong',
     1541                'password'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1542            ) );
     1543        } else {
     1544            $this->assertTrue( current_user_can( 'unfiltered_html' ) );
     1545            $this->verify_user_roundtrip( array(
     1546                'id'          => self::$editor,
     1547                'name'        => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1548                'first_name'  => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1549                'last_name'   => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1550                'url'         => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1551                'description' => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1552                'nickname'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1553                'password'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1554            ), array(
     1555                'name'        => 'div strong',
     1556                'first_name'  => 'div strong',
     1557                'last_name'   => 'div strong',
     1558                'url'         => 'http://divdiv/div%20strongstrong/strong%20scriptoh%20noes/script',
     1559                'description' => 'div <strong>strong</strong> oh noes',
     1560                'nickname'    => 'div strong',
     1561                'password'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1562            ) );
     1563        }
     1564    }
     1565
     1566    public function test_user_roundtrip_as_superadmin() {
     1567        wp_set_current_user( self::$superadmin );
     1568        $this->assertTrue( current_user_can( 'unfiltered_html' ) );
     1569        $valid_username = is_multisite() ? 'noinvalidcharshere' : 'no-invalid-chars-here';
     1570        $this->verify_user_roundtrip( array(
     1571            'username'    => $valid_username,
     1572            'name'        => '\\\&\\\ &amp; &invalid; < &lt; &amp;lt;',
     1573            'first_name'  => '\\\&\\\ &amp; &invalid; < &lt; &amp;lt;',
     1574            'last_name'   => '\\\&\\\ &amp; &invalid; < &lt; &amp;lt;',
     1575            'url'         => '\\\&\\\ &amp; &invalid; < &lt; &amp;lt;',
     1576            'description' => '\\\&\\\ &amp; &invalid; < &lt; &amp;lt;',
     1577            'nickname'    => '\\\&\\\ &amp; &invalid; < &lt; &amp;lt;',
     1578            'password'    => '& &amp; &invalid; < &lt; &amp;lt;',
     1579        ), array(
     1580            'username'    => $valid_username,
     1581            'name'        => '\\\&amp;\\\ &amp; &amp;invalid; &lt; &lt; &amp;lt;',
     1582            'first_name'  => '\\\&amp;\\\ &amp; &amp;invalid; &lt; &lt; &amp;lt;',
     1583            'last_name'   => '\\\&amp;\\\ &amp; &amp;invalid; &lt; &lt; &amp;lt;',
     1584            'url'         => 'http://&amp;%20&amp;%20&amp;invalid;%20%20&lt;%20&amp;lt;',
     1585            'description' => '\\\&amp;\\\ &amp; &amp;invalid; &lt; &lt; &amp;lt;',
     1586            'nickname'    => '\\\&amp;\\\ &amp; &amp;invalid; &lt; &lt; &amp;lt;',
     1587            'password'    => '& &amp; &invalid; < &lt; &amp;lt;',
     1588        ) );
     1589    }
     1590
     1591    public function test_user_roundtrip_as_superadmin_html() {
     1592        wp_set_current_user( self::$superadmin );
     1593        $this->assertTrue( current_user_can( 'unfiltered_html' ) );
     1594        $valid_username = is_multisite() ? 'noinvalidcharshere' : 'no-invalid-chars-here';
     1595        $this->verify_user_roundtrip( array(
     1596            'username'    => $valid_username,
     1597            'name'        => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1598            'first_name'  => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1599            'last_name'   => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1600            'url'         => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1601            'description' => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1602            'nickname'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1603            'password'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1604        ), array(
     1605            'username'    => $valid_username,
     1606            'name'        => 'div strong',
     1607            'first_name'  => 'div strong',
     1608            'last_name'   => 'div strong',
     1609            'url'         => 'http://divdiv/div%20strongstrong/strong%20scriptoh%20noes/script',
     1610            'description' => 'div <strong>strong</strong> oh noes',
     1611            'nickname'    => 'div strong',
     1612            'password'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1613        ) );
    13061614    }
    13071615
Note: See TracChangeset for help on using the changeset viewer.