WordPress.org

Make WordPress Core

Ticket #31039: 31039.3.patch

File 31039.3.patch, 10.9 KB (added by dimadin, 5 years ago)
  • wp-includes/user.php

     
    22342234}
    22352235
    22362236/**
     2237 * Handles sending password retrieval email to user.
     2238 *
     2239 * @since 2.5
     2240 * @since 4.3.0 Moved out of wp-login.php and introduced parameter.
     2241 *
     2242 * @global wpdb         $wpdb      WordPress database abstraction object.
     2243 * @global PasswordHash $wp_hasher Portable PHP password hashing framework.
     2244 *
     2245 * @param string $user_login Username or email of the user.
     2246 * @return bool|WP_Error True: when finish. WP_Error on error.
     2247 */
     2248function retrieve_password( $user_login ) {
     2249        global $wpdb, $wp_hasher;
     2250
     2251        $errors = new WP_Error();
     2252
     2253        if ( empty( $user_login ) ) {
     2254                $errors->add('empty_username', __( '<strong>ERROR</strong>: Enter a username or e-mail address.' ) );
     2255        } elseif ( strpos( $user_login, '@' ) ) {
     2256                $user_data = get_user_by( 'email', trim( $user_login ) );
     2257                if ( empty( $user_data ) ) {
     2258                        $errors->add( 'invalid_email', __( '<strong>ERROR</strong>: There is no user registered with that email address.' ) );
     2259                }
     2260        } else {
     2261                $login = trim( $user_login );
     2262                $user_data = get_user_by( 'login', $login );
     2263        }
     2264
     2265        /**
     2266         * Fires before errors are returned from a password reset request.
     2267         *
     2268         * @since 2.1.0
     2269         */
     2270        do_action( 'lostpassword_post' );
     2271
     2272        if ( $errors->get_error_code() ) {
     2273                return $errors;
     2274        }
     2275
     2276        if ( !$user_data ) {
     2277                $errors->add('invalidcombo', __('<strong>ERROR</strong>: Invalid username or e-mail.'));
     2278                return $errors;
     2279        }
     2280
     2281        // Redefining user_login ensures we return the right case in the email.
     2282        $user_login = $user_data->user_login;
     2283        $user_email = $user_data->user_email;
     2284
     2285        /**
     2286         * Fires before a new password is retrieved.
     2287         *
     2288         * @since 1.5.0
     2289         * @deprecated 1.5.1 Misspelled. Use 'retrieve_password' hook instead.
     2290         *
     2291         * @param string $user_login The user login name.
     2292         */
     2293        do_action( 'retreive_password', $user_login );
     2294
     2295        /**
     2296         * Fires before a new password is retrieved.
     2297         *
     2298         * @since 1.5.1
     2299         *
     2300         * @param string $user_login The user login name.
     2301         */
     2302        do_action( 'retrieve_password', $user_login );
     2303
     2304        /**
     2305         * Filter whether to allow a password to be reset.
     2306         *
     2307         * @since 2.7.0
     2308         *
     2309         * @param bool true           Whether to allow the password to be reset. Default true.
     2310         * @param int  $user_data->ID The ID of the user attempting to reset a password.
     2311         */
     2312        $allow = apply_filters( 'allow_password_reset', true, $user_data->ID );
     2313
     2314        if ( ! $allow ) {
     2315                return new WP_Error( 'no_password_reset', __( 'Password reset is not allowed for this user' ) );
     2316        } elseif ( is_wp_error( $allow ) ) {
     2317                return $allow;
     2318        }
     2319
     2320        // Generate something random for a password reset key.
     2321        $key = wp_generate_password( 20, false );
     2322
     2323        /**
     2324         * Fires when a password reset key is generated.
     2325         *
     2326         * @since 2.5.0
     2327         *
     2328         * @param string $user_login The username for the user.
     2329         * @param string $key        The generated password reset key.
     2330         */
     2331        do_action( 'retrieve_password_key', $user_login, $key );
     2332
     2333        // Now insert the key, hashed, into the DB.
     2334        if ( empty( $wp_hasher ) ) {
     2335                require_once ABSPATH . WPINC . '/class-phpass.php';
     2336                $wp_hasher = new PasswordHash( 8, true );
     2337        }
     2338        $hashed = $wp_hasher->HashPassword( $key );
     2339        $wpdb->update( $wpdb->users, array( 'user_activation_key' => $hashed ), array( 'user_login' => $user_login ) );
     2340
     2341        $message = __( 'Someone requested that the password be reset for the following account:' ) . "\r\n\r\n";
     2342        $message .= network_home_url( '/' ) . "\r\n\r\n";
     2343        $message .= sprintf( __( 'Username: %s' ), $user_login ) . "\r\n\r\n";
     2344        $message .= __( 'If this was a mistake, just ignore this email and nothing will happen.' ) . "\r\n\r\n";
     2345        $message .= __( 'To reset your password, visit the following address:' ) . "\r\n\r\n";
     2346        $message .= '<' . network_site_url ("wp-login.php?action=rp&key=$key&login=" . rawurlencode( $user_login ), 'login' ) . ">\r\n";
     2347
     2348        if ( is_multisite() ) {
     2349                $blogname = $GLOBALS['current_site']->site_name;
     2350        } else {
     2351                /*
     2352                 * The blogname option is escaped with esc_html on the way into the database
     2353                 * in sanitize_option we want to reverse this for the plain text arena of emails.
     2354                 */
     2355                $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
     2356        }
     2357
     2358        $title = sprintf( __( '[%s] Password Reset' ), $blogname );
     2359
     2360        /**
     2361         * Filter the subject of the password reset email.
     2362         *
     2363         * @since 2.8.0
     2364         *
     2365         * @param string $title Default email title.
     2366         */
     2367        $title = apply_filters( 'retrieve_password_title', $title );
     2368
     2369        /**
     2370         * Filter the message body of the password reset mail.
     2371         *
     2372         * @since 2.8.0
     2373         * @since 4.1.0 Added `$user_login` and `$user_data` parameters.
     2374         *
     2375         * @param string  $message    Default mail message.
     2376         * @param string  $key        The activation key.
     2377         * @param string  $user_login The username for the user.
     2378         * @param WP_User $user_data  WP_User object.
     2379         */
     2380        $message = apply_filters( 'retrieve_password_message', $message, $key, $user_login, $user_data );
     2381
     2382        if ( $message && !wp_mail( $user_email, wp_specialchars_decode( $title ), $message ) ) {
     2383                wp_die( __( 'The e-mail could not be sent.' ) . "<br />\n" . __( 'Possible reason: your host may have disabled the mail() function.' ) );
     2384        }
     2385
     2386        return true;
     2387}
     2388
     2389/**
    22372390 * Retrieves a user row based on password reset key and login
    22382391 *
    22392392 * A key is considered 'expired' if it exactly matches the value of the
  • wp-login.php

     
    261261        <?php
    262262}
    263263
    264 /**
    265  * Handles sending password retrieval email to user.
    266  *
    267  * @global wpdb         $wpdb      WordPress database abstraction object.
    268  * @global PasswordHash $wp_hasher Portable PHP password hashing framework.
    269  *
    270  * @return bool|WP_Error True: when finish. WP_Error on error
    271  */
    272 function retrieve_password() {
    273         global $wpdb, $wp_hasher;
    274 
    275         $errors = new WP_Error();
    276 
    277         if ( empty( $_POST['user_login'] ) ) {
    278                 $errors->add('empty_username', __('<strong>ERROR</strong>: Enter a username or e-mail address.'));
    279         } elseif ( strpos( $_POST['user_login'], '@' ) ) {
    280                 $user_data = get_user_by( 'email', trim( $_POST['user_login'] ) );
    281                 if ( empty( $user_data ) )
    282                         $errors->add('invalid_email', __('<strong>ERROR</strong>: There is no user registered with that email address.'));
    283         } else {
    284                 $login = trim($_POST['user_login']);
    285                 $user_data = get_user_by('login', $login);
    286         }
    287 
    288         /**
    289          * Fires before errors are returned from a password reset request.
    290          *
    291          * @since 2.1.0
    292          */
    293         do_action( 'lostpassword_post' );
    294 
    295         if ( $errors->get_error_code() )
    296                 return $errors;
    297 
    298         if ( !$user_data ) {
    299                 $errors->add('invalidcombo', __('<strong>ERROR</strong>: Invalid username or e-mail.'));
    300                 return $errors;
    301         }
    302 
    303         // Redefining user_login ensures we return the right case in the email.
    304         $user_login = $user_data->user_login;
    305         $user_email = $user_data->user_email;
    306 
    307         /**
    308          * Fires before a new password is retrieved.
    309          *
    310          * @since 1.5.0
    311          * @deprecated 1.5.1 Misspelled. Use 'retrieve_password' hook instead.
    312          *
    313          * @param string $user_login The user login name.
    314          */
    315         do_action( 'retreive_password', $user_login );
    316 
    317         /**
    318          * Fires before a new password is retrieved.
    319          *
    320          * @since 1.5.1
    321          *
    322          * @param string $user_login The user login name.
    323          */
    324         do_action( 'retrieve_password', $user_login );
    325 
    326         /**
    327          * Filter whether to allow a password to be reset.
    328          *
    329          * @since 2.7.0
    330          *
    331          * @param bool true           Whether to allow the password to be reset. Default true.
    332          * @param int  $user_data->ID The ID of the user attempting to reset a password.
    333          */
    334         $allow = apply_filters( 'allow_password_reset', true, $user_data->ID );
    335 
    336         if ( ! $allow ) {
    337                 return new WP_Error( 'no_password_reset', __('Password reset is not allowed for this user') );
    338         } elseif ( is_wp_error( $allow ) ) {
    339                 return $allow;
    340         }
    341 
    342         // Generate something random for a password reset key.
    343         $key = wp_generate_password( 20, false );
    344 
    345         /**
    346          * Fires when a password reset key is generated.
    347          *
    348          * @since 2.5.0
    349          *
    350          * @param string $user_login The username for the user.
    351          * @param string $key        The generated password reset key.
    352          */
    353         do_action( 'retrieve_password_key', $user_login, $key );
    354 
    355         // Now insert the key, hashed, into the DB.
    356         if ( empty( $wp_hasher ) ) {
    357                 require_once ABSPATH . WPINC . '/class-phpass.php';
    358                 $wp_hasher = new PasswordHash( 8, true );
    359         }
    360         $hashed = $wp_hasher->HashPassword( $key );
    361         $wpdb->update( $wpdb->users, array( 'user_activation_key' => $hashed ), array( 'user_login' => $user_login ) );
    362 
    363         $message = __('Someone requested that the password be reset for the following account:') . "\r\n\r\n";
    364         $message .= network_home_url( '/' ) . "\r\n\r\n";
    365         $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
    366         $message .= __('If this was a mistake, just ignore this email and nothing will happen.') . "\r\n\r\n";
    367         $message .= __('To reset your password, visit the following address:') . "\r\n\r\n";
    368         $message .= '<' . network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . ">\r\n";
    369 
    370         if ( is_multisite() )
    371                 $blogname = $GLOBALS['current_site']->site_name;
    372         else
    373                 /*
    374                  * The blogname option is escaped with esc_html on the way into the database
    375                  * in sanitize_option we want to reverse this for the plain text arena of emails.
    376                  */
    377                 $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
    378 
    379         $title = sprintf( __('[%s] Password Reset'), $blogname );
    380 
    381         /**
    382          * Filter the subject of the password reset email.
    383          *
    384          * @since 2.8.0
    385          *
    386          * @param string $title Default email title.
    387          */
    388         $title = apply_filters( 'retrieve_password_title', $title );
    389 
    390         /**
    391          * Filter the message body of the password reset mail.
    392          *
    393          * @since 2.8.0
    394          * @since 4.1.0 Added `$user_login` and `$user_data` parameters.
    395          *
    396          * @param string  $message    Default mail message.
    397          * @param string  $key        The activation key.
    398          * @param string  $user_login The username for the user.
    399          * @param WP_User $user_data  WP_User object.
    400          */
    401         $message = apply_filters( 'retrieve_password_message', $message, $key, $user_login, $user_data );
    402 
    403         if ( $message && !wp_mail( $user_email, wp_specialchars_decode( $title ), $message ) )
    404                 wp_die( __('The e-mail could not be sent.') . "<br />\n" . __('Possible reason: your host may have disabled the mail() function.') );
    405 
    406         return true;
    407 }
    408 
    409264//
    410265// Main
    411266//
     
    512367case 'lostpassword' :
    513368case 'retrievepassword' :
    514369
    515         if ( $http_post ) {
    516                 $errors = retrieve_password();
     370        if ( $http_post && isset( $_POST['user_login'] ) ) {
     371                $errors = retrieve_password( $_POST['user_login'] );
    517372                if ( !is_wp_error($errors) ) {
    518373                        $redirect_to = !empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : 'wp-login.php?checkemail=confirm';
    519374                        wp_safe_redirect( $redirect_to );