/** * The function that actually handles the login! */ function handle_login() { $wpcom_nonce = sanitize_key($_GET['sso_nonce']); $wpcom_user_id = (int) $_GET['user_id']; Jetpack::load_xml_rpc_client(); $xml = new Jetpack_IXR_Client(array('user_id' => get_current_user_id())); $xml->query('jetpack.sso.validateResult', $wpcom_nonce, $wpcom_user_id); $user_data = $xml->isError() ? false : $xml->getResponse(); if (empty($user_data)) { add_filter('jetpack_sso_default_to_sso_login', '__return_false'); add_filter('login_message', array('Jetpack_SSO_Notices', 'error_invalid_response_data')); return; } $user_data = (object) $user_data; $user = null; /** * Fires before Jetpack's SSO modifies the log in form. * * @module sso * * @since 2.6.0 * * @param object $user_data WordPress.com User information. */ do_action('jetpack_sso_pre_handle_login', $user_data); if (Jetpack_SSO_Helpers::is_two_step_required() && 0 === (int) $user_data->two_step_enabled) { $this->user_data = $user_data; JetpackTracking::record_user_event('sso_login_failed', array('error_message' => 'error_msg_enable_two_step')); /** This filter is documented in core/src/wp-includes/pluggable.php */ do_action('wp_login_failed', $user_data->login); add_filter('login_message', array('Jetpack_SSO_Notices', 'error_msg_enable_two_step')); return; } $user_found_with = ''; if (empty($user) && isset($user_data->external_user_id)) { $user_found_with = 'external_user_id'; $user = get_user_by('id', intval($user_data->external_user_id)); if ($user) { update_user_meta($user->ID, 'wpcom_user_id', $user_data->ID); } } // If we don't have one by wpcom_user_id, try by the email? if (empty($user) && Jetpack_SSO_Helpers::match_by_email()) { $user_found_with = 'match_by_email'; $user = get_user_by('email', $user_data->email); if ($user) { update_user_meta($user->ID, 'wpcom_user_id', $user_data->ID); } } // If we've still got nothing, create the user. if (empty($user) && (get_option('users_can_register') || Jetpack_SSO_Helpers::new_user_override())) { /** * If not matching by email we still need to verify the email does not exist * or this blows up * * If match_by_email is true, we know the email doesn't exist, as it would have * been found in the first pass. If get_user_by( 'email' ) doesn't find the * user, then we know that email is unused, so it's safe to add. */ if (Jetpack_SSO_Helpers::match_by_email() || !get_user_by('email', $user_data->email)) { $user = Jetpack_SSO_Helpers::generate_user($user_data); if (!$user) { JetpackTracking::record_user_event('sso_login_failed', array('error_message' => 'could_not_create_username')); add_filter('login_message', array('Jetpack_SSO_Notices', 'error_unable_to_create_user')); return; } $user_found_with = Jetpack_SSO_Helpers::new_user_override() ? 'user_created_new_user_override' : 'user_created_users_can_register'; } else { JetpackTracking::record_user_event('sso_login_failed', array('error_message' => 'error_msg_email_already_exists')); $this->user_data = $user_data; add_action('login_message', array('Jetpack_SSO_Notices', 'error_msg_email_already_exists')); return; } } /** * Fires after we got login information from WordPress.com. * * @module sso * * @since 2.6.0 * * @param array $user Local User information. * @param object $user_data WordPress.com User Login information. */ do_action('jetpack_sso_handle_login', $user, $user_data); if ($user) { // Cache the user's details, so we can present it back to them on their user screen update_user_meta($user->ID, 'wpcom_user_data', $user_data); add_filter('auth_cookie_expiration', array('Jetpack_SSO_Helpers', 'extend_auth_cookie_expiration_for_sso')); wp_set_auth_cookie($user->ID, true); remove_filter('auth_cookie_expiration', array('Jetpack_SSO_Helpers', 'extend_auth_cookie_expiration_for_sso')); /** This filter is documented in core/src/wp-includes/user.php */ do_action('wp_login', $user->user_login, $user); wp_set_current_user($user->ID); $_request_redirect_to = isset($_REQUEST['redirect_to']) ? esc_url_raw($_REQUEST['redirect_to']) : ''; $redirect_to = user_can($user, 'edit_posts') ? admin_url() : self::profile_page_url(); // If we have a saved redirect to request in a cookie if (!empty($_COOKIE['jetpack_sso_redirect_to'])) { // Set that as the requested redirect to $redirect_to = $_request_redirect_to = esc_url_raw($_COOKIE['jetpack_sso_redirect_to']); // And then purge it setcookie('jetpack_sso_redirect_to', ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN); } $is_user_connected = Jetpack::is_user_connected($user->ID); JetpackTracking::record_user_event('sso_user_logged_in', array('user_found_with' => $user_found_with, 'user_connected' => (bool) $is_user_connected, 'user_role' => Jetpack::translate_current_user_to_role())); if (!$is_user_connected) { $calypso_env = !empty($_GET['calypso_env']) ? sanitize_key($_GET['calypso_env']) : ''; wp_safe_redirect(add_query_arg(array('redirect_to' => $redirect_to, 'request_redirect_to' => $_request_redirect_to, 'calypso_env' => $calypso_env, 'jetpack-sso-auth-redirect' => '1'), admin_url())); exit; } wp_safe_redirect(apply_filters('login_redirect', $redirect_to, $_request_redirect_to, $user)); exit; } add_filter('jetpack_sso_default_to_sso_login', '__return_false'); JetpackTracking::record_user_event('sso_login_failed', array('error_message' => 'cant_find_user')); $this->user_data = $user_data; /** This filter is documented in core/src/wp-includes/pluggable.php */ do_action('wp_login_failed', $user_data->login); add_filter('login_message', array('Jetpack_SSO_Notices', 'cant_find_user')); }
function test_generate_user_returns_false_when_no_more_tries_and_username_exists() { add_filter('jetpack_sso_allowed_username_generate_retries', '__return_zero'); $this->factory->user->create(array('user_login' => $this->user_data->login)); $this->assertFalse(Jetpack_SSO_Helpers::generate_user($this->user_data)); }