Make WordPress Core

Ticket #17904: 17904.6.diff

File 17904.6.diff, 17.6 KB (added by FolioVision, 8 years ago)

Making it possible to signup with user name with spaces and uppercase letters

  • 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-default-filters.php

     
    3030add_action( 'network_site_new_created_user',   'wp_send_new_user_notifications' );
    3131add_action( 'network_site_users_created_user', 'wp_send_new_user_notifications' );
    3232add_action( 'network_user_new_created_user',   'wp_send_new_user_notifications' );
    33 add_filter( 'sanitize_user', 'strtolower' );
    3433
    3534// Blogs
    3635add_filter( 'wpmu_validate_blog_signup', 'signup_nonce_check' );
  • src/wp-includes/ms-functions.php

     
    403403 *
    404404 * @global wpdb $wpdb WordPress database abstraction object.
    405405 *
    406  * @param string $user_name The login name provided by the user.
     406 * @param string $user_login The login name provided by the user.
    407407 * @param string $user_email The email provided by the user.
    408408 * @return array Contains username, email, and error messages.
    409409 */
    410 function wpmu_validate_user_signup($user_name, $user_email) {
     410function wpmu_validate_user_signup( $user_login, $user_email ) {
    411411        global $wpdb;
    412412
    413413        $errors = new WP_Error();
     414        $orig_userlogin = $user_login;
     415        wp_validate_user_login( $user_login, $errors );
    414416
    415         $orig_username = $user_name;
    416         $user_name = preg_replace( '/\s+/', '', sanitize_user( $user_name, true ) );
    417 
    418         if ( $user_name != $orig_username || preg_match( '/[^a-z0-9]/', $user_name ) ) {
    419                 $errors->add( 'user_name', __( 'Usernames can only contain lowercase letters (a-z) and numbers.' ) );
    420                 $user_name = $orig_username;
    421         }
    422 
    423417        $user_email = sanitize_email( $user_email );
    424418
    425         if ( empty( $user_name ) )
    426                 $errors->add('user_name', __( 'Please enter a username.' ) );
    427 
    428         $illegal_names = get_site_option( 'illegal_names' );
    429         if ( ! is_array( $illegal_names ) ) {
    430                 $illegal_names = array(  'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator' );
    431                 add_site_option( 'illegal_names', $illegal_names );
    432         }
    433         if ( in_array( $user_name, $illegal_names ) ) {
    434                 $errors->add( 'user_name',  __( 'Sorry, that username is not allowed.' ) );
    435         }
    436 
    437         /** This filter is documented in wp-includes/user.php */
    438         $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
    439 
    440         if ( in_array( strtolower( $user_name ), array_map( 'strtolower', $illegal_logins ) ) ) {
    441                 $errors->add( 'user_name',  __( 'Sorry, that username is not allowed.' ) );
    442         }
    443 
    444419        if ( is_email_address_unsafe( $user_email ) )
    445420                $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.'));
    446421
    447         if ( strlen( $user_name ) < 4 )
    448                 $errors->add('user_name',  __( 'Username must be at least 4 characters.' ) );
    449 
    450         if ( strlen( $user_name ) > 60 ) {
    451                 $errors->add( 'user_name', __( 'Username may not be longer than 60 characters.' ) );
    452         }
    453 
    454         // all numeric?
    455         if ( preg_match( '/^[0-9]*$/', $user_name ) )
    456                 $errors->add('user_name', __('Sorry, usernames must have letters too!'));
    457 
    458422        if ( !is_email( $user_email ) )
    459423                $errors->add('user_email', __( 'Please enter a valid email address.' ) );
    460424
     
    466430                }
    467431        }
    468432
    469         // Check if the username has been used already.
    470         if ( username_exists($user_name) )
    471                 $errors->add( 'user_name', __( 'Sorry, that username already exists!' ) );
    472 
    473433        // Check if the email address has been used already.
    474434        if ( email_exists($user_email) )
    475435                $errors->add( 'user_email', __( 'Sorry, that email address is already used!' ) );
    476436
    477         // Has someone already signed up for this username?
    478         $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE user_login = %s", $user_name) );
    479         if ( $signup != null ) {
    480                 $registered_at =  mysql2date('U', $signup->registered);
    481                 $now = current_time( 'timestamp', true );
    482                 $diff = $now - $registered_at;
    483                 // If registered more than two days ago, cancel registration and let this signup go through.
    484                 if ( $diff > 2 * DAY_IN_SECONDS )
    485                         $wpdb->delete( $wpdb->signups, array( 'user_login' => $user_name ) );
    486                 else
    487                         $errors->add('user_name', __('That username is currently reserved but may be available in a couple of days.'));
    488         }
    489 
    490437        $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE user_email = %s", $user_email) );
    491438        if ( $signup != null ) {
    492439                $diff = current_time( 'timestamp', true ) - mysql2date('U', $signup->registered);
     
    497444                        $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.'));
    498445        }
    499446
    500         $result = array('user_name' => $user_name, 'orig_username' => $orig_username, 'user_email' => $user_email, 'errors' => $errors);
     447        $result = array( 'user_name' => $user_login, 'orig_username' => $orig_userlogin, 'user_email' => $user_email, 'errors' => $errors );
    501448
    502449        /**
    503450         * Filters the validated user registration details.
  • src/wp-includes/user.php

     
    22292229}
    22302230
    22312231/**
     2232 * Validate a provided user_login
     2233 *
     2234 * user_login requirements:
     2235 *     - minimum of 4 characters
     2236 *     - maximum of 60 characters
     2237 *     - only contains (case-insensitive) characters: a-z 0-9 _ . - @
     2238 *     - no whitespace
     2239 *     - not on blacklist of illegal names
     2240 *     - contains at least one letter
     2241 *     - must be unique
     2242 *     - not pending signup already
     2243 *
     2244 * @since TBD
     2245 *
     2246 * @param string $user_login The user_login value to be be validated.
     2247 *
     2248 * @return True|WP_Error True if the user login is valid, WP_Error otherwise.
     2249 */
     2250function wp_validate_user_login( $user_login = '', $errors = null ) {
     2251        global $wpdb;
     2252        $original_user_login = $user_login;
     2253
     2254        if ( ! is_wp_error( $errors ) ) {
     2255                $errors = new WP_Error();
     2256        }
     2257
     2258        // User login cannot be empty
     2259        if ( empty( $user_login ) ) {
     2260                $errors->add( 'user_name', __( 'Please enter a username.' ) );
     2261        }
     2262
     2263        // User login must be less than 60 characters
     2264        if ( strlen( $user_login ) > 60 ) {
     2265                $errors->add( 'user_name', __( 'Username may not be longer than 60 characters.' ) );
     2266        }
     2267
     2268        // Check if the login passes sanitize_user() which doesn't strip whitespace
     2269        $user_login = sanitize_user( $user_login, true );
     2270
     2271        // If the previous operation generated a different value, the username is invalid
     2272        if ( $user_login !== $original_user_login ) {
     2273                $errors->add( 'user_name', __( '<strong>ERROR</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.' ) );
     2274        }
     2275
     2276        if ( is_multisite() ) {
     2277                // Check the user_login against an array of illegal names
     2278                $illegal_logins = get_site_option( 'illegal_names' );
     2279                if ( false == is_array( $illegal_logins ) ) {
     2280                        $illegal_logins = array( 'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator' );
     2281                        add_site_option( 'illegal_names', $illegal_logins );
     2282                }
     2283                if ( in_array( $user_login, $illegal_logins ) ) {
     2284                        $errors->add( 'user_name',  __( 'Sorry, that username is not allowed.' ) );
     2285                }
     2286        }
     2287
     2288        /** This filter is documented in wp-includes/user.php */
     2289        $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
     2290
     2291        if ( in_array( strtolower( $user_login ), array_map( 'strtolower', $illegal_logins ) ) ) {
     2292                if ( is_multisite() ) {
     2293                        $errors->add( 'user_name',  __( 'Sorry, that username is not allowed.' ) );
     2294                } else {
     2295                        $errors->add( 'invalid_username',  __( 'Sorry, that username is not allowed.' ) );
     2296                }
     2297        }
     2298
     2299        if ( is_multisite() ) {
     2300                // User login must have at least one letter
     2301                if ( ! preg_match( '/[a-zA-Z]+/', $user_login ) ) {
     2302                        $errors->add( 'user_name', __( 'Sorry, usernames must have letters too!' ) );
     2303                }
     2304        }
     2305
     2306        // Check if the username has been used already.
     2307        if ( username_exists( $user_login ) ) {
     2308                $errors->add( 'user_name', __( 'Sorry, that username already exists!' ) );
     2309        }
     2310
     2311        if ( is_multisite() ) {
     2312                // Has someone already signed up for this username?
     2313                $signup = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->signups WHERE user_login = %s", $user_login ) );
     2314                if ( $signup != null ) {
     2315                        $registered_at =  mysql2date( 'U', $signup->registered );
     2316                        $now = current_time( 'timestamp', true );
     2317                        $diff = $now - $registered_at;
     2318                        // If registered more than two days ago, cancel registration and let this signup go through.
     2319                        if ( $diff > 2 * DAY_IN_SECONDS )
     2320                                $wpdb->delete( $wpdb->signups, array( 'user_login' => $user_login ) );
     2321                        else
     2322                                $errors->add( 'user_name', __( 'That username is currently reserved but may be available in a couple of days.' ) );
     2323                }
     2324        }
     2325
     2326        /**
     2327         * Filter whether the provided user_login is valid or not.
     2328         *
     2329         * @since 2.0.1
     2330         *
     2331         * @param bool   $valid      Whether given user_login is valid.
     2332         * @param string $user_login user_login to check.
     2333         */
     2334        $valid = apply_filters( 'validate_username', true, $user_login );
     2335        if ( ! $valid ) {
     2336                $errors->add( 'user_name', __( 'Sorry, that username is invalid.' ) );
     2337        }
     2338
     2339        /**
     2340         * Validate a user_login. A user_login can be invalidated by adding an error
     2341         * to the WP_Error.
     2342         *
     2343         * @since TBD
     2344         *
     2345         * @param  WP_Error $errors
     2346         * @param  string   $user_login The user_login to validate.
     2347         */
     2348        do_action( 'wp_validate_user_login', $errors, $user_login );
     2349
     2350        if ( $errors->errors ) {
     2351                return $errors;
     2352        } else {
     2353                return true;
     2354        }
     2355}
     2356
     2357/**
    22322358 * Handles registering a new user.
    22332359 *
    22342360 * @since 2.5.0
     
    22402366function register_new_user( $user_login, $user_email ) {
    22412367        $errors = new WP_Error();
    22422368
    2243         $sanitized_user_login = sanitize_user( $user_login );
    22442369        /**
    22452370         * Filters the email address of a user being registered.
    22462371         *
     
    22502375         */
    22512376        $user_email = apply_filters( 'user_registration_email', $user_email );
    22522377
    2253         // Check the username
    2254         if ( $sanitized_user_login == '' ) {
    2255                 $errors->add( 'empty_username', __( '<strong>ERROR</strong>: Please enter a username.' ) );
    2256         } elseif ( ! validate_username( $user_login ) ) {
    2257                 $errors->add( 'invalid_username', __( '<strong>ERROR</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.' ) );
    2258                 $sanitized_user_login = '';
    2259         } elseif ( username_exists( $sanitized_user_login ) ) {
    2260                 $errors->add( 'username_exists', __( '<strong>ERROR</strong>: This username is already registered. Please choose another one.' ) );
     2378        // Validate the username
     2379        wp_validate_user_login( $user_login, $errors );
    22612380
    2262         } else {
    2263                 /** This filter is documented in wp-includes/user.php */
    2264                 $illegal_user_logins = array_map( 'strtolower', (array) apply_filters( 'illegal_user_logins', array() ) );
    2265                 if ( in_array( strtolower( $sanitized_user_login ), $illegal_user_logins ) ) {
    2266                         $errors->add( 'invalid_username', __( '<strong>ERROR</strong>: Sorry, that username is not allowed.' ) );
    2267                 }
    2268         }
    2269 
    22702381        // Check the email address
    22712382        if ( $user_email == '' ) {
    22722383                $errors->add( 'empty_email', __( '<strong>ERROR</strong>: Please type your email address.' ) );
     
    22822393         *
    22832394         * @since 2.1.0
    22842395         *
    2285          * @param string   $sanitized_user_login The submitted username after being sanitized.
    2286          * @param string   $user_email           The submitted email.
    2287          * @param WP_Error $errors               Contains any errors with submitted username and email,
    2288          *                                       e.g., an empty field, an invalid username or email,
    2289          *                                       or an existing username or email.
     2396         * @param string   $user_login The submitted username after being sanitized.
     2397         * @param string   $user_email The submitted email.
     2398         * @param WP_Error $errors     Contains any errors with submitted username and email,
     2399         *                             e.g., an empty field, an invalid username or email,
     2400         *                             or an existing username or email.
    22902401         */
    2291         do_action( 'register_post', $sanitized_user_login, $user_email, $errors );
     2402        do_action( 'register_post', $user_login, $user_email, $errors );
    22922403
    22932404        /**
    22942405         * Filters the errors encountered when a new user is being registered.
     
    23012412         *
    23022413         * @since 2.1.0
    23032414         *
    2304          * @param WP_Error $errors               A WP_Error object containing any errors encountered
    2305          *                                       during registration.
    2306          * @param string   $sanitized_user_login User's username after it has been sanitized.
    2307          * @param string   $user_email           User's email.
     2415         * @param WP_Error $errors     A WP_Error object containing any errors encountered
     2416         *                             during registration.
     2417         * @param string   $user_login User's username.
     2418         * @param string   $user_email User's email.
    23082419         */
    2309         $errors = apply_filters( 'registration_errors', $errors, $sanitized_user_login, $user_email );
     2420        $errors = apply_filters( 'registration_errors', $errors, $user_login, $user_email );
    23102421
    23112422        if ( $errors->get_error_code() )
    23122423                return $errors;
    23132424
    23142425        $user_pass = wp_generate_password( 12, false );
    2315         $user_id = wp_create_user( $sanitized_user_login, $user_pass, $user_email );
     2426        $user_id = wp_create_user( $user_login, $user_pass, $user_email );
    23162427        if ( ! $user_id || is_wp_error( $user_id ) ) {
    23172428                $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' ) ) );
    23182429                return $errors;
  • src/wp-signup.php

     
    659659        $errors = $filtered_results['errors'];
    660660
    661661        if ( empty($blogname) )
    662                 $blogname = $user_name;
     662                $blogname = preg_replace( '|[ _.\-@]|i', '', strtolower($user_name) );
    663663        ?>
    664664        <form id="setupform" method="post" action="wp-signup.php">
    665665                <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                );