From a98d30864f930f94602d779a8ab90ca15685202a Mon Sep 17 00:00:00 2001 From: westi Date: Sat, 24 Jan 2009 22:38:19 +0000 Subject: [PATCH] Make authentication more pluggable than ever before. See #8938 props wnorris. git-svn-id: http://svn.automattic.com/wordpress/trunk@10437 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/pluggable.php | 29 ++++------- wp-includes/user.php | 100 ++++++++++++++++++++++++++++---------- 2 files changed, 82 insertions(+), 47 deletions(-) diff --git a/wp-includes/pluggable.php b/wp-includes/pluggable.php index edafc9dd4..ddb746ad0 100644 --- a/wp-includes/pluggable.php +++ b/wp-includes/pluggable.php @@ -422,32 +422,21 @@ if ( !function_exists('wp_authenticate') ) : */ function wp_authenticate($username, $password) { $username = sanitize_user($username); + $password = trim($password); - if ( '' == $username ) - return new WP_Error('empty_username', __('ERROR: The username field is empty.')); + $user = apply_filters('authenticate', null, $username, $password); - if ( '' == $password ) - return new WP_Error('empty_password', __('ERROR: The password field is empty.')); - - $user = get_userdatabylogin($username); - - if ( !$user || ($user->user_login != $username) ) { - do_action( 'wp_login_failed', $username ); - return new WP_Error('invalid_username', __('ERROR: Invalid username.')); + 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 = apply_filters('wp_authenticate_user', $user, $password); - if ( is_wp_error($user) ) { - do_action( 'wp_login_failed', $username ); - return $user; + if (is_wp_error($user)) { + do_action('wp_login_failed', $username); } - if ( !wp_check_password($password, $user->user_pass, $user->ID) ) { - do_action( 'wp_login_failed', $username ); - return new WP_Error('incorrect_password', __('ERROR: Incorrect password.')); - } - - return new WP_User($user->ID); + return $user; } endif; diff --git a/wp-includes/user.php b/wp-includes/user.php index cea1a03d2..d21d5f54e 100644 --- a/wp-includes/user.php +++ b/wp-includes/user.php @@ -32,27 +32,90 @@ function wp_signon( $credentials = '', $secure_cookie = '' ) { $credentials['remember'] = $_POST['rememberme']; } - if ( !empty($credentials['user_login']) ) - $credentials['user_login'] = sanitize_user($credentials['user_login']); - if ( !empty($credentials['user_password']) ) - $credentials['user_password'] = trim($credentials['user_password']); if ( !empty($credentials['remember']) ) $credentials['remember'] = true; else $credentials['remember'] = false; + // TODO do we deprecate the wp_authentication action? do_action_ref_array('wp_authenticate', array(&$credentials['user_login'], &$credentials['user_password'])); if ( '' === $secure_cookie ) $secure_cookie = is_ssl() ? true : false; - // If no credential info provided, check cookie. - if ( empty($credentials['user_login']) && empty($credentials['user_password']) ) { - $user = wp_validate_auth_cookie(); - if ( $user ) - return new WP_User($user); + global $auth_secure_cookie; // XXX ugly hack to pass this to wp_authenticate_cookie + $auth_secure_cookie = $secure_cookie; - if ( $secure_cookie ) + add_filter('authenticate', 'wp_authenticate_cookie', 30, 3); + + $user = wp_authenticate($credentials['user_login'], $credentials['user_password']); + + if ( is_wp_error($user) ) + return $user; + + wp_set_auth_cookie($user->ID, $credentials['remember'], $secure_cookie); + do_action('wp_login', $credentials['user_login']); + return $user; +} + + +/** + * Authenticate the user using the username and password. + */ +add_filter('authenticate', 'wp_authenticate_username_password', 20, 3); +function wp_authenticate_username_password($user, $username, $password) { + if ( is_a($user, 'WP_User') ) { return $user; } + + // XXX slight hack to handle initial load of wp-login.php + if ( (empty($username) && empty($password)) && $GLOBALS['pagenow'] == 'wp-login.php' ) { + return $user; + } + + if ( empty($username) || empty($password) ) { + $error = new WP_Error(); + + if ( empty($username) ) + $error->add('empty_username', __('ERROR: The username field is empty.')); + + if ( empty($password) ) + $error->add('empty_password', __('ERROR: The password field is empty.')); + + return $error; + } + + $userdata = get_userdatabylogin($username); + + if ( !$userdata || ($userdata->user_login != $username) ) { + return new WP_Error('invalid_username', __('ERROR: Invalid username.')); + } + + $user = apply_filters('wp_authenticate_user', $user, $password); + if ( is_wp_error($user) ) { + return $user; + } + + if ( !wp_check_password($password, $userdata->user_pass, $userdata->ID) ) { + return new WP_Error('incorrect_password', __('ERROR: Incorrect password.')); + } + + $user = new WP_User($userdata->ID); + return $user; +} + +/** + * Authenticate the user using the WordPress auth cookie. + */ +function wp_authenticate_cookie($user, $username, $password) { + if ( is_a($user, 'WP_User') ) { return $user; } + + if ( empty($username) && empty($password) ) { + $user_id = wp_validate_auth_cookie(); + if ( $user_id ) + return new WP_User($user_id); + + global $auth_secure_cookie; + + if ( $auth_secure_cookie ) $auth_cookie = SECURE_AUTH_COOKIE; else $auth_cookie = AUTH_COOKIE; @@ -61,25 +124,8 @@ function wp_signon( $credentials = '', $secure_cookie = '' ) { return new WP_Error('expired_session', __('Please log in again.')); // If the cookie is not set, be silent. - return new WP_Error(); } - if ( empty($credentials['user_login']) || empty($credentials['user_password']) ) { - $error = new WP_Error(); - - if ( empty($credentials['user_login']) ) - $error->add('empty_username', __('ERROR: The username field is empty.')); - if ( empty($credentials['user_password']) ) - $error->add('empty_password', __('ERROR: The password field is empty.')); - return $error; - } - - $user = wp_authenticate($credentials['user_login'], $credentials['user_password']); - if ( is_wp_error($user) ) - return $user; - - wp_set_auth_cookie($user->ID, $credentials['remember'], $secure_cookie); - do_action('wp_login', $credentials['user_login']); return $user; }