WordPress.org

Make WordPress Core

Ticket #17904: 17904.5.diff

File 17904.5.diff, 17.0 KB (added by ericlewis, 4 years ago)
  • src/wp-admin/includes/user.php

     
    2020/**
    2121 * Edit user settings based on contents of $_POST
    2222 *
    23  * Used on user-edit.php and profile.php to manage and process user options, passwords etc.
     23 * Used on user-edit.php, user-new.php, and profile.php to manage and process user options, passwords etc.
    2424 *
    2525 * @since 2.0.0
    2626 *
     
    3939                $update = false;
    4040        }
    4141
    42         if ( !$update && isset( $_POST['user_login'] ) )
    43                 $user->user_login = sanitize_user($_POST['user_login'], true);
    44 
    4542        $pass1 = $pass2 = '';
    4643        if ( isset( $_POST['pass1'] ) )
    4744                $pass1 = $_POST['pass1'];
     
    104101
    105102        $errors = new WP_Error();
    106103
    107         /* checking that username has been typed */
    108         if ( $user->user_login == '' )
    109                 $errors->add( 'user_login', __( '<strong>ERROR</strong>: Please enter a username.' ) );
     104        /* Validate the user_login when not updating the user */
     105        if ( ! $update ) {
     106                $user->user_login = '';
    110107
     108                if ( isset( $_POST['user_login'] ) ) {
     109                        $user->user_login = $_POST['user_login'];
     110                }
     111
     112                wp_validate_user_login( $user->user_login, $errors );
     113        }
     114
    111115        /* checking that nickname has been typed */
    112116        if ( $update && empty( $user->nickname ) ) {
    113117                $errors->add( 'nickname', __( '<strong>ERROR</strong>: Please enter a nickname.' ) );
     
    142146        if ( !empty( $pass1 ) )
    143147                $user->user_pass = $pass1;
    144148
    145         if ( !$update && isset( $_POST['user_login'] ) && !validate_username( $_POST['user_login'] ) )
    146                 $errors->add( 'user_login', __( '<strong>ERROR</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.' ));
    147 
    148         if ( !$update && username_exists( $user->user_login ) )
    149                 $errors->add( 'user_login', __( '<strong>ERROR</strong>: This username is already registered. Please choose another one.' ));
    150 
    151149        /** This filter is documented in wp-includes/user.php */
    152150        $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
    153151
  • src/wp-includes/ms-functions.php

     
    400400 *
    401401 * @global wpdb $wpdb WordPress database abstraction object.
    402402 *
    403  * @param string $user_name The login name provided by the user.
     403 * @param string $user_login The login name provided by the user.
    404404 * @param string $user_email The email provided by the user.
    405405 * @return array Contains username, email, and error messages.
    406406 */
    407 function wpmu_validate_user_signup($user_name, $user_email) {
     407function wpmu_validate_user_signup( $user_login, $user_email ) {
    408408        global $wpdb;
    409409
    410410        $errors = new WP_Error();
     411        $orig_userlogin = $user_login;
     412        wp_validate_user_login( $user_login, $errors );
    411413
    412         $orig_username = $user_name;
    413         $user_name = preg_replace( '/\s+/', '', sanitize_user( $user_name, true ) );
    414 
    415         if ( $user_name != $orig_username || preg_match( '/[^a-z0-9]/', $user_name ) ) {
    416                 $errors->add( 'user_name', __( 'Usernames can only contain lowercase letters (a-z) and numbers.' ) );
    417                 $user_name = $orig_username;
    418         }
    419 
    420414        $user_email = sanitize_email( $user_email );
    421415
    422         if ( empty( $user_name ) )
    423                 $errors->add('user_name', __( 'Please enter a username.' ) );
    424 
    425         $illegal_names = get_site_option( 'illegal_names' );
    426         if ( ! is_array( $illegal_names ) ) {
    427                 $illegal_names = array(  'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator' );
    428                 add_site_option( 'illegal_names', $illegal_names );
    429         }
    430         if ( in_array( $user_name, $illegal_names ) ) {
    431                 $errors->add( 'user_name',  __( 'Sorry, that username is not allowed.' ) );
    432         }
    433 
    434         /** This filter is documented in wp-includes/user.php */
    435         $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
    436 
    437         if ( in_array( strtolower( $user_name ), array_map( 'strtolower', $illegal_logins ) ) ) {
    438                 $errors->add( 'user_name',  __( 'Sorry, that username is not allowed.' ) );
    439         }
    440 
    441416        if ( is_email_address_unsafe( $user_email ) )
    442417                $errors->add('user_email',  __('You cannot use that email address to signup. We are having problems with them blocking some of our email. Please use another email provider.'));
    443418
    444         if ( strlen( $user_name ) < 4 )
    445                 $errors->add('user_name',  __( 'Username must be at least 4 characters.' ) );
    446 
    447         if ( strlen( $user_name ) > 60 ) {
    448                 $errors->add( 'user_name', __( 'Username may not be longer than 60 characters.' ) );
    449         }
    450 
    451         // all numeric?
    452         if ( preg_match( '/^[0-9]*$/', $user_name ) )
    453                 $errors->add('user_name', __('Sorry, usernames must have letters too!'));
    454 
    455419        if ( !is_email( $user_email ) )
    456420                $errors->add('user_email', __( 'Please enter a valid email address.' ) );
    457421
     
    463427                }
    464428        }
    465429
    466         // Check if the username has been used already.
    467         if ( username_exists($user_name) )
    468                 $errors->add( 'user_name', __( 'Sorry, that username already exists!' ) );
    469 
    470430        // Check if the email address has been used already.
    471431        if ( email_exists($user_email) )
    472432                $errors->add( 'user_email', __( 'Sorry, that email address is already used!' ) );
    473433
    474         // Has someone already signed up for this username?
    475         $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE user_login = %s", $user_name) );
    476         if ( $signup != null ) {
    477                 $registered_at =  mysql2date('U', $signup->registered);
    478                 $now = current_time( 'timestamp', true );
    479                 $diff = $now - $registered_at;
    480                 // If registered more than two days ago, cancel registration and let this signup go through.
    481                 if ( $diff > 2 * DAY_IN_SECONDS )
    482                         $wpdb->delete( $wpdb->signups, array( 'user_login' => $user_name ) );
    483                 else
    484                         $errors->add('user_name', __('That username is currently reserved but may be available in a couple of days.'));
    485         }
    486 
    487434        $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE user_email = %s", $user_email) );
    488435        if ( $signup != null ) {
    489436                $diff = current_time( 'timestamp', true ) - mysql2date('U', $signup->registered);
     
    494441                        $errors->add('user_email', __('That email address has already been used. Please check your inbox for an activation email. It will become available in a couple of days if you do nothing.'));
    495442        }
    496443
    497         $result = array('user_name' => $user_name, 'orig_username' => $orig_username, 'user_email' => $user_email, 'errors' => $errors);
     444        $result = array( 'user_name' => $user_login, 'orig_username' => $orig_userlogin, 'user_email' => $user_email, 'errors' => $errors );
    498445
    499446        /**
    500447         * Filter the validated user registration details.
  • src/wp-includes/user.php

     
    22252225}
    22262226
    22272227/**
     2228 * Validate a provided user_login
     2229 *
     2230 * user_login requirements:
     2231 *     - minimum of 4 characters
     2232 *     - maximum of 60 characters
     2233 *     - only contains (case-insensitive) characters: a-z 0-9 _ . - @
     2234 *     - no whitespace
     2235 *     - not on blacklist of illegal names
     2236 *     - contains at least one letter
     2237 *     - must be unique
     2238 *     - not pending signup already
     2239 *
     2240 * @since TBD
     2241 *
     2242 * @param string $user_login The user_login value to be be validated.
     2243 *
     2244 * @return True|WP_Error True if the user login is valid, WP_Error otherwise.
     2245 */
     2246function wp_validate_user_login( $user_login = '', $errors = null ) {
     2247        global $wpdb;
     2248        $original_user_login = $user_login;
     2249
     2250        if ( ! is_wp_error( $errors ) ) {
     2251                $errors = new WP_Error();
     2252        }
     2253
     2254        // User login cannot be empty
     2255        if ( empty( $user_login ) ) {
     2256                $errors->add( 'user_name', __( 'Please enter a username.' ) );
     2257        }
     2258
     2259        // User login must be less than 60 characters
     2260        if ( strlen( $user_login ) > 60 ) {
     2261                $errors->add( 'user_name', __( 'Username may not be longer than 60 characters.' ) );
     2262        }
     2263
     2264        // Strip any whitespace and then match against case insensitive characters a-z 0-9 _ . - @
     2265        $user_login = preg_replace( '/\s+/', '', sanitize_user( $user_login, true ) );
     2266
     2267        // If the previous operation generated a different value, the username is invalid
     2268        if ( $user_login !== $original_user_login ) {
     2269                $errors->add( 'user_name', __( '<strong>ERROR</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.' ) );
     2270        }
     2271
     2272        if ( is_multisite() ) {
     2273                // Check the user_login against an array of illegal names
     2274                $illegal_logins = get_site_option( 'illegal_names' );
     2275                if ( false == is_array( $illegal_logins ) ) {
     2276                        $illegal_logins = array( 'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator' );
     2277                        add_site_option( 'illegal_names', $illegal_logins );
     2278                }
     2279                if ( in_array( $user_login, $illegal_logins ) ) {
     2280                        $errors->add( 'user_name',  __( 'Sorry, that username is not allowed.' ) );
     2281                }
     2282        }
     2283
     2284        /** This filter is documented in wp-includes/user.php */
     2285        $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
     2286
     2287        if ( in_array( strtolower( $user_login ), array_map( 'strtolower', $illegal_logins ) ) ) {
     2288                if ( is_multisite() ) {
     2289                        $errors->add( 'user_name',  __( 'Sorry, that username is not allowed.' ) );
     2290                } else {
     2291                        $errors->add( 'invalid_username',  __( 'Sorry, that username is not allowed.' ) );
     2292                }
     2293        }
     2294
     2295        if ( is_multisite() ) {
     2296                // User login must have at least one letter
     2297                if ( ! preg_match( '/[a-zA-Z]+/', $user_login ) ) {
     2298                        $errors->add( 'user_name', __( 'Sorry, usernames must have letters too!' ) );
     2299                }
     2300        }
     2301
     2302        // Check if the username has been used already.
     2303        if ( username_exists( $user_login ) ) {
     2304                $errors->add( 'user_name', __( 'Sorry, that username already exists!' ) );
     2305        }
     2306
     2307        if ( is_multisite() ) {
     2308                // Has someone already signed up for this username?
     2309                $signup = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->signups WHERE user_login = %s", $user_login ) );
     2310                if ( $signup != null ) {
     2311                        $registered_at =  mysql2date( 'U', $signup->registered );
     2312                        $now = current_time( 'timestamp', true );
     2313                        $diff = $now - $registered_at;
     2314                        // If registered more than two days ago, cancel registration and let this signup go through.
     2315                        if ( $diff > 2 * DAY_IN_SECONDS )
     2316                                $wpdb->delete( $wpdb->signups, array( 'user_login' => $user_login ) );
     2317                        else
     2318                                $errors->add( 'user_name', __( 'That username is currently reserved but may be available in a couple of days.' ) );
     2319                }
     2320        }
     2321
     2322        /**
     2323         * Filter whether the provided user_login is valid or not.
     2324         *
     2325         * @since 2.0.1
     2326         *
     2327         * @param bool   $valid      Whether given user_login is valid.
     2328         * @param string $user_login user_login to check.
     2329         */
     2330        $valid = apply_filters( 'validate_username', true, $user_login );
     2331        if ( ! $valid ) {
     2332                $errors->add( 'user_name', __( 'Sorry, that username is invalid.' ) );
     2333        }
     2334
     2335        /**
     2336         * Validate a user_login. A user_login can be invalidated by adding an error
     2337         * to the WP_Error.
     2338         *
     2339         * @since TBD
     2340         *
     2341         * @param  WP_Error $errors
     2342         * @param  string   $user_login The user_login to validate.
     2343         */
     2344        do_action( 'wp_validate_user_login', $errors, $user_login );
     2345
     2346        if ( $errors->errors ) {
     2347                return $errors;
     2348        } else {
     2349                return true;
     2350        }
     2351}
     2352
     2353/**
    22282354 * Handles registering a new user.
    22292355 *
    22302356 * @since 2.5.0
     
    22362362function register_new_user( $user_login, $user_email ) {
    22372363        $errors = new WP_Error();
    22382364
    2239         $sanitized_user_login = sanitize_user( $user_login );
    22402365        /**
    22412366         * Filter the email address of a user being registered.
    22422367         *
     
    22462371         */
    22472372        $user_email = apply_filters( 'user_registration_email', $user_email );
    22482373
    2249         // Check the username
    2250         if ( $sanitized_user_login == '' ) {
    2251                 $errors->add( 'empty_username', __( '<strong>ERROR</strong>: Please enter a username.' ) );
    2252         } elseif ( ! validate_username( $user_login ) ) {
    2253                 $errors->add( 'invalid_username', __( '<strong>ERROR</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.' ) );
    2254                 $sanitized_user_login = '';
    2255         } elseif ( username_exists( $sanitized_user_login ) ) {
    2256                 $errors->add( 'username_exists', __( '<strong>ERROR</strong>: This username is already registered. Please choose another one.' ) );
     2374        // Validate the username
     2375        wp_validate_user_login( $user_login, $errors );
    22572376
    2258         } else {
    2259                 /** This filter is documented in wp-includes/user.php */
    2260                 $illegal_user_logins = array_map( 'strtolower', (array) apply_filters( 'illegal_user_logins', array() ) );
    2261                 if ( in_array( strtolower( $sanitized_user_login ), $illegal_user_logins ) ) {
    2262                         $errors->add( 'invalid_username', __( '<strong>ERROR</strong>: Sorry, that username is not allowed.' ) );
    2263                 }
    2264         }
    2265 
    22662377        // Check the email address
    22672378        if ( $user_email == '' ) {
    22682379                $errors->add( 'empty_email', __( '<strong>ERROR</strong>: Please type your email address.' ) );
     
    22782389         *
    22792390         * @since 2.1.0
    22802391         *
    2281          * @param string   $sanitized_user_login The submitted username after being sanitized.
    2282          * @param string   $user_email           The submitted email.
    2283          * @param WP_Error $errors               Contains any errors with submitted username and email,
    2284          *                                       e.g., an empty field, an invalid username or email,
    2285          *                                       or an existing username or email.
     2392         * @param string   $user_login The submitted username after being sanitized.
     2393         * @param string   $user_email The submitted email.
     2394         * @param WP_Error $errors     Contains any errors with submitted username and email,
     2395         *                             e.g., an empty field, an invalid username or email,
     2396         *                             or an existing username or email.
    22862397         */
    2287         do_action( 'register_post', $sanitized_user_login, $user_email, $errors );
     2398        do_action( 'register_post', $user_login, $user_email, $errors );
    22882399
    22892400        /**
    22902401         * Filter the errors encountered when a new user is being registered.
     
    22972408         *
    22982409         * @since 2.1.0
    22992410         *
    2300          * @param WP_Error $errors               A WP_Error object containing any errors encountered
    2301          *                                       during registration.
    2302          * @param string   $sanitized_user_login User's username after it has been sanitized.
    2303          * @param string   $user_email           User's email.
     2411         * @param WP_Error $errors     A WP_Error object containing any errors encountered
     2412         *                             during registration.
     2413         * @param string   $user_login User's username.
     2414         * @param string   $user_email User's email.
    23042415         */
    2305         $errors = apply_filters( 'registration_errors', $errors, $sanitized_user_login, $user_email );
     2416        $errors = apply_filters( 'registration_errors', $errors, $user_login, $user_email );
    23062417
    23072418        if ( $errors->get_error_code() )
    23082419                return $errors;
    23092420
    23102421        $user_pass = wp_generate_password( 12, false );
    2311         $user_id = wp_create_user( $sanitized_user_login, $user_pass, $user_email );
     2422        $user_id = wp_create_user( $user_login, $user_pass, $user_email );
    23122423        if ( ! $user_id || is_wp_error( $user_id ) ) {
    23132424                $errors->add( 'registerfail', sprintf( __( '<strong>ERROR</strong>: Couldn&#8217;t register you&hellip; please contact the <a href="mailto:%s">webmaster</a> !' ), get_option( 'admin_email' ) ) );
    23142425                return $errors;
  • src/wp-signup.php

     
    639639        $errors = $filtered_results['errors'];
    640640
    641641        if ( empty($blogname) )
    642                 $blogname = $user_name;
     642                $blogname = preg_replace( '|[ _.\-@]|i', '', $user_name );
    643643        ?>
    644644        <form id="setupform" method="post" action="wp-signup.php">
    645645                <input type="hidden" name="stage" value="validate-blog-signup" />
  • tests/phpunit/tests/multisite/wpmuValidateUserSignup.php

     
    99        /**
    1010         * @dataProvider data_user_name
    1111         */
    12         public function test_user_name( $user_name, $error_message ) {
    13                 $v = wpmu_validate_user_signup( $user_name, 'foo@example.com' );
     12        public function test_user_name( $user_login, $error_message ) {
     13                $v = wpmu_validate_user_signup( $user_login, 'foo@example.com' );
    1414                $this->assertContains( 'user_name', $v['errors']->get_error_codes(), $error_message );
    1515        }
    1616
     
    1818                return array(
    1919                        array( 'contains spaces', 'User names with spaces are not allowed.' ),
    2020                        array( 'ContainsCaps', 'User names with capital letters are not allowed.'  ),
    21                         array( 'contains_underscores', 'User names with underscores are not allowed.'  ),
    2221                        array( 'contains%^*()junk', 'User names with non-alphanumeric characters are not allowed.'  ),
    2322                        array( '', 'Empty user names are not allowed.'  ),
    24                         array( 'foo', 'User names of 3 characters are not allowed.'  ),
    25                         array( 'fo', 'User names of 2 characters are not allowed.'  ),
    26                         array( 'f', 'User names of 1 characters are not allowed.'  ),
    27                         array( 'f', 'User names of 1 characters are not allowed.'  ),
    2823                        array( '12345', 'User names consisting only of numbers are not allowed.'  ),
    2924                        array( 'thisusernamecontainsenoughcharacterstobelongerthan60characters', 'User names longer than 60 characters are not allowed.' ),
    3025                );