Skip to content

Sign in with Google doesn't work with WordPress 2FA plugin #11032

Description

@tofumatt

Bug Description

When Sign in with Google and the WordPress 2FA plugin are both enabled, creating an account works fine.

But signing in with that account, afterward, reportedly does not work.

This is likely because the 2FA flow fails.

In the case of users whose account uses SiwG, we should likely disable 2FA for that SiwG sign-in flow, relying on the Google Account to use 2FA—this is usually how social logins work 🤔

Steps to reproduce

  1. Set up Site Kit and the Sign in with Google module
  2. Install the WordPress 2FA plugin
  3. Create a user account using Sign in with Google.
  4. Sign out and then try to sign in with that same account again, using Sign in with Google

Do not alter or remove anything below. The following sections will be managed by moderators only.

Acceptance criteria

  • When the WordPress 2FA plugin is active/detected, users with the existing WordPress accounts and enabled 2FA are prevented from signing in with Google if they don't have their accounts already connected to Google's.
    • An error is shown to the user stating that their account uses two-factor authentication and that they need to link their account to Google's before they can use Sign in with Google.
    • Users can connect their Google accounts in their profiles even if they use 2FA. Once accounts are connected, they can sign in with Google.
  • When a new user is registered using Sign in with Google directly, their new account is connected to Google's automatically as it works today.

Implementation Brief

  • In includes/Modules/Sign_In_With_Google/Authenticator.php
    • Add const ERROR_TWO_FACTOR_ENABLED = 'googlesitekit_auth_two_factor_enabled'; with @since.
    • Three new protected helpers (each with @since):
      • is_two_factor_plugin_active(): bool returns class_exists( 'Two_Factor_Core' ).
      • user_has_two_factor( int $user_id ): bool returns false when is_two_factor_plugin_active() is false, otherwise calls \Two_Factor_Core::is_user_using_two_factor( $user_id ) with // @phpstan-ignore class.notFound on the call line.
      • disable_two_factor_for_new_user( int $user_id ): void calls update_user_meta( $user_id, '_two_factor_enabled_providers', array() ) when is_two_factor_plugin_active() is true.
    • In the email-match branch of find_user(), return new WP_Error( self::ERROR_TWO_FACTOR_ENABLED ) ahead of the Hashed_User_ID::OPTION write when user_has_two_factor( $user->ID ) is true.
    • Update the find_user() docblock to @return WP_User|WP_Error|null and add a @since n.e.x.t note about the new WP_Error return when an email-matched user has two-factor enabled.
    • In create_user(), call disable_two_factor_for_new_user( $user_id ) between wp_insert_user() and wp_send_new_user_notifications().
    • In authenticate_user(), short-circuit immediately after find_user() with if ( is_wp_error( $user ) ) { return $this->get_error_redirect_url( $user->get_error_code() ); }.
  • In includes/Modules/Sign_In_With_Google.php
    • In handle_login_errors(), add case Authenticator::ERROR_TWO_FACTOR_ENABLED: $error->add( self::MODULE_SLUG, __( 'An existing account using two-factor authentication was detected with that email address. To connect an account using Sign in with Google, two-factor auth must be disabled for your user account.', 'google-site-kit' ) ); break;.

Test Coverage

  • In tests/phpunit/integration/Modules/Sign_In_With_Google/AuthenticatorTest.php, a test subclass overrides is_two_factor_plugin_active() and user_has_two_factor(). Five cases:
    • Plugin active, email-matched user with 2FA: authenticate_user() returns wp_login_url() with error=googlesitekit_auth_two_factor_enabled and Hashed_User_ID::OPTION is not written.
    • Plugin active, email-matched user without 2FA: Hashed_User_ID::OPTION is written and the user signs in.
    • Plugin inactive: the email-match branch runs even when the user already has _two_factor_enabled_providers meta set.
    • Plugin active, new user created: _two_factor_enabled_providers meta equals array() after authenticate_user() returns.
    • Plugin inactive, new user created: _two_factor_enabled_providers is not written.
  • In tests/phpunit/integration/Modules/Sign_In_With_GoogleTest.php:
    • $_GET['error'] = Authenticator::ERROR_TWO_FACTOR_ENABLED makes handle_login_errors() add a Sign_In_With_Google::MODULE_SLUG message containing "two-factor authentication".
    • An unrecognized $_GET['error'] value leaves the input WP_Error untouched.
  • No Storybook or VRT changes.

QA Brief

  • Set up Site Kit and connect the Sign in with Google module.
  • Install and activate the Two-Factor plugin.
  • On General Settings, select Anyone can register.

A new Sign in with Google account

  1. Sign out and click Sign in with Google with a Google Account that has no WordPress user.
  2. Confirm it creates a new account and signs in.
  3. Sign out and click Sign in with Google with the same account. Confirm it signs in again with no two-factor prompt.
  4. Open that account under Users and confirm its Two-Factor Options stay off.

Two-factor stays on for a regular login

  1. Turn on a Two-Factor Options provider for the new account.
  2. Sign out and log in with its password. Confirm the two-factor challenge still shows.
  3. Sign out and click Sign in with Google with the same account. Confirm it skips the challenge and signs in.

An existing account with two-factor enabled

  1. Create a new WordPress user (one that has never signed in with Google) whose email matches a Google Account, then turn on a Two-Factor Options provider for it.
  2. Sign out and click Sign in with Google with that account.
  3. Confirm the login page shows the red error: An existing account using two-factor authentication was detected with that email address. To connect an account using Sign in with Google, two-factor auth must be disabled for your user account.
  4. Confirm the user's Two-Factor Options stay on.
  5. Turn off the user's Two-Factor Options, then click Sign in with Google with the same account. Confirm it links and signs in.

A new account with the Two-Factor plugin inactive

  1. Deactivate the Two-Factor plugin.
  2. Sign out and click Sign in with Google with a Google Account that has no WordPress user.
  3. Confirm it creates a new account and signs in.

Changelog entry

Metadata

Metadata

Assignees

Labels

Module: Sign in with GoogleSign in with Google (SiwG) related issues.P1Medium priorityTeam SIssues for Squad 1

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions