Skip to content

Commit

Permalink
Merge pull request #855 from google/fix/854-profile-fetching
Browse files Browse the repository at this point in the history
Lazy load profile data
  • Loading branch information
felixarntz authored Nov 14, 2019
2 parents 5fab058 + af29410 commit 0f9425c
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 41 deletions.
4 changes: 2 additions & 2 deletions google-site-kit.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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__ );

/**
Expand Down
6 changes: 5 additions & 1 deletion includes/Core/Authentication/Authentication.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) {
Expand Down
7 changes: 1 addition & 6 deletions includes/Core/Authentication/Clients/OAuth_Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}
Expand Down
42 changes: 16 additions & 26 deletions includes/Core/Authentication/Profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 );
}
}

/**
Expand All @@ -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;
}

/**
Expand Down Expand Up @@ -115,28 +111,22 @@ 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 {
$client = $this->auth_client->get_client();
$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;
Expand Down
2 changes: 1 addition & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
50 changes: 47 additions & 3 deletions tests/phpunit/integration/Core/Authentication/ProfileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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' => '[email protected]',
'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' => '[email protected]' ),
),
// ['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( '[email protected]', $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() {
Expand All @@ -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' => '[email protected]', 'photo' => 'test-photo.jpg' ) );
$this->assertFalse( $profile->has() );
$user_options->set( Profile::OPTION, array( 'email' => '[email protected]', 'photo' => 'test-photo.jpg', 'timestamp' => current_time( 'timestamp' ) ) );
$this->assertTrue( $profile->has() );
}

Expand Down

0 comments on commit 0f9425c

Please sign in to comment.