Make WordPress Core

Ticket #17904: 17904.5.diff

File 17904.5.diff, 17.0 KB (added by ericlewis, 10 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                );