From 7ebe2c1e7a8ce5f321887fca1ea5b68d35c9a5de Mon Sep 17 00:00:00 2001 From: Dominik Schilling Date: Mon, 22 Feb 2016 23:15:27 +0000 Subject: [PATCH] Authentication: Allow users to log in using their email address. Introduces `wp_authenticate_email_password()` which is hooked into `authenticate` after `wp_authenticate_username_password()`. Props Denis-de-Bernardy, ericlewis, vhomenko, MikeHansenMe, swissspidy, ocean90. Fixes #9568. Built from https://develop.svn.wordpress.org/trunk@36617 git-svn-id: http://core.svn.wordpress.org/trunk@36584 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/default-filters.php | 1 + wp-includes/pluggable.php | 4 +- wp-includes/user.php | 72 +++++++++++++++++++++++++++++++++ wp-includes/version.php | 2 +- wp-login.php | 12 ++++-- 5 files changed, 85 insertions(+), 6 deletions(-) diff --git a/wp-includes/default-filters.php b/wp-includes/default-filters.php index 098c2514a7..76111ff428 100644 --- a/wp-includes/default-filters.php +++ b/wp-includes/default-filters.php @@ -342,6 +342,7 @@ add_filter( 'heartbeat_nopriv_send', 'wp_auth_check' ); // Default authentication filters add_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 ); +add_filter( 'authenticate', 'wp_authenticate_email_password', 20, 3 ); add_filter( 'authenticate', 'wp_authenticate_spam_check', 99 ); add_filter( 'determine_current_user', 'wp_validate_auth_cookie' ); add_filter( 'determine_current_user', 'wp_validate_logged_in_cookie', 20 ); diff --git a/wp-includes/pluggable.php b/wp-includes/pluggable.php index 8e24100a75..860d8027df 100644 --- a/wp-includes/pluggable.php +++ b/wp-includes/pluggable.php @@ -548,7 +548,7 @@ if ( !function_exists('wp_authenticate') ) : * * @since 2.5.0 * - * @param string $username User's username. + * @param string $username User's username or email address. * @param string $password User's password. * @return WP_User|WP_Error WP_User object if the credentials are valid, * otherwise WP_Error. @@ -575,7 +575,7 @@ function wp_authenticate($username, $password) { if ( $user == null ) { // TODO what should the error message be? (Or would these even happen?) // Only needed if all authentication handlers fail to return anything. - $user = new WP_Error('authentication_failed', __('ERROR: Invalid username or incorrect password.')); + $user = new WP_Error( 'authentication_failed', __( 'ERROR: Invalid username, email address or incorrect password.' ) ); } $ignore_codes = array('empty_username', 'empty_password'); diff --git a/wp-includes/user.php b/wp-includes/user.php index c1c63045e3..8b1b0321b4 100644 --- a/wp-includes/user.php +++ b/wp-includes/user.php @@ -173,6 +173,78 @@ function wp_authenticate_username_password($user, $username, $password) { return $user; } +/** + * Authenticate the user using the email and password. + * + * @since 4.5.0 + * + * @param WP_User|WP_Error|null $user WP_User or WP_Error object if a previous + * callback failed authentication. + * @param string $email Email address for authentication. + * @param string $password Password for authentication. + * @return WP_User|WP_Error WP_User on success, WP_Error on failure. + */ +function wp_authenticate_email_password( $user, $email, $password ) { + if ( $user instanceof WP_User ) { + return $user; + } + + if ( empty( $email ) || empty( $password ) ) { + if ( is_wp_error( $user ) ) { + return $user; + } + + $error = new WP_Error(); + + if ( empty( $email ) ) { + $error->add( 'empty_username', __( 'ERROR: The email field is empty.' ) ); // Uses 'empty_username' for back-compat with wp_signon() + } + + if ( empty( $password ) ) { + $error->add( 'empty_password', __( 'ERROR: The password field is empty.' ) ); + } + + return $error; + } + + if ( ! is_email( $email ) ) { + return $user; + } + + $user = get_user_by( 'email', $email ); + + if ( ! $user ) { + return new WP_Error( 'invalid_email', + __( 'ERROR: Invalid email address.' ) . + ' ' . + __( 'Lost your password?' ) . + '' + ); + } + + /** This filter is documented in wp-includes/user.php */ + $user = apply_filters( 'wp_authenticate_user', $user, $password ); + + if ( is_wp_error( $user ) ) { + return $user; + } + + if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) { + return new WP_Error( 'incorrect_password', + sprintf( + /* translators: %s: email address */ + __( 'ERROR: The password you entered for the email address %s is incorrect.' ), + '' . $email . '' + ) . + ' ' . + __( 'Lost your password?' ) . + '' + ); + } + + return $user; +} + /** * Authenticate the user using the WordPress auth cookie. * diff --git a/wp-includes/version.php b/wp-includes/version.php index e5212c652c..b0a5e13e2b 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -4,7 +4,7 @@ * * @global string $wp_version */ -$wp_version = '4.5-alpha-36616'; +$wp_version = '4.5-alpha-36617'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. diff --git a/wp-login.php b/wp-login.php index 28dbaaed4b..64852134da 100644 --- a/wp-login.php +++ b/wp-login.php @@ -529,7 +529,7 @@ case 'retrievepassword' :

-

ID) ) { $secure_cookie = true; force_ssl_admin(true); @@ -882,7 +888,7 @@ default:

-