diff --git a/google-site-kit.php b/google-site-kit.php index 7fb82289ade..ff49bab415e 100644 --- a/google-site-kit.php +++ b/google-site-kit.php @@ -11,7 +11,7 @@ * Plugin Name: Site Kit by Google * Plugin URI: https://sitekit.withgoogle.com * Description: Site Kit is a one-stop solution for WordPress users to use everything Google has to offer to make them successful on the web. - * Version: 1.0.3 + * Version: 1.0.4 * Author: Google * Author URI: https://opensource.google.com * License: Apache License 2.0 @@ -24,7 +24,7 @@ } // Define most essential constants. -define( 'GOOGLESITEKIT_VERSION', '1.0.3' ); +define( 'GOOGLESITEKIT_VERSION', '1.0.4' ); define( 'GOOGLESITEKIT_PLUGIN_MAIN_FILE', __FILE__ ); /** diff --git a/includes/Core/Authentication/Authentication.php b/includes/Core/Authentication/Authentication.php index 4af01cb2615..876a6706551 100644 --- a/includes/Core/Authentication/Authentication.php +++ b/includes/Core/Authentication/Authentication.php @@ -466,7 +466,11 @@ private function refresh_auth_token_on_login() { */ private function inline_js_admin_data( $data ) { if ( ! isset( $data['userData'] ) ) { - $data['userData'] = array(); + $current_user = wp_get_current_user(); + $data['userData'] = array( + 'email' => $current_user->user_email, + 'picture' => get_avatar_url( $current_user->user_email ), + ); } $profile_data = $this->profile->get(); if ( $profile_data ) { diff --git a/includes/Core/Authentication/Clients/OAuth_Client.php b/includes/Core/Authentication/Clients/OAuth_Client.php index 4e6b8c27651..944212442bf 100644 --- a/includes/Core/Authentication/Clients/OAuth_Client.php +++ b/includes/Core/Authentication/Clients/OAuth_Client.php @@ -287,13 +287,8 @@ public function refresh_token() { * @since 1.0.0 */ public function revoke_token() { - // Stop if google_client not initialized yet. - if ( ! $this->google_client instanceof Google_Client ) { - return; - } - try { - $this->google_client->revokeToken(); + $this->get_client()->revokeToken(); } catch ( \Exception $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement // No special handling, we just need to make sure this goes through. } diff --git a/includes/Core/Authentication/Profile.php b/includes/Core/Authentication/Profile.php index e88386c16cb..8add8611e1e 100644 --- a/includes/Core/Authentication/Profile.php +++ b/includes/Core/Authentication/Profile.php @@ -10,7 +10,6 @@ namespace Google\Site_Kit\Core\Authentication; -use Google\Site_Kit\Helpers; use Google\Site_Kit\Core\Storage\User_Options; use Google\Site_Kit\Core\Authentication\Clients\OAuth_Client; use Google\Site_Kit_Dependencies\Google_Service_PeopleService; @@ -54,19 +53,6 @@ final class Profile { public function __construct( User_Options $user_options, OAuth_Client $auth_client ) { $this->user_options = $user_options; $this->auth_client = $auth_client; - - // Ensure we have fresh profile data. - $profile_data = $this->get(); - $timestamp = isset( $profile_data['timestamp'] ) ? (int) $profile_data['timestamp'] : 0; - $currenttime = time(); - - // If the stored profile data is missing, or older than a week, re-fetch it. - if ( ! $profile_data || ( ( $currenttime - $timestamp ) > ( 7 * DAY_IN_SECONDS ) ) ) { - $profile_data = $this->retrieve_google_profile_from_api(); - } - if ( 0 !== $profile_data['timestamp'] ) { - $this->set( $profile_data ); - } } /** @@ -77,7 +63,17 @@ public function __construct( User_Options $user_options, OAuth_Client $auth_clie * @return array|bool Value set for the profile, or false if not set. */ public function get() { - return $this->user_options->get( self::OPTION ); + // Ensure we have fresh profile data. + $profile_data = $this->user_options->get( self::OPTION ); + $profile_time = isset( $profile_data['timestamp'] ) ? (int) $profile_data['timestamp'] : 0; + $current_time = current_time( 'timestamp' ); + + // If the stored profile data is missing, or older than a week, re-fetch it. + if ( ! $profile_data || ( $current_time - $profile_time ) > WEEK_IN_SECONDS ) { + $profile_data = $this->retrieve_google_profile_from_api(); + } + + return $profile_data; } /** @@ -115,13 +111,7 @@ public function has() { */ private function retrieve_google_profile_from_api() { - // Fall back to the user's WordPress profile information. - $current_user = wp_get_current_user(); - $profile_data = array( - 'email' => $current_user->user_email, - 'photo' => get_avatar_url( $current_user->user_email ), - 'timestamp' => 0, // Don't cache WP user data. - ); + $profile_data = false; // Retrieve and store the user's Google profile data. try { @@ -129,14 +119,14 @@ private function retrieve_google_profile_from_api() { $people_service = new Google_Service_PeopleService( $client ); $profile = $people_service->people->get( 'people/me', array( 'personFields' => 'emailAddresses,photos' ) ); - if ( isset( $profile['emailAddresses'][0]['value'] ) && isset( $profile['photos'][0]['url'] ) ) { - - // Success - we have the profile data from the People API. + if ( isset( $profile['emailAddresses'][0]['value'], $profile['photos'][0]['url'] ) ) { $profile_data = array( 'email' => $profile['emailAddresses'][0]['value'], 'photo' => $profile['photos'][0]['url'], - 'timestamp' => time(), + 'timestamp' => current_time( 'timestamp' ), ); + + $this->set( $profile_data ); } } catch ( \Exception $e ) { return $profile_data; diff --git a/readme.txt b/readme.txt index 77aeb7815b8..c0583daf9af 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Contributors: google Requires at least: 4.7 Tested up to: 5.3 Requires PHP: 5.4 -Stable tag: 1.0.3 +Stable tag: 1.0.4 License: Apache License 2.0 License URI: https://www.apache.org/licenses/LICENSE-2.0 Tags: google, search-console, analytics, adsense, pagespeed-insights, optimize, tag-manager, site-kit diff --git a/tests/phpunit/integration/Core/Authentication/Clients/OAuth_ClientTest.php b/tests/phpunit/integration/Core/Authentication/Clients/OAuth_ClientTest.php index 26c71368fd6..5091cebeee1 100644 --- a/tests/phpunit/integration/Core/Authentication/Clients/OAuth_ClientTest.php +++ b/tests/phpunit/integration/Core/Authentication/Clients/OAuth_ClientTest.php @@ -49,8 +49,7 @@ public function test_refresh_token() { $client->refresh_token(); - // Google client must be initialized first - $this->assertEquals( 'refresh_token_not_exist', get_user_option( OAuth_Client::OPTION_ERROR_CODE, $user_id ) ); + $this->assertEquals( 'access_token_not_received', get_user_option( OAuth_Client::OPTION_ERROR_CODE, $user_id ) ); $client->get_client()->setHttpClient( new FakeHttpClient() ); $client->refresh_token(); diff --git a/tests/phpunit/integration/Core/Authentication/ProfileTest.php b/tests/phpunit/integration/Core/Authentication/ProfileTest.php index 873bd90e493..ee23e973cf5 100644 --- a/tests/phpunit/integration/Core/Authentication/ProfileTest.php +++ b/tests/phpunit/integration/Core/Authentication/ProfileTest.php @@ -14,7 +14,10 @@ use Google\Site_Kit\Core\Authentication\Clients\OAuth_Client; use Google\Site_Kit\Core\Authentication\Profile; use Google\Site_Kit\Core\Storage\User_Options; +use Google\Site_Kit\Tests\FakeHttpClient; use Google\Site_Kit\Tests\TestCase; +use Google\Site_Kit_Dependencies\GuzzleHttp\Message\Response; +use Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Stream; /** * @group Authentication @@ -28,12 +31,51 @@ public function test_get() { $client = new OAuth_Client( new Context( GOOGLESITEKIT_PLUGIN_MAIN_FILE ) ); $profile = new Profile( $user_options, $client ); + // Profile data is always an array with email, photo, and a timestamp otherwise false. $this->assertFalse( $profile->get() ); - // get() is a simple wrapper for fetching the option value. - $user_options->set( Profile::OPTION, 'test-profile' ); + $valid_profile_data = array( + 'email' => 'user@foo.com', + 'photo' => 'https://example.com/me.jpg', + 'timestamp' => current_time( 'timestamp' ) - DAY_IN_SECONDS, + ); + $user_options->set( Profile::OPTION, $valid_profile_data ); + + $this->assertEquals( $valid_profile_data, $profile->get() ); + + // If there is no data, or the timestamp is older than 1 week it attempts to fetch new data. + $stale_profile_data = $valid_profile_data; + $stale_profile_data['timestamp'] = current_time( 'timestamp' ) - WEEK_IN_SECONDS - MINUTE_IN_SECONDS; + update_user_option( $user_id, Profile::OPTION, $stale_profile_data ); + + // Stub the response to return fresh profile data from the API. + $fake_http = new FakeHttpClient(); + $fake_http->set_request_handler( function () { + return new Response( + 200, + array(), + Stream::factory(json_encode(array( + // ['emailAddresses'][0]['value'] + 'emailAddresses' => array( + array( 'value' => 'fresh@foo.com' ), + ), + // ['photos'][0]['url'] + 'photos' => array( + array( 'url' => 'https://example.com/fresh.jpg' ), + ), + ))) + ); + }); + $client->get_client()->setHttpClient( $fake_http ); - $this->assertEquals( 'test-profile', $profile->get() ); + $fresh_profile_data = $profile->get(); + + $this->assertEquals( 'fresh@foo.com', $fresh_profile_data['email'] ); + $this->assertEquals( 'https://example.com/fresh.jpg', $fresh_profile_data['photo'] ); + $this->assertGreaterThan( + $valid_profile_data['timestamp'], + $fresh_profile_data['timestamp'] + ); } public function test_has() { @@ -58,6 +100,8 @@ public function test_has() { $user_options->set( Profile::OPTION, array( 'email' => '', 'photo' => 'test-photo.jpg' ) ); $this->assertFalse( $profile->has() ); $user_options->set( Profile::OPTION, array( 'email' => 'user@example.com', 'photo' => 'test-photo.jpg' ) ); + $this->assertFalse( $profile->has() ); + $user_options->set( Profile::OPTION, array( 'email' => 'user@example.com', 'photo' => 'test-photo.jpg', 'timestamp' => current_time( 'timestamp' ) ) ); $this->assertTrue( $profile->has() ); }