summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrogerta@chromium.org <rogerta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-30 23:27:20 +0000
committerrogerta@chromium.org <rogerta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-30 23:27:20 +0000
commit431a075a671f8c7f1f31a90282f76af6e0cc94ff (patch)
tree0d0f540ddb318688b1613408c72030fc6700d094
parentfca61dc53df4dbb46c2ee4bf075f662632418d61 (diff)
downloadchromium_src-431a075a671f8c7f1f31a90282f76af6e0cc94ff.zip
chromium_src-431a075a671f8c7f1f31a90282f76af6e0cc94ff.tar.gz
chromium_src-431a075a671f8c7f1f31a90282f76af6e0cc94ff.tar.bz2
Use new people.get api instead of oauth2/v1/userinfo.
Consolidate all uses into main helper class. Details about new api: https://developers.google.com/+/api/latest/people/get Format of returned response: https://developers.google.com/+/api/latest/people#resource BUG=320354 Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=267068 Review URL: https://codereview.chromium.org/257773002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@267374 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/login/user_image_manager_browsertest.cc9
-rw-r--r--chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.cc2
-rw-r--r--chrome/browser/chromeos/policy/wildcard_login_checker.cc2
-rw-r--r--chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc13
-rw-r--r--chrome/browser/profiles/profile_downloader.cc120
-rw-r--r--chrome/browser/profiles/profile_downloader.h14
-rw-r--r--chrome/browser/profiles/profile_downloader_unittest.cc47
-rw-r--r--chrome/browser/signin/account_reconcilor_unittest.cc20
-rw-r--r--chrome/browser/sync/test/integration/sync_test.cc2
-rw-r--r--chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc4
-rw-r--r--components/policy/core/common/cloud/cloud_policy_client_registration_helper.cc2
-rw-r--r--components/policy/core/common/cloud/user_info_fetcher.cc73
-rw-r--r--components/policy/core/common/cloud/user_info_fetcher.h27
-rw-r--r--components/policy/core/common/cloud/user_info_fetcher_unittest.cc11
-rw-r--r--google_apis/gaia/gaia_constants.cc5
-rw-r--r--google_apis/gaia/gaia_constants.h4
-rw-r--r--google_apis/gaia/gaia_oauth_client.cc60
-rw-r--r--google_apis/gaia/gaia_oauth_client.h18
-rw-r--r--google_apis/gaia/gaia_oauth_client_unittest.cc59
-rw-r--r--google_apis/gaia/gaia_urls.cc10
-rw-r--r--google_apis/gaia/gaia_urls.h4
21 files changed, 290 insertions, 216 deletions
diff --git a/chrome/browser/chromeos/login/user_image_manager_browsertest.cc b/chrome/browser/chromeos/login/user_image_manager_browsertest.cc
index 796998b..0bb9730 100644
--- a/chrome/browser/chromeos/login/user_image_manager_browsertest.cc
+++ b/chrome/browser/chromeos/login/user_image_manager_browsertest.cc
@@ -56,6 +56,7 @@
#include "content/public/browser/notification_source.h"
#include "content/public/test/test_utils.h"
#include "crypto/rsa_private_key.h"
+#include "google_apis/gaia/gaia_oauth_client.h"
#include "google_apis/gaia/oauth2_token_service.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/url_request/test_url_fetcher_factory.h"
@@ -229,13 +230,15 @@ class UserImageManagerTest : public LoginManagerTest,
static_cast<OAuth2TokenService::Consumer*>(profile_downloader)->
OnGetTokenSuccess(NULL,
- std::string(),
+ "token",
base::Time::Now() + base::TimeDelta::FromDays(1));
- net::TestURLFetcher* fetcher = url_fetcher_factory->GetFetcherByID(0);
+ net::TestURLFetcher* fetcher =
+ url_fetcher_factory->GetFetcherByID(
+ gaia::GaiaOAuthClient::kUrlFetcherId);
ASSERT_TRUE(fetcher);
fetcher->SetResponseString(
- "{ \"picture\": \"http://localhost/avatar.jpg\" }");
+ "{ \"image\": {\"url\": \"http://localhost/avatar.jpg\"} }");
fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
net::OK));
fetcher->set_response_code(200);
diff --git a/chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.cc b/chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.cc
index abbab93..006b18e 100644
--- a/chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.cc
+++ b/chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.cc
@@ -58,6 +58,8 @@ void PolicyOAuth2TokenFetcher::StartFetchingAccessToken() {
std::vector<std::string> scopes;
scopes.push_back(GaiaConstants::kDeviceManagementServiceOAuth);
scopes.push_back(GaiaConstants::kOAuthWrapBridgeUserInfoScope);
+ scopes.push_back(GaiaConstants::kGoogleUserInfoEmail);
+ scopes.push_back(GaiaConstants::kGoogleUserInfoProfile);
access_token_fetcher_.reset(
new OAuth2AccessTokenFetcherImpl(this,
system_context_getter_.get(),
diff --git a/chrome/browser/chromeos/policy/wildcard_login_checker.cc b/chrome/browser/chromeos/policy/wildcard_login_checker.cc
index 7fa0253..7c2bd2e 100644
--- a/chrome/browser/chromeos/policy/wildcard_login_checker.cc
+++ b/chrome/browser/chromeos/policy/wildcard_login_checker.cc
@@ -18,7 +18,7 @@ namespace {
// Presence of this key in the userinfo response indicates whether the user is
// on a hosted domain.
-const char kHostedDomainKey[] = "hd";
+const char kHostedDomainKey[] = "domain";
// UMA histogram names.
const char kUMADelayPolicyTokenFetch[] =
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
index f9e490c..c80c62e 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
@@ -36,6 +36,7 @@
#include "content/public/browser/notification_source.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "google_apis/gaia/gaia_constants.h"
+#include "google_apis/gaia/gaia_oauth_client.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "net/http/http_status_code.h"
#include "net/url_request/test_url_fetcher_factory.h"
@@ -74,7 +75,7 @@ const char kValidTokenResponse[] =
const char kHostedDomainResponse[] =
"{"
- " \"hd\": \"test.com\""
+ " \"domain\": \"test.com\""
"}";
class SigninManagerFake : public FakeSigninManager {
@@ -231,10 +232,15 @@ class UserPolicySigninServiceTest : public testing::Test {
return static_cast<FakeProfileOAuth2TokenService*>(service);
}
+ // Returns true if a request for policy information is active. A request
+ // is considered active if there is an active fetcher for an access token
+ // hosted domain information (i.e. the gaia oauth client) or some other
+ // fecther used in the code (id 0).
bool IsRequestActive() {
if (!GetTokenService()->GetPendingRequests().empty())
return true;
- return url_factory_.GetFetcherByID(0);
+ return url_factory_.GetFetcherByID(0) ||
+ url_factory_.GetFetcherByID(gaia::GaiaOAuthClient::kUrlFetcherId);
}
void MakeOAuthTokenFetchSucceed() {
@@ -252,7 +258,8 @@ class UserPolicySigninServiceTest : public testing::Test {
void ReportHostedDomainStatus(bool is_hosted_domain) {
ASSERT_TRUE(IsRequestActive());
- net::TestURLFetcher* fetcher = url_factory_.GetFetcherByID(0);
+ net::TestURLFetcher* fetcher =
+ url_factory_.GetFetcherByID(gaia::GaiaOAuthClient::kUrlFetcherId);
fetcher->set_response_code(net::HTTP_OK);
fetcher->SetResponseString(is_hosted_domain ? kHostedDomainResponse : "{}");
fetcher->delegate()->OnURLFetchComplete(fetcher);
diff --git a/chrome/browser/profiles/profile_downloader.cc b/chrome/browser/profiles/profile_downloader.cc
index 15e8cee..5d08ffe 100644
--- a/chrome/browser/profiles/profile_downloader.cc
+++ b/chrome/browser/profiles/profile_downloader.cc
@@ -38,24 +38,16 @@ namespace {
const char kAuthorizationHeader[] =
"Authorization: Bearer %s";
-// URL requesting user info.
-const char kUserEntryURL[] =
- "https://www.googleapis.com/oauth2/v1/userinfo?alt=json";
-
-// OAuth scope for the user info API.
-// For more info, see https://developers.google.com/accounts/docs/OAuth2LoginV1.
-const char kAPIScope[] = "https://www.googleapis.com/auth/userinfo.profile";
-
// Path in JSON dictionary to user's photo thumbnail URL.
-const char kPhotoThumbnailURLPath[] = "picture";
+const char kPhotoThumbnailURLPath[] = "image.url";
// From the user info API, this field corresponds to the full name of the user.
-const char kFullNamePath[] = "name";
+const char kFullNamePath[] = "displayName";
-const char kGivenNamePath[] = "given_name";
+const char kGivenNamePath[] = "name.givenName";
// Path in JSON dictionary to user's preferred locale.
-const char kLocalePath[] = "locale";
+const char kLocalePath[] = "language";
// Path format for specifying thumbnail's size.
const char kThumbnailSizeFormat[] = "s%d-c";
@@ -133,7 +125,7 @@ bool GetImageURLWithSize(const GURL& old_url, int size, GURL* new_url) {
// Parses the entry response and gets the name and profile image URL.
// |data| should be the JSON formatted data return by the response.
// Returns false to indicate a parsing error.
-bool ProfileDownloader::ParseProfileJSON(const std::string& data,
+bool ProfileDownloader::ParseProfileJSON(base::DictionaryValue* root_dictionary,
base::string16* full_name,
base::string16* given_name,
std::string* url,
@@ -149,23 +141,6 @@ bool ProfileDownloader::ParseProfileJSON(const std::string& data,
*url = std::string();
*profile_locale = std::string();
- int error_code = -1;
- std::string error_message;
- scoped_ptr<base::Value> root_value(base::JSONReader::ReadAndReturnError(
- data, base::JSON_PARSE_RFC, &error_code, &error_message));
- if (!root_value) {
- LOG(ERROR) << "Error while parsing user entry response: "
- << error_message;
- return false;
- }
- if (!root_value->IsType(base::Value::TYPE_DICTIONARY)) {
- LOG(ERROR) << "JSON root is not a dictionary: "
- << root_value->GetType();
- return false;
- }
- base::DictionaryValue* root_dictionary =
- static_cast<base::DictionaryValue*>(root_value.get());
-
root_dictionary->GetString(kFullNamePath, full_name);
root_dictionary->GetString(kGivenNamePath, given_name);
root_dictionary->GetString(kLocalePath, profile_locale);
@@ -273,24 +248,17 @@ std::string ProfileDownloader::GetProfilePictureURL() const {
}
void ProfileDownloader::StartFetchingImage() {
+ DCHECK(!auth_token_.empty());
VLOG(1) << "Fetching user entry with token: " << auth_token_;
- user_entry_fetcher_.reset(net::URLFetcher::Create(
- GURL(kUserEntryURL), net::URLFetcher::GET, this));
- user_entry_fetcher_->SetRequestContext(
- delegate_->GetBrowserProfile()->GetRequestContext());
- user_entry_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
- net::LOAD_DO_NOT_SAVE_COOKIES);
- if (!auth_token_.empty()) {
- user_entry_fetcher_->SetExtraRequestHeaders(
- base::StringPrintf(kAuthorizationHeader, auth_token_.c_str()));
- }
- user_entry_fetcher_->Start();
+ gaia_client_.reset(new gaia::GaiaOAuthClient(
+ delegate_->GetBrowserProfile()->GetRequestContext()));
+ gaia_client_->GetUserInfo(auth_token_, 0, this);
}
void ProfileDownloader::StartFetchingOAuth2AccessToken() {
Profile* profile = delegate_->GetBrowserProfile();
OAuth2TokenService::ScopeSet scopes;
- scopes.insert(kAPIScope);
+ scopes.insert(GaiaConstants::kGoogleUserInfoProfile);
ProfileOAuth2TokenService* token_service =
ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
oauth2_access_token_request_ = token_service->StartRequest(
@@ -307,27 +275,10 @@ ProfileDownloader::~ProfileDownloader() {
service->RemoveObserver(this);
}
-void ProfileDownloader::OnURLFetchComplete(const net::URLFetcher* source) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- std::string data;
- source->GetResponseAsString(&data);
- bool network_error =
- source->GetStatus().status() != net::URLRequestStatus::SUCCESS;
- if (network_error || source->GetResponseCode() != 200) {
- LOG(WARNING) << "Fetching profile data failed";
- DVLOG(1) << " Status: " << source->GetStatus().status();
- DVLOG(1) << " Error: " << source->GetStatus().error();
- DVLOG(1) << " Response code: " << source->GetResponseCode();
- DVLOG(1) << " Url: " << source->GetURL().spec();
- delegate_->OnProfileDownloadFailure(this, network_error ?
- ProfileDownloaderDelegate::NETWORK_ERROR :
- ProfileDownloaderDelegate::SERVICE_ERROR);
- return;
- }
-
- if (source == user_entry_fetcher_.get()) {
+void ProfileDownloader::OnGetUserInfoResponse(
+ scoped_ptr<base::DictionaryValue> user_info) {
std::string image_url;
- if (!ParseProfileJSON(data,
+ if (!ParseProfileJSON(user_info.get(),
&profile_full_name_,
&profile_given_name_,
&image_url,
@@ -367,14 +318,45 @@ void ProfileDownloader::OnURLFetchComplete(const net::URLFetcher* source) {
base::StringPrintf(kAuthorizationHeader, auth_token_.c_str()));
}
profile_image_fetcher_->Start();
- } else if (source == profile_image_fetcher_.get()) {
- VLOG(1) << "Decoding the image...";
- scoped_refptr<ImageDecoder> image_decoder = new ImageDecoder(
- this, data, ImageDecoder::DEFAULT_CODEC);
- scoped_refptr<base::MessageLoopProxy> task_runner =
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
- image_decoder->Start(task_runner);
+}
+
+void ProfileDownloader::OnOAuthError() {
+ LOG(WARNING) << "OnOAuthError: Fetching profile data failed";
+ delegate_->OnProfileDownloadFailure(
+ this, ProfileDownloaderDelegate::SERVICE_ERROR);
+}
+
+void ProfileDownloader::OnNetworkError(int response_code) {
+ LOG(WARNING) << "OnNetworkError: Fetching profile data failed";
+ DVLOG(1) << " Response code: " << response_code;
+ delegate_->OnProfileDownloadFailure(
+ this, ProfileDownloaderDelegate::NETWORK_ERROR);
+}
+
+void ProfileDownloader::OnURLFetchComplete(const net::URLFetcher* source) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ std::string data;
+ source->GetResponseAsString(&data);
+ bool network_error =
+ source->GetStatus().status() != net::URLRequestStatus::SUCCESS;
+ if (network_error || source->GetResponseCode() != 200) {
+ LOG(WARNING) << "Fetching profile data failed";
+ DVLOG(1) << " Status: " << source->GetStatus().status();
+ DVLOG(1) << " Error: " << source->GetStatus().error();
+ DVLOG(1) << " Response code: " << source->GetResponseCode();
+ DVLOG(1) << " Url: " << source->GetURL().spec();
+ delegate_->OnProfileDownloadFailure(this, network_error ?
+ ProfileDownloaderDelegate::NETWORK_ERROR :
+ ProfileDownloaderDelegate::SERVICE_ERROR);
+ return;
}
+
+ VLOG(1) << "Decoding the image...";
+ scoped_refptr<ImageDecoder> image_decoder = new ImageDecoder(
+ this, data, ImageDecoder::DEFAULT_CODEC);
+ scoped_refptr<base::MessageLoopProxy> task_runner =
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
+ image_decoder->Start(task_runner);
}
void ProfileDownloader::OnImageDecoded(const ImageDecoder* decoder,
diff --git a/chrome/browser/profiles/profile_downloader.h b/chrome/browser/profiles/profile_downloader.h
index 8faf26d..a178773 100644
--- a/chrome/browser/profiles/profile_downloader.h
+++ b/chrome/browser/profiles/profile_downloader.h
@@ -12,6 +12,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "chrome/browser/image_decoder.h"
+#include "google_apis/gaia/gaia_oauth_client.h"
#include "google_apis/gaia/oauth2_token_service.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -26,7 +27,8 @@ class URLFetcher;
// Downloads user profile information. The profile picture is decoded in a
// sandboxed process.
-class ProfileDownloader : public net::URLFetcherDelegate,
+class ProfileDownloader : public gaia::GaiaOAuthClient::Delegate,
+ public net::URLFetcherDelegate,
public ImageDecoder::Delegate,
public OAuth2TokenService::Observer,
public OAuth2TokenService::Consumer {
@@ -80,6 +82,12 @@ class ProfileDownloader : public net::URLFetcherDelegate,
FRIEND_TEST_ALL_PREFIXES(ProfileDownloaderTest, ParseData);
FRIEND_TEST_ALL_PREFIXES(ProfileDownloaderTest, DefaultURL);
+ // gaia::GaiaOAuthClient::Delegate implementation.
+ virtual void OnGetUserInfoResponse(
+ scoped_ptr<base::DictionaryValue> user_info) OVERRIDE;
+ virtual void OnOAuthError() OVERRIDE;
+ virtual void OnNetworkError(int response_code) OVERRIDE;
+
// Overriden from net::URLFetcherDelegate:
virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
@@ -101,7 +109,7 @@ class ProfileDownloader : public net::URLFetcherDelegate,
// Parses the entry response and gets the name, profile image URL and locale.
// |data| should be the JSON formatted data return by the response.
// Returns false to indicate a parsing error.
- static bool ParseProfileJSON(const std::string& data,
+ static bool ParseProfileJSON(base::DictionaryValue* root_dictionary,
base::string16* full_name,
base::string16* given_name,
std::string* url,
@@ -123,7 +131,7 @@ class ProfileDownloader : public net::URLFetcherDelegate,
ProfileDownloaderDelegate* delegate_;
std::string account_id_;
std::string auth_token_;
- scoped_ptr<net::URLFetcher> user_entry_fetcher_;
+ scoped_ptr<gaia::GaiaOAuthClient> gaia_client_;
scoped_ptr<net::URLFetcher> profile_image_fetcher_;
scoped_ptr<OAuth2TokenService::Request> oauth2_access_token_request_;
base::string16 profile_full_name_;
diff --git a/chrome/browser/profiles/profile_downloader_unittest.cc b/chrome/browser/profiles/profile_downloader_unittest.cc
index 3761c77..c7c1312 100644
--- a/chrome/browser/profiles/profile_downloader_unittest.cc
+++ b/chrome/browser/profiles/profile_downloader_unittest.cc
@@ -4,38 +4,31 @@
#include "chrome/browser/profiles/profile_downloader.h"
+#include "base/json/json_reader.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
-std::string GetJSonData(const std::string& full_name,
- const std::string& given_name,
- const std::string& url,
- const std::string& locale) {
- std::stringstream stream;
- bool started = false;
-
- stream << "{ ";
- if (!full_name.empty()) {
- stream << "\"name\": \"" << full_name << "\"";
- started = true;
- }
- if (!given_name.empty()) {
- stream << (started ? ", " : "") << "\"given_name\": \"" << given_name
- << "\"";
- started = true;
- }
- if (!url.empty()) {
- stream << (started ? ", " : "") << "\"picture\": \"" << url << "\"";
- started = true;
- }
+void GetJSonData(const std::string& full_name,
+ const std::string& given_name,
+ const std::string& url,
+ const std::string& locale,
+ base::DictionaryValue* dict) {
+ if (!full_name.empty())
+ dict->SetString("displayName", full_name);
- if (!locale.empty())
- stream << (started ? ", " : "") << "\"locale\": \"" << locale << "\"";
+ if (!given_name.empty())
+ dict->SetString("name.givenName", given_name);
+
+ if (!url.empty())
+ dict->SetString("image.url", url);
- stream << " }";
- return stream.str();
+ if (!locale.empty())
+ dict->SetString("language", locale);
}
} // namespace
@@ -58,8 +51,10 @@ class ProfileDownloaderTest : public testing::Test {
base::string16 parsed_given_name;
std::string parsed_url;
std::string parsed_locale;
+ scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
+ GetJSonData(full_name, given_name, url, locale, dict.get());
bool result = ProfileDownloader::ParseProfileJSON(
- GetJSonData(full_name, given_name, url, locale),
+ dict.get(),
&parsed_full_name,
&parsed_given_name,
&parsed_url,
diff --git a/chrome/browser/signin/account_reconcilor_unittest.cc b/chrome/browser/signin/account_reconcilor_unittest.cc
index ca312d5..9da0f1d 100644
--- a/chrome/browser/signin/account_reconcilor_unittest.cc
+++ b/chrome/browser/signin/account_reconcilor_unittest.cc
@@ -262,7 +262,7 @@ TEST_F(AccountReconcilorTest, ValidateAccountsFromTokens) {
reconcilor->ValidateAccountsFromTokenService();
ASSERT_FALSE(reconcilor->AreAllRefreshTokensChecked());
- SetFakeResponse("https://www.googleapis.com/oauth2/v1/userinfo",
+ SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
"{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
token_service()->IssueTokenForAllPendingRequests("access_token",
base::Time::Now() + base::TimeDelta::FromHours(1));
@@ -284,7 +284,7 @@ TEST_F(AccountReconcilorTest, ValidateAccountsFromTokensFailedUserInfo) {
reconcilor->ValidateAccountsFromTokenService();
ASSERT_FALSE(reconcilor->AreAllRefreshTokensChecked());
- SetFakeResponse("https://www.googleapis.com/oauth2/v1/userinfo",
+ SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
"", net::HTTP_NOT_FOUND, net::URLRequestStatus::SUCCESS);
token_service()->IssueTokenForAllPendingRequests("access_token",
base::Time::Now() + base::TimeDelta::FromHours(1));
@@ -326,7 +326,7 @@ TEST_F(AccountReconcilorTest, StartReconcileNoop) {
SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
"[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
- SetFakeResponse("https://www.googleapis.com/oauth2/v1/userinfo",
+ SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
"{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
reconcilor->StartReconcile();
@@ -365,7 +365,7 @@ TEST_F(AccountReconcilorTest, StartReconcileNoopWithDots) {
SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
"[\"f\", [[\"b\", 0, \"n\", \"dot.s@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
- SetFakeResponse("https://www.googleapis.com/oauth2/v1/userinfo",
+ SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
"{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
reconcilor->StartReconcile();
@@ -400,7 +400,7 @@ TEST_F(AccountReconcilorTest, StartReconcileNoopMultiple) {
"[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
"[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
- SetFakeResponse("https://www.googleapis.com/oauth2/v1/userinfo",
+ SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
"{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
reconcilor->StartReconcile();
@@ -436,7 +436,7 @@ TEST_F(AccountReconcilorTest, StartReconcileAddToCookie) {
SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
"[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
- SetFakeResponse("https://www.googleapis.com/oauth2/v1/userinfo",
+ SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
"{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
AccountReconcilor* reconcilor = GetMockReconcilor();
@@ -464,7 +464,7 @@ TEST_F(AccountReconcilorTest, StartReconcileAddToChrome) {
"[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
"[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
- SetFakeResponse("https://www.googleapis.com/oauth2/v1/userinfo",
+ SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
"{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
AccountReconcilor* reconcilor = GetMockReconcilor();
@@ -491,7 +491,7 @@ TEST_F(AccountReconcilorTest, StartReconcileBadPrimary) {
"[\"f\", [[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
"[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
- SetFakeResponse("https://www.googleapis.com/oauth2/v1/userinfo",
+ SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
"{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
AccountReconcilor* reconcilor = GetMockReconcilor();
@@ -522,7 +522,7 @@ TEST_F(AccountReconcilorTest, StartReconcileOnlyOnce) {
SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
"[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
- SetFakeResponse("https://www.googleapis.com/oauth2/v1/userinfo",
+ SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
"{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
ASSERT_FALSE(reconcilor->is_reconcile_started_);
@@ -547,7 +547,7 @@ TEST_F(AccountReconcilorTest, StartReconcileWithSessionInfoExpiredDefault) {
"[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 0],"
"[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
- SetFakeResponse("https://www.googleapis.com/oauth2/v1/userinfo",
+ SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
"{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
AccountReconcilor* reconcilor =
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc
index dea47a9..3c8b63a 100644
--- a/chrome/browser/sync/test/integration/sync_test.cc
+++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -515,7 +515,7 @@ void SyncTest::SetupMockGaiaResponses() {
net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
fake_factory_->SetFakeResponse(
- GaiaUrls::GetInstance()->oauth_user_info_url(),
+ GaiaUrls::GetInstance()->people_get_url(),
"{"
" \"id\": \"12345\""
"}",
diff --git a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc
index b293e67..44b5281 100644
--- a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc
@@ -411,13 +411,13 @@ class LocalDiscoveryUITest : public WebUIBrowserTest {
.Times(AnyNumber());
fake_fetcher_factory().SetFakeResponse(
- GaiaUrls::GetInstance()->oauth_user_info_url(),
+ GaiaUrls::GetInstance()->people_get_url(),
kResponseGaiaId,
net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
- GaiaUrls::GetInstance()->oauth_user_info_url().spec()))
+ GaiaUrls::GetInstance()->people_get_url().spec()))
.Times(AnyNumber());
ProfileOAuth2TokenService* token_service =
diff --git a/components/policy/core/common/cloud/cloud_policy_client_registration_helper.cc b/components/policy/core/common/cloud/cloud_policy_client_registration_helper.cc
index c7b184b..b390ffb 100644
--- a/components/policy/core/common/cloud/cloud_policy_client_registration_helper.cc
+++ b/components/policy/core/common/cloud/cloud_policy_client_registration_helper.cc
@@ -24,7 +24,7 @@ namespace policy {
// The key under which the hosted-domain value is stored in the UserInfo
// response.
-const char kGetHostedDomainKey[] = "hd";
+const char kGetHostedDomainKey[] = "domain";
typedef base::Callback<void(const std::string&)> StringCallback;
diff --git a/components/policy/core/common/cloud/user_info_fetcher.cc b/components/policy/core/common/cloud/user_info_fetcher.cc
index b8f9f74d..978e4c8 100644
--- a/components/policy/core/common/cloud/user_info_fetcher.cc
+++ b/components/policy/core/common/cloud/user_info_fetcher.cc
@@ -16,23 +16,11 @@
#include "net/url_request/url_request_status.h"
#include "url/gurl.h"
-namespace {
-
-static const char kAuthorizationHeaderFormat[] =
- "Authorization: Bearer %s";
-
-static std::string MakeAuthorizationHeader(const std::string& auth_token) {
- return base::StringPrintf(kAuthorizationHeaderFormat, auth_token.c_str());
-}
-
-} // namespace
-
namespace policy {
UserInfoFetcher::UserInfoFetcher(Delegate* delegate,
net::URLRequestContextGetter* context)
- : delegate_(delegate),
- context_(context) {
+ : delegate_(delegate), gaia_client_(context) {
DCHECK(delegate);
}
@@ -41,49 +29,28 @@ UserInfoFetcher::~UserInfoFetcher() {
void UserInfoFetcher::Start(const std::string& access_token) {
// Create a URLFetcher and start it.
- url_fetcher_.reset(net::URLFetcher::Create(
- 0, GaiaUrls::GetInstance()->oauth_user_info_url(),
- net::URLFetcher::GET, this));
- url_fetcher_->SetRequestContext(context_);
- url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
- net::LOAD_DO_NOT_SAVE_COOKIES);
- url_fetcher_->AddExtraRequestHeader(MakeAuthorizationHeader(access_token));
- url_fetcher_->Start(); // Results in a call to OnURLFetchComplete().
+ gaia_client_.GetUserInfo(access_token, 0, &delegate_);
}
-void UserInfoFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
- net::URLRequestStatus status = source->GetStatus();
- GoogleServiceAuthError error = GoogleServiceAuthError::AuthErrorNone();
- if (!status.is_success()) {
- if (status.status() == net::URLRequestStatus::CANCELED)
- error = GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED);
- else
- error = GoogleServiceAuthError::FromConnectionError(status.error());
- } else if (source->GetResponseCode() != net::HTTP_OK) {
- DLOG(WARNING) << "UserInfo request failed with HTTP code: "
- << source->GetResponseCode();
- error = GoogleServiceAuthError(
- GoogleServiceAuthError::CONNECTION_FAILED);
- }
- if (error.state() != GoogleServiceAuthError::NONE) {
- delegate_->OnGetUserInfoFailure(error);
- return;
- }
+UserInfoFetcher::GaiaDelegate::GaiaDelegate(UserInfoFetcher::Delegate* delegate)
+ : delegate_(delegate) {
+}
+
+void UserInfoFetcher::GaiaDelegate::OnGetUserInfoResponse(
+ scoped_ptr<base::DictionaryValue> user_info) {
+ delegate_->OnGetUserInfoSuccess(user_info.get());
+}
+
+void UserInfoFetcher::GaiaDelegate::OnOAuthError() {
+ GoogleServiceAuthError error =
+ GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
+ delegate_->OnGetUserInfoFailure(error);
+}
- // Successfully fetched userinfo from the server - parse it and hand it off
- // to the delegate.
- std::string unparsed_data;
- source->GetResponseAsString(&unparsed_data);
- DVLOG(1) << "Received UserInfo response: " << unparsed_data;
- scoped_ptr<base::Value> parsed_value(base::JSONReader::Read(unparsed_data));
- base::DictionaryValue* dict;
- if (parsed_value.get() && parsed_value->GetAsDictionary(&dict)) {
- delegate_->OnGetUserInfoSuccess(dict);
- } else {
- NOTREACHED() << "Could not parse userinfo response from server";
- delegate_->OnGetUserInfoFailure(GoogleServiceAuthError(
- GoogleServiceAuthError::CONNECTION_FAILED));
- }
+void UserInfoFetcher::GaiaDelegate::OnNetworkError(int response_code) {
+ GoogleServiceAuthError error =
+ GoogleServiceAuthError::FromConnectionError(response_code);
+ delegate_->OnGetUserInfoFailure(error);
}
}; // namespace policy
diff --git a/components/policy/core/common/cloud/user_info_fetcher.h b/components/policy/core/common/cloud/user_info_fetcher.h
index c248d81..0f4c25f 100644
--- a/components/policy/core/common/cloud/user_info_fetcher.h
+++ b/components/policy/core/common/cloud/user_info_fetcher.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/memory/scoped_ptr.h"
#include "components/policy/policy_export.h"
+#include "google_apis/gaia/gaia_oauth_client.h"
#include "net/url_request/url_fetcher_delegate.h"
class GoogleServiceAuthError;
@@ -25,7 +26,7 @@ namespace policy {
// Class that makes a UserInfo request, parses the response, and notifies
// a provided Delegate when the request is complete.
-class POLICY_EXPORT UserInfoFetcher : public net::URLFetcherDelegate {
+class POLICY_EXPORT UserInfoFetcher {
public:
class POLICY_EXPORT Delegate {
public:
@@ -48,13 +49,25 @@ class POLICY_EXPORT UserInfoFetcher : public net::URLFetcherDelegate {
// Starts the UserInfo request, using the passed OAuth2 |access_token|.
void Start(const std::string& access_token);
- // net::URLFetcherDelegate implementation.
- virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
-
private:
- Delegate* delegate_;
- net::URLRequestContextGetter* context_;
- scoped_ptr<net::URLFetcher> url_fetcher_;
+ class GaiaDelegate : public gaia::GaiaOAuthClient::Delegate {
+ public:
+ explicit GaiaDelegate(UserInfoFetcher::Delegate* delegate);
+
+ private:
+ // gaia::GaiaOAuthClient::Delegate implementation.
+ virtual void OnGetUserInfoResponse(
+ scoped_ptr<base::DictionaryValue> user_info) OVERRIDE;
+ virtual void OnOAuthError() OVERRIDE;
+ virtual void OnNetworkError(int response_code) OVERRIDE;
+
+ UserInfoFetcher::Delegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(GaiaDelegate);
+ };
+
+ GaiaDelegate delegate_;
+ gaia::GaiaOAuthClient gaia_client_;
DISALLOW_COPY_AND_ASSIGN(UserInfoFetcher);
};
diff --git a/components/policy/core/common/cloud/user_info_fetcher_unittest.cc b/components/policy/core/common/cloud/user_info_fetcher_unittest.cc
index 8649427..5c8a24b 100644
--- a/components/policy/core/common/cloud/user_info_fetcher_unittest.cc
+++ b/components/policy/core/common/cloud/user_info_fetcher_unittest.cc
@@ -4,6 +4,7 @@
#include "base/values.h"
#include "components/policy/core/common/cloud/user_info_fetcher.h"
+#include "google_apis/gaia/gaia_oauth_client.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "net/http/http_status_code.h"
#include "net/url_request/test_url_fetcher_factory.h"
@@ -20,7 +21,7 @@ static const char kUserInfoResponse[] =
"{"
" \"email\": \"test_user@test.com\","
" \"verified_email\": true,"
- " \"hd\": \"test.com\""
+ " \"domain\": \"test.com\""
"}";
class MockUserInfoFetcherDelegate : public UserInfoFetcher::Delegate {
@@ -49,7 +50,8 @@ TEST_F(UserInfoFetcherTest, FailedFetch) {
// Fake a failed fetch - should result in the failure callback being invoked.
EXPECT_CALL(delegate, OnGetUserInfoFailure(_));
- net::TestURLFetcher* url_fetcher = url_factory_.GetFetcherByID(0);
+ net::TestURLFetcher* url_fetcher =
+ url_factory_.GetFetcherByID(gaia::GaiaOAuthClient::kUrlFetcherId);
url_fetcher->set_status(net::URLRequestStatus(
net::URLRequestStatus::FAILED, -1));
url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
@@ -65,12 +67,13 @@ TEST_F(UserInfoFetcherTest, SuccessfulFetch) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("email", "test_user@test.com");
dict->SetBoolean("verified_email", true);
- dict->SetString("hd", "test.com");
+ dict->SetString("domain", "test.com");
// Fake a successful fetch - should result in the data being parsed and
// the values passed off to the success callback.
EXPECT_CALL(delegate, OnGetUserInfoSuccess(MatchDict(dict.get())));
- net::TestURLFetcher* url_fetcher = url_factory_.GetFetcherByID(0);
+ net::TestURLFetcher* url_fetcher =
+ url_factory_.GetFetcherByID(gaia::GaiaOAuthClient::kUrlFetcherId);
url_fetcher->set_response_code(net::HTTP_OK);
url_fetcher->SetResponseString(kUserInfoResponse);
url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
diff --git a/google_apis/gaia/gaia_constants.cc b/google_apis/gaia/gaia_constants.cc
index 60546bf..14a41c9 100644
--- a/google_apis/gaia/gaia_constants.cc
+++ b/google_apis/gaia/gaia_constants.cc
@@ -45,6 +45,11 @@ const char kChromeSyncManagedOAuth2Scope[] =
const char kGoogleTalkOAuth2Scope[] =
"https://www.googleapis.com/auth/googletalk";
+const char kGoogleUserInfoEmail[] =
+ "https://www.googleapis.com/auth/userinfo.email";
+const char kGoogleUserInfoProfile[] =
+ "https://www.googleapis.com/auth/userinfo.profile";
+
// Used to mint uber auth tokens when needed.
const char kGaiaSid[] = "sid";
const char kGaiaLsid[] = "lsid";
diff --git a/google_apis/gaia/gaia_constants.h b/google_apis/gaia/gaia_constants.h
index 406298c..7adc130 100644
--- a/google_apis/gaia/gaia_constants.h
+++ b/google_apis/gaia/gaia_constants.h
@@ -18,6 +18,8 @@ extern const char kGaiaService[]; // uber token
extern const char kPicasaService[];
extern const char kSyncService[];
extern const char kRemotingService[];
+
+// OAuth2 scopes.
extern const char kOAuth1LoginScope[];
extern const char kOAuthWrapBridgeUserInfoScope[];
extern const char kDeviceManagementServiceOAuth[];
@@ -25,6 +27,8 @@ extern const char kAnyApiOAuth2Scope[];
extern const char kChromeSyncOAuth2Scope[];
extern const char kChromeSyncManagedOAuth2Scope[];
extern const char kGoogleTalkOAuth2Scope[];
+extern const char kGoogleUserInfoEmail[];
+extern const char kGoogleUserInfoProfile[];
// Used with uber auth tokens when needed.
extern const char kGaiaSid[];
diff --git a/google_apis/gaia/gaia_oauth_client.cc b/google_apis/gaia/gaia_oauth_client.cc
index 1113ff6..1d5f9eb 100644
--- a/google_apis/gaia/gaia_oauth_client.cc
+++ b/google_apis/gaia/gaia_oauth_client.cc
@@ -56,6 +56,9 @@ class GaiaOAuthClient::Core
void GetUserId(const std::string& oauth_access_token,
int max_retries,
Delegate* delegate);
+ void GetUserInfo(const std::string& oauth_access_token,
+ int max_retries,
+ Delegate* delegate);
void GetTokenInfo(const std::string& oauth_access_token,
int max_retries,
Delegate* delegate);
@@ -73,13 +76,14 @@ class GaiaOAuthClient::Core
TOKEN_INFO,
USER_EMAIL,
USER_ID,
+ USER_INFO,
};
virtual ~Core() {}
- void GetUserInfo(const std::string& oauth_access_token,
- int max_retries,
- Delegate* delegate);
+ void PeopleGet(const std::string& oauth_access_token,
+ int max_retries,
+ Delegate* delegate);
void MakeGaiaRequest(const GURL& url,
const std::string& post_body,
int max_retries,
@@ -145,7 +149,7 @@ void GaiaOAuthClient::Core::GetUserEmail(const std::string& oauth_access_token,
DCHECK_EQ(request_type_, NO_PENDING_REQUEST);
DCHECK(!request_.get());
request_type_ = USER_EMAIL;
- GetUserInfo(oauth_access_token, max_retries, delegate);
+ PeopleGet(oauth_access_token, max_retries, delegate);
}
void GaiaOAuthClient::Core::GetUserId(const std::string& oauth_access_token,
@@ -154,16 +158,25 @@ void GaiaOAuthClient::Core::GetUserId(const std::string& oauth_access_token,
DCHECK_EQ(request_type_, NO_PENDING_REQUEST);
DCHECK(!request_.get());
request_type_ = USER_ID;
- GetUserInfo(oauth_access_token, max_retries, delegate);
+ PeopleGet(oauth_access_token, max_retries, delegate);
}
void GaiaOAuthClient::Core::GetUserInfo(const std::string& oauth_access_token,
int max_retries,
Delegate* delegate) {
+ DCHECK_EQ(request_type_, NO_PENDING_REQUEST);
+ DCHECK(!request_.get());
+ request_type_ = USER_INFO;
+ PeopleGet(oauth_access_token, max_retries, delegate);
+}
+
+void GaiaOAuthClient::Core::PeopleGet(const std::string& oauth_access_token,
+ int max_retries,
+ Delegate* delegate) {
delegate_ = delegate;
num_retries_ = 0;
request_.reset(net::URLFetcher::Create(
- kUrlFetcherId, GURL(GaiaUrls::GetInstance()->oauth_user_info_url()),
+ kUrlFetcherId, GURL(GaiaUrls::GetInstance()->people_get_url()),
net::URLFetcher::GET, this));
request_->SetRequestContext(request_context_getter_.get());
request_->AddExtraRequestHeader("Authorization: OAuth " + oauth_access_token);
@@ -282,9 +295,27 @@ void GaiaOAuthClient::Core::HandleResponse(
switch (type) {
case USER_EMAIL: {
- std::string email;
- response_dict->GetString("email", &email);
- delegate_->OnGetUserEmailResponse(email);
+ // Use first email of type "account" as the user's email.
+ const base::ListValue* emails_list;
+ bool email_found = false;
+ if (response_dict->GetList("emails", &emails_list)) {
+ for (size_t i = 0; i < emails_list->GetSize(); ++i) {
+ const base::DictionaryValue* email_dict;
+ if (emails_list->GetDictionary(i, &email_dict)) {
+ std::string email;
+ std::string type;
+ if (email_dict->GetString("type", &type) &&
+ type == "account" &&
+ email_dict->GetString("value", &email)) {
+ delegate_->OnGetUserEmailResponse(email);
+ email_found = true;
+ break;
+ }
+ }
+ }
+ }
+ if (!email_found)
+ delegate_->OnNetworkError(net::URLFetcher::RESPONSE_CODE_INVALID);
break;
}
@@ -295,6 +326,11 @@ void GaiaOAuthClient::Core::HandleResponse(
break;
}
+ case USER_INFO: {
+ delegate_->OnGetUserInfoResponse(response_dict.Pass());
+ break;
+ }
+
case TOKEN_INFO: {
delegate_->OnGetTokenInfoResponse(response_dict.Pass());
break;
@@ -372,6 +408,12 @@ void GaiaOAuthClient::GetUserId(const std::string& access_token,
return core_->GetUserId(access_token, max_retries, delegate);
}
+void GaiaOAuthClient::GetUserInfo(const std::string& access_token,
+ int max_retries,
+ Delegate* delegate) {
+ return core_->GetUserInfo(access_token, max_retries, delegate);
+}
+
void GaiaOAuthClient::GetTokenInfo(const std::string& access_token,
int max_retries,
Delegate* delegate) {
diff --git a/google_apis/gaia/gaia_oauth_client.h b/google_apis/gaia/gaia_oauth_client.h
index 8e01ef6..fd13f46 100644
--- a/google_apis/gaia/gaia_oauth_client.h
+++ b/google_apis/gaia/gaia_oauth_client.h
@@ -47,6 +47,9 @@ class GaiaOAuthClient {
virtual void OnGetUserEmailResponse(const std::string& user_email) {}
// Invoked on a successful response to the GetUserId request.
virtual void OnGetUserIdResponse(const std::string& user_id) {}
+ // Invoked on a successful response to the GetUserInfo request.
+ virtual void OnGetUserInfoResponse(
+ scoped_ptr<base::DictionaryValue> user_info) {}
// Invoked on a successful response to the GetTokenInfo request.
virtual void OnGetTokenInfoResponse(
scoped_ptr<base::DictionaryValue> token_info) {}
@@ -88,7 +91,7 @@ class GaiaOAuthClient {
int max_retries,
Delegate* delegate);
- // Call the userinfo API, returning the user email address associated
+ // Call the people.get API, returning the user email address associated
// with the given access token. The provided access token must have
// https://www.googleapis.com/auth/userinfo.email as one of its scopes.
// See |max_retries| docs above.
@@ -96,14 +99,23 @@ class GaiaOAuthClient {
int max_retries,
Delegate* delegate);
- // Call the userinfo API, returning the user gaia ID associated
+ // Call the people.get API, returning the user gaia ID associated
// with the given access token. The provided access token must have
- // https://www.googleapis.com/auth/userinfo as one of its scopes.
+ // https://www.googleapis.com/auth/userinfo.profile as one of its scopes.
// See |max_retries| docs above.
void GetUserId(const std::string& oauth_access_token,
int max_retries,
Delegate* delegate);
+ // Call the people.get API, returning the user info associated
+ // with the given access token. The provided access token must have
+ // https://www.googleapis.com/auth/userinfo.email and
+ // https://www.googleapis.com/auth/userinfo.profile as its scopes.
+ // See |max_retries| docs above.
+ void GetUserInfo(const std::string& oauth_access_token,
+ int max_retries,
+ Delegate* delegate);
+
// Call the tokeninfo API, returning a dictionary of response values. The
// provided access token may have any scope, and basic results will be
// returned: issued_to, audience, scope, expires_in, access_type. In
diff --git a/google_apis/gaia/gaia_oauth_client_unittest.cc b/google_apis/gaia/gaia_oauth_client_unittest.cc
index d4014f7..338578e 100644
--- a/google_apis/gaia/gaia_oauth_client_unittest.cc
+++ b/google_apis/gaia/gaia_oauth_client_unittest.cc
@@ -134,25 +134,22 @@ const std::string kTestUserId = "8675309";
const int kTestExpiresIn = 3920;
const std::string kDummyGetTokensResult =
- "{\"access_token\":\"" + kTestAccessToken + "\","
- "\"expires_in\":" + base::IntToString(kTestExpiresIn) + ","
- "\"refresh_token\":\"" + kTestRefreshToken + "\"}";
+ "{\"access_token\":\"" + kTestAccessToken + "\","
+ "\"expires_in\":" + base::IntToString(kTestExpiresIn) + ","
+ "\"refresh_token\":\"" + kTestRefreshToken + "\"}";
const std::string kDummyRefreshTokenResult =
- "{\"access_token\":\"" + kTestAccessToken + "\","
- "\"expires_in\":" + base::IntToString(kTestExpiresIn) + "}";
-
-const std::string kDummyUserInfoResult =
- "{\"email\":\"" + kTestUserEmail + "\"}";
+ "{\"access_token\":\"" + kTestAccessToken + "\","
+ "\"expires_in\":" + base::IntToString(kTestExpiresIn) + "}";
const std::string kDummyUserIdResult =
- "{\"id\":\"" + kTestUserId + "\"}";
+ "{\"id\":\"" + kTestUserId + "\"}";
const std::string kDummyTokenInfoResult =
- "{\"issued_to\": \"1234567890.apps.googleusercontent.com\","
- "\"audience\": \"1234567890.apps.googleusercontent.com\","
- "\"scope\": \"https://googleapis.com/oauth2/v2/tokeninfo\","
- "\"expires_in\":" + base::IntToString(kTestExpiresIn) + "}";
+ "{\"issued_to\": \"1234567890.apps.googleusercontent.com\","
+ "\"audience\": \"1234567890.apps.googleusercontent.com\","
+ "\"scope\": \"https://googleapis.com/oauth2/v2/tokeninfo\","
+ "\"expires_in\":" + base::IntToString(kTestExpiresIn) + "}";
}
namespace gaia {
@@ -304,11 +301,45 @@ TEST_F(GaiaOAuthClientTest, RefreshTokenDownscopingSuccess) {
factory.get_url_fetcher()->Finish();
}
-
TEST_F(GaiaOAuthClientTest, GetUserEmail) {
MockGaiaOAuthClientDelegate delegate;
EXPECT_CALL(delegate, OnGetUserEmailResponse(kTestUserEmail)).Times(1);
+ const std::string kDummyUserInfoResult =
+ "{\"emails\": [{\"value\":\"" + kTestUserEmail +
+ "\", \"type\":\"account\"}]}";
+
+ MockOAuthFetcherFactory factory;
+ factory.set_results(kDummyUserInfoResult);
+
+ GaiaOAuthClient auth(GetRequestContext());
+ auth.GetUserEmail("access_token", 1, &delegate);
+}
+
+TEST_F(GaiaOAuthClientTest, GetUserEmailSecondItemValid) {
+ MockGaiaOAuthClientDelegate delegate;
+ EXPECT_CALL(delegate, OnGetUserEmailResponse(kTestUserEmail)).Times(1);
+
+ const std::string kDummyUserInfoResult =
+ "{\"emails\": [{\"value\":\"foo\"},"
+ "{\"value\":\"" + kTestUserEmail +
+ "\", \"type\":\"account\"}]}";
+
+ MockOAuthFetcherFactory factory;
+ factory.set_results(kDummyUserInfoResult);
+
+ GaiaOAuthClient auth(GetRequestContext());
+ auth.GetUserEmail("access_token", 1, &delegate);
+}
+
+TEST_F(GaiaOAuthClientTest, GetUserEmailNoValidItems) {
+ MockGaiaOAuthClientDelegate delegate;
+ EXPECT_CALL(delegate, OnNetworkError(_)).Times(1);
+
+ const std::string kDummyUserInfoResult =
+ "{\"emails\": [{\"value\":\"" + kTestUserEmail +
+ "\", \"type\":\"foo\"}]}";
+
MockOAuthFetcherFactory factory;
factory.set_results(kDummyUserInfoResult);
diff --git a/google_apis/gaia/gaia_urls.cc b/google_apis/gaia/gaia_urls.cc
index 0b44a91..5abff9c 100644
--- a/google_apis/gaia/gaia_urls.cc
+++ b/google_apis/gaia/gaia_urls.cc
@@ -42,7 +42,7 @@ const char kOAuth2TokenUrlSuffix[] = "o/oauth2/token";
// API calls from www.googleapis.com
const char kOAuth2IssueTokenUrlSuffix[] = "oauth2/v2/IssueToken";
const char kOAuth2TokenInfoUrlSuffix[] = "oauth2/v2/tokeninfo";
-const char kOAuthUserInfoUrlSuffix[] = "oauth2/v1/userinfo";
+const char kPeopleGetUrlSuffix[] = "plus/v1/people/me";
void GetSwitchValueWithDefault(const char* switch_value,
const char* default_value,
@@ -118,8 +118,8 @@ GaiaUrls::GaiaUrls() {
google_apis_origin_url_.Resolve(kOAuth2IssueTokenUrlSuffix);
oauth2_token_info_url_ =
google_apis_origin_url_.Resolve(kOAuth2TokenInfoUrlSuffix);
- oauth_user_info_url_ =
- google_apis_origin_url_.Resolve(kOAuthUserInfoUrlSuffix);
+ people_get_url_ =
+ google_apis_origin_url_.Resolve(kPeopleGetUrlSuffix);
gaia_login_form_realm_ = gaia_url_;
}
@@ -179,8 +179,8 @@ const GURL& GaiaUrls::oauth_wrap_bridge_url() const {
return oauth_wrap_bridge_url_;
}
-const GURL& GaiaUrls::oauth_user_info_url() const {
- return oauth_user_info_url_;
+const GURL& GaiaUrls::people_get_url() const {
+ return people_get_url_;
}
const GURL& GaiaUrls::oauth_revoke_token_url() const {
diff --git a/google_apis/gaia/gaia_urls.h b/google_apis/gaia/gaia_urls.h
index f96e89c..7a41ebf 100644
--- a/google_apis/gaia/gaia_urls.h
+++ b/google_apis/gaia/gaia_urls.h
@@ -24,12 +24,12 @@ class GaiaUrls {
const GURL& service_logout_url() const;
const GURL& issue_auth_token_url() const;
const GURL& get_user_info_url() const;
+ const GURL& people_get_url() const;
const GURL& token_auth_url() const;
const GURL& merge_session_url() const;
const GURL& get_oauth_token_url() const;
const GURL& oauth_get_access_token_url() const;
const GURL& oauth_wrap_bridge_url() const;
- const GURL& oauth_user_info_url() const;
const GURL& oauth_revoke_token_url() const;
const GURL& oauth1_login_url() const;
const GURL& list_accounts_url() const;
@@ -65,12 +65,12 @@ class GaiaUrls {
GURL service_logout_url_;
GURL issue_auth_token_url_;
GURL get_user_info_url_;
+ GURL people_get_url_;
GURL token_auth_url_;
GURL merge_session_url_;
GURL get_oauth_token_url_;
GURL oauth_get_access_token_url_;
GURL oauth_wrap_bridge_url_;
- GURL oauth_user_info_url_;
GURL oauth_revoke_token_url_;
GURL oauth1_login_url_;
GURL list_accounts_url_;