Skip to content

Commit a374357

Browse files
committed
Address feedback from code review.
1 parent d864cc2 commit a374357

8 files changed

Lines changed: 57 additions & 38 deletions

File tree

includes/Modules/Sign_In_With_Google.php

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ public function __construct(
146146
*
147147
* @since 1.137.0
148148
* @since 1.141.0 Add functionality to allow users to disconnect their own account and admins to disconnect any user.
149-
* @since n.e.x.t Allow signed-in users to connect their existing WordPress account from the profile page.
149+
* @since n.e.x.t Allow signed-in users to connect their existing WordPress account from their own profile page.
150150
*/
151151
public function register() {
152152
$this->register_inline_data();
@@ -174,13 +174,21 @@ function () {
174174

175175
add_action( 'admin_action_' . self::ACTION_DISCONNECT, array( $this, 'handle_disconnect_user' ) );
176176

177-
// Render the Sign in with Google profile section. The user's own profile
178-
// shows connect or disconnect, other editable profiles show disconnect only.
177+
// Render the Sign in with Google profile section.
178+
// If this profile belongs to the current user (eg. they're editing
179+
// their own profile): show the "connect a Google account" if
180+
// they don't have a Google Account associated with their profile,
181+
// or the "Disconnect your Google account" option if they do have
182+
// a Google Account associated with their profile
183+
//
184+
// If this profile belongs to another user (eg. we're an admin editing
185+
// another user's profile), only the "Disconnect Google Account"
186+
// option is shown.
179187
add_action( 'show_user_profile', $this->get_method_proxy( 'render_sign_in_with_google_profile' ) );
180188
add_action( 'edit_user_profile', $this->get_method_proxy( 'render_sign_in_with_google_profile' ) );
181189

182190
// Output the Sign in with Google init script so the placeholder above
183-
// becomes a real button on the user's own unlinked profile.
191+
// becomes a real button on the user's own, unlinked profile.
184192
add_action( 'admin_footer', $this->get_method_proxy( 'maybe_render_profile_signinwithgoogle' ) );
185193

186194
// Surface the already-connected error from the profile-page connect flow.
@@ -235,7 +243,14 @@ function ( $paths ) {
235243
}
236244

237245
/**
238-
* Resolves the authenticator class to instantiate for an auth callback.
246+
* Get the authenticator class to use for the integration specified.
247+
*
248+
* Returns the name of the class to load for this Sign in with Google
249+
* authentication flow (eg. for WooCommerce, connecting an existing
250+
* user, etc.)
251+
*
252+
* Returns the base authenticator class's class name if no integration
253+
* matches the one supplied.
239254
*
240255
* @since n.e.x.t
241256
*
@@ -664,7 +679,7 @@ public function get_authenticated_users_count() {
664679
*
665680
* @since n.e.x.t
666681
*
667-
* @param int $user_id User ID to scope the accessor to.
682+
* @param int $user_id User ID to use to build the hashed ID.
668683
* @return Hashed_User_ID
669684
*/
670685
private function get_hashed_user_id( $user_id ) {
@@ -784,16 +799,16 @@ private function build_registrable_tag(): ?Web_Tag {
784799

785800
/**
786801
* Outputs the Sign in with Google init script that turns the placeholder
787-
* from `render_sign_in_with_google_profile()` into a real button.
802+
* `<div>` from `render_sign_in_with_google_profile()` into a real button.
788803
*
789804
* Hooks `admin_footer` so `did_action( 'show_user_profile' )` reliably
790805
* reports whether the section actually rendered.
791806
*
792807
* @since n.e.x.t
793808
*/
794809
private function maybe_render_profile_signinwithgoogle() {
795-
// `show_user_profile` only fires on the user's own profile, so this runs
796-
// only there. The connect button never renders for other users.
810+
// `show_user_profile` only fires on the user's own profile.
811+
// The connect button should never render for other users.
797812
if ( ! did_action( 'show_user_profile' ) ) {
798813
return;
799814
}
@@ -844,7 +859,7 @@ private function render_profile_admin_notices() {
844859

845860
printf(
846861
'<div class="notice notice-error is-dismissible"><p>%s</p></div>',
847-
esc_html__( 'A profile is already connected to this Google account.', 'google-site-kit' )
862+
esc_html__( 'Another user on this site already connected this Google account to their profile.', 'google-site-kit' )
848863
);
849864
}
850865

@@ -965,7 +980,7 @@ public function handle_disconnect_user() {
965980
*
966981
* @since 1.141.0
967982
* @since n.e.x.t Renamed from `render_disconnect_profile` and added the
968-
* connect-existing-profile branch.
983+
* the ability to connect an existing profile.
969984
*
970985
* @param WP_User $user WordPress user object.
971986
*/
@@ -979,8 +994,9 @@ private function render_sign_in_with_google_profile( WP_User $user ) {
979994
$is_own_profile = get_current_user_id() === $user->ID;
980995
$is_unlinked = empty( $current_user_google_id );
981996

982-
// Skip when there's no linked account and the connect button can't show
983-
// anyway (other user's profile, or module not connected).
997+
// Skip when there's no linked account and the connect button shouldn't
998+
// appear (eg. when on another user's profile or Sign in with Google is
999+
// not connected).
9841000
if ( $is_unlinked && ( ! $is_own_profile || ! $this->is_connected() ) ) {
9851001
return;
9861002
}

includes/Modules/Sign_In_With_Google/Authenticator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class Authenticator implements Authenticator_Interface {
4848
*
4949
* @since n.e.x.t
5050
*/
51-
const CONNECT_NONCE_ACTION = 'googlesitekit_connect_existing_profile';
51+
const CONNECT_EXISTING_PROFILE_NONCE_ACTION = 'googlesitekit_connect_existing_profile';
5252

5353
/**
5454
* User options instance.

includes/Modules/Sign_In_With_Google/Profile_Authenticator.php

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class Profile_Authenticator extends Authenticator {
4949
* of the Google account's email address.
5050
* - A new user is never created. Open registration is irrelevant.
5151
* - If the Google account is already linked to another WordPress user,
52-
* the flow errors out without mutating any user meta.
52+
* an error is triggered.
5353
*
5454
* @since n.e.x.t
5555
*
@@ -65,7 +65,7 @@ public function authenticate_user( Input $input ): string {
6565
// Tie the link request to the current WordPress session so a
6666
// cross-site request can't piggyback on the user's auth cookie.
6767
$nonce = $input->filter( INPUT_POST, 'connect_nonce' );
68-
if ( ! wp_verify_nonce( $nonce, self::CONNECT_NONCE_ACTION ) ) {
68+
if ( ! wp_verify_nonce( $nonce, self::CONNECT_EXISTING_PROFILE_NONCE_ACTION ) ) {
6969
return $this->get_error_redirect_url( self::ERROR_INVALID_REQUEST );
7070
}
7171

@@ -78,9 +78,12 @@ public function authenticate_user( Input $input ): string {
7878

7979
$g_user_hid = $this->get_hashed_google_user_id( $payload );
8080

81-
// Block the link if another WordPress user already has this Google
82-
// account stored against their profile.
83-
$existing_users = get_users(
81+
// Check to see if the Google user ID for the Google Account we signed in
82+
// with is already in use (eg. registered to another user on the site).
83+
//
84+
// If this is the case, we'll trigger an error instance of associating
85+
// this Google Account with the current user.
86+
$existing_user = get_users(
8487
array(
8588
// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
8689
'meta_key' => $this->user_options->get_meta_key( Hashed_User_ID::OPTION ),
@@ -92,7 +95,7 @@ public function authenticate_user( Input $input ): string {
9295
)
9396
);
9497

95-
if ( ! empty( $existing_users ) ) {
98+
if ( ! empty( $existing_user ) ) {
9699
return $this->get_error_redirect_url( self::ERROR_ACCOUNT_ALREADY_CONNECTED );
97100
}
98101

@@ -121,9 +124,9 @@ protected function get_error_redirect_url( $code ): string {
121124
$user_id = get_current_user_id();
122125
$target = $user_id ? get_edit_user_link( $user_id ) : admin_url( 'profile.php' );
123126

124-
// A Site Kit-specific query arg avoids the empty error notice WP core
125-
// emits on `wp-admin/profile.php` and `wp-admin/user-edit.php` for any
126-
// unrecognized `?error=`.
127+
// Do not use `error=` as a query arg here, because
128+
// `wp-admin/profile.php` and `wp-admin/user-edit.php` will
129+
// show an error for any unrecognized `?error=` value.
127130
return add_query_arg( self::ERROR_QUERY_ARG, $code, $target );
128131
}
129132
}

includes/Modules/Sign_In_With_Google/Web_Tag.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ protected function render() {
191191
<?php if ( ! is_preview() ) : // phpcs:ignore Generic.WhiteSpace.ScopeIndent.Incorrect ?>
192192
<?php if ( $this->is_connect_existing_profile ) : // phpcs:ignore Generic.WhiteSpace.ScopeIndent.Incorrect ?>
193193
response.integration = 'connect_existing_profile';
194-
response.connect_nonce = <?php echo wp_json_encode( wp_create_nonce( Authenticator::CONNECT_NONCE_ACTION ) ); ?>;
194+
response.connect_nonce = <?php echo wp_json_encode( wp_create_nonce( Authenticator::CONNECT_EXISTING_PROFILE_NONCE_ACTION ) ); ?>;
195195
<?php elseif ( $is_woocommerce && ! $this->is_wp_login ) : // phpcs:ignore Generic.WhiteSpace.ScopeIndent.Incorrect ?>
196196
response.integration = 'woocommerce';
197197
<?php endif; // phpcs:ignore Generic.WhiteSpace.ScopeIndent.Incorrect ?>

tests/phpunit/integration/Core/Util/Current_ScreenTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public function test_returns_wp_screen_for_profile_screen() {
2525
$screen = Current_Screen::get();
2626

2727
$this->assertInstanceOf( WP_Screen::class, $screen, 'Should return a WP_Screen instance when the profile screen is active.' );
28-
$this->assertSame( 'profile', $screen->id, 'Returned screen ID should match the active profile screen.' );
28+
$this->assertSame( 'profile', $screen->id, "Returned screen ID should match the current user's profile screen." );
2929
}
3030

3131
public function test_returns_wp_screen_for_user_edit_screen() {
@@ -40,6 +40,6 @@ public function test_returns_wp_screen_for_user_edit_screen() {
4040
public function test_returns_null_when_no_current_screen_is_set() {
4141
unset( $GLOBALS['current_screen'] );
4242

43-
$this->assertNull( Current_Screen::get(), 'Should return null when no current screen has been set.' );
43+
$this->assertNull( Current_Screen::get(), 'Should return null (eg. should not throw an error) when no current screen has been set.' );
4444
}
4545
}

tests/phpunit/integration/Modules/Sign_In_With_Google/ProfileAuthenticatorTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function tear_down() {
5050

5151
private function do_authenticate_user( $profile_reader_data = array(), $with_valid_nonce = true ) {
5252
if ( $with_valid_nonce ) {
53-
$_POST['connect_nonce'] = wp_create_nonce( Authenticator::CONNECT_NONCE_ACTION );
53+
$_POST['connect_nonce'] = wp_create_nonce( Authenticator::CONNECT_EXISTING_PROFILE_NONCE_ACTION );
5454
}
5555

5656
$user_options = new User_Options( new Context( GOOGLESITEKIT_PLUGIN_MAIN_FILE ) );
@@ -127,7 +127,7 @@ public function test_returns_error_redirect_when_google_account_taken_by_other_u
127127
$this->assertEquals( $expected, $actual, 'Should redirect with already-connected error when another user owns the Google account.' );
128128
$this->assertEmpty(
129129
get_user_option( Hashed_User_ID::OPTION, $current_user_id ),
130-
'Current user should not gain a Google link when another user owns the Google account.'
130+
'Current user should not be associated with a Google account already linked to another WordPress user on the site.'
131131
);
132132
}
133133

tests/phpunit/integration/Modules/Sign_In_With_Google/Web_TagTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ public function test_render_tag__emits_connect_markers_only_when_flag_on() {
243243
$output = $this->capture_render_tag_output();
244244
$this->assertStringContainsString( "response.integration='connect_existing_profile'", $output, 'Rendered script should set the connect_existing_profile integration when the flag is on.' );
245245
$this->assertStringContainsString( 'response.connect_nonce=', $output, 'Rendered script should include the connect nonce assignment when the flag is on.' );
246-
$this->assertStringContainsString( wp_create_nonce( Authenticator::CONNECT_NONCE_ACTION ), $output, 'Rendered nonce should match wp_create_nonce for CONNECT_NONCE_ACTION.' );
246+
$this->assertStringContainsString( wp_create_nonce( Authenticator::CONNECT_EXISTING_PROFILE_NONCE_ACTION ), $output, 'Rendered nonce should be a valid wp_create_nonce.' );
247247

248248
// Toggling the flag off on the same instance guards against a vacuous pass if the marker
249249
// strings ever change. The positive phase above fails first when that happens, signalling
@@ -265,7 +265,7 @@ public function test_render_tag__forces_button_render_loop_on_connect_flow_even_
265265
// Logged-in users normally skip the button render loop. The connect flow flips that gate
266266
// so the placeholder div on the profile page can still be wired up.
267267
$this->assertStringContainsString( 'google.accounts.id.renderButton', $output, 'Connect flow should force the button render loop even when the user is logged in.' );
268-
$this->assertStringContainsString( 'googlesitekit-sign-in-with-google__frontend-output-button', $output, 'Render loop should target the SiwG placeholder class.' );
268+
$this->assertStringContainsString( 'googlesitekit-sign-in-with-google__frontend-output-button', $output, 'Render loop should target the Sign in with Google placeholder class.' );
269269
}
270270

271271
private function capture_render_tag_output() {

tests/phpunit/integration/Modules/Sign_In_With_GoogleTest.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ public function test_render_sign_in_with_google_profile__connect_branch_on_own_p
406406
$output = $this->capture_action( 'show_user_profile', wp_get_current_user() );
407407
$this->assertStringContainsString( 'Connect your account to sign in with Google.', $output, 'Connect copy should render on own profile when no Google user id stored.' );
408408
$this->assertStringContainsString( 'id="googlesitekit-sign-in-with-google-profile-settings"', $output, 'Connect branch should reuse the profile-settings id.' );
409-
$this->assertStringContainsString( 'googlesitekit-sign-in-with-google__frontend-output-button', $output, 'Connect branch should render the SiwG button placeholder.' );
409+
$this->assertStringContainsString( 'googlesitekit-sign-in-with-google__frontend-output-button', $output, 'Connect branch should render the Sign in with Google button placeholder.' );
410410
$this->assertStringContainsString( 'googlesitekit-sign-in-with-google__profile-connect-button', $output, 'Connect branch should tag the placeholder with the profile-connect class.' );
411411
$this->assertStringNotContainsString( 'Disconnect Google Account', $output, 'Connect branch should not render the disconnect button.' );
412412
$this->assertSame( 1, substr_count( $output, '<h2>' ), 'Connect branch should render only one <h2>.' );
@@ -422,7 +422,7 @@ public function test_render_sign_in_with_google_profile__skips_connect_branch_wh
422422
// connected (no `clientID`), the connect section should not render
423423
// at all because the button JS would never wire it up.
424424
$output = $this->capture_action( 'show_user_profile', wp_get_current_user() );
425-
$this->assertEmpty( $output, 'Connect branch should not render when SiwG module is not connected.' );
425+
$this->assertEmpty( $output, 'Connect branch should not render when Sign in with Google module is not connected.' );
426426
}
427427

428428
public function test_render_sign_in_with_google_profile__skips_connect_branch_on_other_user_profile() {
@@ -441,17 +441,17 @@ public function test_render_sign_in_with_google_profile__skips_connect_branch_on
441441
// branch's other short-circuit can't fire. The only thing keeping
442442
// the section out is the admin viewing someone else's profile.
443443
$output = $this->capture_action( 'edit_user_profile', get_user_by( 'id', $editor_id ) );
444-
$this->assertEmpty( $output, 'Section should not render on another user profile when that user has no linked Google account.' );
444+
$this->assertEmpty( $output, "Section should never render on a profile that is not the current user's profile." );
445445
}
446446

447-
public function test_render_profile_admin_notices__shows_error_on_profile_page() {
447+
public function test_render_profile_admin_notices__shows_error_on_profile_page_when_profile_has_linked_google_account() {
448448
$_GET[ Profile_Authenticator::ERROR_QUERY_ARG ] = Profile_Authenticator::ERROR_ACCOUNT_ALREADY_CONNECTED;
449449
set_current_screen( 'profile' );
450450

451451
$this->module->register();
452452

453453
$output = $this->capture_action( 'admin_notices' );
454-
$this->assertStringContainsString( 'A profile is already connected to this Google account.', $output, 'Admin notice should render the already-connected copy on profile.php.' );
454+
$this->assertStringContainsString( 'A profile is already connected to this Google account.', $output, 'Admin notice should render the already-connected error.' );
455455

456456
unset( $_GET[ Profile_Authenticator::ERROR_QUERY_ARG ] );
457457
}
@@ -463,7 +463,7 @@ public function test_render_profile_admin_notices__shows_error_on_user_edit_page
463463
$this->module->register();
464464

465465
$output = $this->capture_action( 'admin_notices' );
466-
$this->assertStringContainsString( 'A profile is already connected to this Google account.', $output, 'Admin notice should render the already-connected copy on user-edit.php.' );
466+
$this->assertStringContainsString( 'A profile is already connected to this Google account.', $output, 'Admin notice should render the already-connected error.' );
467467

468468
unset( $_GET[ Profile_Authenticator::ERROR_QUERY_ARG ] );
469469
}
@@ -475,7 +475,7 @@ public function test_render_profile_admin_notices__skips_outside_profile_pages()
475475
$this->module->register();
476476

477477
$output = $this->capture_action( 'admin_notices' );
478-
$this->assertEmpty( $output, 'Admin notice should not render outside of profile.php or user-edit.php.' );
478+
$this->assertEmpty( $output, 'Errors related to a Google Account already being connected should not appear outside of profile.php or user-edit.php.' );
479479

480480
unset( $_GET[ Profile_Authenticator::ERROR_QUERY_ARG ] );
481481
}
@@ -516,7 +516,7 @@ public function test_maybe_render_profile_signinwithgoogle__skips_when_show_user
516516

517517
$output = $this->capture_action( 'admin_footer' );
518518

519-
$this->assertStringNotContainsString( "response.integration='connect_existing_profile'", $output, 'admin_footer should not emit the connect script outside the profile page.' );
519+
$this->assertStringNotContainsString( "response.integration='connect_existing_profile'", $output, 'admin_footer should not render the connect script outside the profile page.' );
520520
}
521521

522522
public function test_maybe_render_profile_signinwithgoogle__skips_when_user_already_linked() {

0 commit comments

Comments
 (0)