diff options
-rw-r--r-- | chrome/browser/signin/signin_manager.cc | 47 | ||||
-rw-r--r-- | chrome/browser/signin/signin_manager.h | 8 | ||||
-rw-r--r-- | chrome/browser/signin/signin_manager_factory.cc | 2 | ||||
-rw-r--r-- | chrome/browser/signin/signin_manager_unittest.cc | 30 | ||||
-rw-r--r-- | chrome/common/net/gaia/gaia_auth_consumer.h | 7 | ||||
-rw-r--r-- | chrome/common/net/gaia/gaia_auth_fetcher.cc | 22 | ||||
-rw-r--r-- | chrome/common/net/gaia/gaia_auth_fetcher.h | 8 | ||||
-rw-r--r-- | chrome/common/pref_names.cc | 3 | ||||
-rw-r--r-- | chrome/common/pref_names.h | 1 |
9 files changed, 85 insertions, 43 deletions
diff --git a/chrome/browser/signin/signin_manager.cc b/chrome/browser/signin/signin_manager.cc index 47c0c85..5f6c987 100644 --- a/chrome/browser/signin/signin_manager.cc +++ b/chrome/browser/signin/signin_manager.cc @@ -4,7 +4,11 @@ #include "chrome/browser/signin/signin_manager.h" +#include <string> +#include <vector> + #include "base/command_line.h" +#include "base/string_split.h" #include "base/string_util.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" @@ -18,6 +22,8 @@ #include "content/public/browser/notification_service.h" const char kGetInfoEmailKey[] = "email"; +const char kGetInfoServicesKey[] = "allServices"; +const char kGooglePlusServiceKey[] = "googleme"; SigninManager::SigninManager() : profile_(NULL), @@ -188,6 +194,7 @@ void SigninManager::SignOut() { authenticated_username_.clear(); profile_->GetPrefs()->ClearPref(prefs::kGoogleServicesUsername); profile_->GetPrefs()->ClearPref(prefs::kSyncUsingOAuth); + profile_->GetPrefs()->ClearPref(prefs::kIsGooglePlusUser); profile_->GetTokenService()->ResetCredentialsInMemory(); profile_->GetTokenService()->EraseTokensFromDB(); } @@ -203,22 +210,40 @@ bool SigninManager::AuthInProgress() const { void SigninManager::OnClientLoginSuccess(const ClientLoginResult& result) { DCHECK(!browser_sync::IsUsingOAuth()); last_result_ = result; - // Make a request for the canonical email address. - client_login_->StartGetUserInfo(result.lsid, kGetInfoEmailKey); + // Make a request for the canonical email address and services. + client_login_->StartGetUserInfo(result.lsid); } // NOTE: GetUserInfo is a ClientLogin request similar to OAuth's userinfo -void SigninManager::OnGetUserInfoSuccess(const std::string& key, - const std::string& value) { +void SigninManager::OnGetUserInfoSuccess(const UserInfoMap& data) { DCHECK(!browser_sync::IsUsingOAuth()); - DCHECK(key == kGetInfoEmailKey); - last_login_auth_error_ = GoogleServiceAuthError::None(); - SetAuthenticatedUsername(value); - possibly_invalid_username_.clear(); - profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername, - authenticated_username_); - profile_->GetPrefs()->SetBoolean(prefs::kSyncUsingOAuth, false); + UserInfoMap::const_iterator email_iter = data.find(kGetInfoEmailKey); + if (email_iter == data.end()) { + OnGetUserInfoKeyNotFound(kGetInfoEmailKey); + return; + } else { + DCHECK(email_iter->first == kGetInfoEmailKey); + last_login_auth_error_ = GoogleServiceAuthError::None(); + SetAuthenticatedUsername(email_iter->second); + possibly_invalid_username_.clear(); + profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername, + authenticated_username_); + profile_->GetPrefs()->SetBoolean(prefs::kSyncUsingOAuth, false); + } + UserInfoMap::const_iterator service_iter = data.find(kGetInfoServicesKey); + if (service_iter == data.end()) { + DLOG(WARNING) << "Could not retrieve services for account with email: " + << authenticated_username_ <<"."; + } else { + DCHECK(service_iter->first == kGetInfoServicesKey); + std::vector<std::string> services; + base::SplitStringUsingSubstr(service_iter->second, ", ", &services); + std::vector<std::string>::const_iterator iter = + std::find(services.begin(), services.end(), kGooglePlusServiceKey); + bool isGPlusUser = (iter != services.end()); + profile_->GetPrefs()->SetBoolean(prefs::kIsGooglePlusUser, isGPlusUser); + } GoogleServiceSigninSuccessDetails details(authenticated_username_, password_); content::NotificationService::current()->Notify( diff --git a/chrome/browser/signin/signin_manager.h b/chrome/browser/signin/signin_manager.h index 5f4e806..6224463 100644 --- a/chrome/browser/signin/signin_manager.h +++ b/chrome/browser/signin/signin_manager.h @@ -100,13 +100,15 @@ class SigninManager : public GaiaAuthConsumer, // Returns true if there's a signin in progress. bool AuthInProgress() const; + // Handles errors if a required user info key is not returned from the + // GetUserInfo call. + void OnGetUserInfoKeyNotFound(const std::string& key); + // GaiaAuthConsumer virtual void OnClientLoginSuccess(const ClientLoginResult& result) OVERRIDE; virtual void OnClientLoginFailure( const GoogleServiceAuthError& error) OVERRIDE; - virtual void OnGetUserInfoSuccess(const std::string& key, - const std::string& value) OVERRIDE; - virtual void OnGetUserInfoKeyNotFound(const std::string& key) OVERRIDE; + virtual void OnGetUserInfoSuccess(const UserInfoMap& data) OVERRIDE; virtual void OnGetUserInfoFailure( const GoogleServiceAuthError& error) OVERRIDE; virtual void OnTokenAuthFailure(const GoogleServiceAuthError& error) OVERRIDE; diff --git a/chrome/browser/signin/signin_manager_factory.cc b/chrome/browser/signin/signin_manager_factory.cc index 2a307fe..659eee4 100644 --- a/chrome/browser/signin/signin_manager_factory.cc +++ b/chrome/browser/signin/signin_manager_factory.cc @@ -39,6 +39,8 @@ void SigninManagerFactory::RegisterUserPrefs(PrefService* user_prefs) { PrefService::UNSYNCABLE_PREF); user_prefs->RegisterBooleanPref(prefs::kReverseAutologinEnabled, true, PrefService::UNSYNCABLE_PREF); + user_prefs->RegisterBooleanPref(prefs::kIsGooglePlusUser, false, + PrefService::UNSYNCABLE_PREF); } ProfileKeyedService* SigninManagerFactory::BuildServiceInstanceFor( diff --git a/chrome/browser/signin/signin_manager_unittest.cc b/chrome/browser/signin/signin_manager_unittest.cc index 68d3bfb..e5626dc 100644 --- a/chrome/browser/signin/signin_manager_unittest.cc +++ b/chrome/browser/signin/signin_manager_unittest.cc @@ -65,9 +65,12 @@ class SigninManagerTest : public TokenServiceTestHarness { browser_sync::SetIsUsingOAuthForTest(originally_using_oauth_); } - void SimulateValidResponseClientLogin() { + void SimulateValidResponseClientLogin(bool isGPlusUser) { DCHECK(!browser_sync::IsUsingOAuth()); // Simulate the correct ClientLogin response. + std::string respons_string = isGPlusUser ? + "email=user@gmail.com\nallServices=googleme" : + "email=user@gmail.com\nallServices="; TestURLFetcher* fetcher = factory_.GetFetcherByID(0); DCHECK(fetcher); DCHECK(fetcher->delegate()); @@ -86,7 +89,7 @@ class SigninManagerTest : public TokenServiceTestHarness { fetcher->set_url(GURL(GaiaUrls::GetInstance()->get_user_info_url())); fetcher->set_status(net::URLRequestStatus()); fetcher->set_response_code(200); - fetcher->SetResponseString("email=user@gmail.com"); + fetcher->SetResponseString(respons_string); fetcher->delegate()->OnURLFetchComplete(fetcher); } @@ -136,8 +139,9 @@ TEST_F(SigninManagerTest, SignInClientLogin) { manager_->StartSignIn("username", "password", "", ""); EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty()); - SimulateValidResponseClientLogin(); + SimulateValidResponseClientLogin(true); EXPECT_FALSE(manager_->GetAuthenticatedUsername().empty()); + EXPECT_TRUE(profile_->GetPrefs()->GetBoolean(prefs::kIsGooglePlusUser)); // Should go into token service and stop. EXPECT_EQ(1U, google_login_success_.size()); @@ -149,6 +153,19 @@ TEST_F(SigninManagerTest, SignInClientLogin) { EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedUsername()); } +TEST_F(SigninManagerTest, SignInClientLoginNoGPlus) { + browser_sync::SetIsUsingOAuthForTest(false); + manager_->Initialize(profile_.get()); + EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty()); + + manager_->StartSignIn("username", "password", "", ""); + EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty()); + + SimulateValidResponseClientLogin(false); + EXPECT_FALSE(manager_->GetAuthenticatedUsername().empty()); + EXPECT_FALSE(profile_->GetPrefs()->GetBoolean(prefs::kIsGooglePlusUser)); +} + TEST_F(SigninManagerTest, ClearTransientSigninData) { browser_sync::SetIsUsingOAuthForTest(false); manager_->Initialize(profile_.get()); @@ -157,7 +174,7 @@ TEST_F(SigninManagerTest, ClearTransientSigninData) { manager_->StartSignIn("username", "password", "", ""); EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty()); - SimulateValidResponseClientLogin(); + SimulateValidResponseClientLogin(false); // Should go into token service and stop. EXPECT_EQ(1U, google_login_success_.size()); @@ -206,12 +223,13 @@ TEST_F(SigninManagerTest, SignOutClientLogin) { browser_sync::SetIsUsingOAuthForTest(false); manager_->Initialize(profile_.get()); manager_->StartSignIn("username", "password", "", ""); - SimulateValidResponseClientLogin(); + SimulateValidResponseClientLogin(false); manager_->OnClientLoginSuccess(credentials_); EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedUsername()); manager_->SignOut(); EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty()); + EXPECT_FALSE(profile_->GetPrefs()->GetBoolean(prefs::kIsGooglePlusUser)); // Should not be persisted anymore manager_.reset(new SigninManager()); manager_->Initialize(profile_.get()); @@ -267,7 +285,7 @@ TEST_F(SigninManagerTest, ProvideSecondFactorSuccess) { EXPECT_FALSE(manager_->possibly_invalid_username_.empty()); manager_->ProvideSecondFactorAccessCode("access"); - SimulateValidResponseClientLogin(); + SimulateValidResponseClientLogin(false); EXPECT_EQ(1U, google_login_success_.size()); EXPECT_EQ(1U, google_login_failure_.size()); diff --git a/chrome/common/net/gaia/gaia_auth_consumer.h b/chrome/common/net/gaia/gaia_auth_consumer.h index b519c47..37a96cd 100644 --- a/chrome/common/net/gaia/gaia_auth_consumer.h +++ b/chrome/common/net/gaia/gaia_auth_consumer.h @@ -7,9 +7,12 @@ #pragma once #include <string> +#include <map> class GoogleServiceAuthError; +typedef std::map<std::string, std::string> UserInfoMap; + // An interface that defines the callbacks for objects that // GaiaAuthFetcher can return data to. class GaiaAuthConsumer { @@ -47,9 +50,7 @@ class GaiaAuthConsumer { int expires_in_secs) {} virtual void OnOAuthLoginTokenFailure(const GoogleServiceAuthError& error) {} - virtual void OnGetUserInfoSuccess(const std::string& key, - const std::string& value) {} - virtual void OnGetUserInfoKeyNotFound(const std::string& key) {} + virtual void OnGetUserInfoSuccess(const UserInfoMap& data) {} virtual void OnGetUserInfoFailure(const GoogleServiceAuthError& error) {} virtual void OnTokenAuthSuccess(const std::string& data) {} diff --git a/chrome/common/net/gaia/gaia_auth_fetcher.cc b/chrome/common/net/gaia/gaia_auth_fetcher.cc index ba2f6b7..66038b1 100644 --- a/chrome/common/net/gaia/gaia_auth_fetcher.cc +++ b/chrome/common/net/gaia/gaia_auth_fetcher.cc @@ -518,8 +518,7 @@ void GaiaAuthFetcher::StartOAuthLoginTokenFetch( fetcher_->Start(); } -void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid, - const std::string& info_key) { +void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid) { DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; DVLOG(1) << "Starting GetUserInfo for lsid=" << lsid; @@ -531,7 +530,6 @@ void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid, false, this)); fetch_pending_ = true; - requested_info_key_ = info_key; fetcher_->Start(); } @@ -785,21 +783,15 @@ void GaiaAuthFetcher::OnGetUserInfoFetched( const std::string& data, const net::URLRequestStatus& status, int response_code) { - using std::vector; - using std::string; - using std::pair; - if (status.is_success() && response_code == RC_REQUEST_OK) { - vector<pair<string, string> > tokens; + std::vector<std::pair<std::string, std::string> > tokens; + UserInfoMap matches; base::SplitStringIntoKeyValuePairs(data, '=', '\n', &tokens); - for (vector<pair<string, string> >::iterator i = tokens.begin(); - i != tokens.end(); ++i) { - if (i->first == requested_info_key_) { - consumer_->OnGetUserInfoSuccess(i->first, i->second); - return; - } + std::vector<std::pair<std::string, std::string> >::iterator i; + for (i = tokens.begin(); i != tokens.end(); ++i) { + matches[i->first] = i->second; } - consumer_->OnGetUserInfoKeyNotFound(requested_info_key_); + consumer_->OnGetUserInfoSuccess(matches); } else { consumer_->OnGetUserInfoFailure(GenerateAuthError(data, status)); } diff --git a/chrome/common/net/gaia/gaia_auth_fetcher.h b/chrome/common/net/gaia/gaia_auth_fetcher.h index 56bae60..27966cc 100644 --- a/chrome/common/net/gaia/gaia_auth_fetcher.h +++ b/chrome/common/net/gaia/gaia_auth_fetcher.h @@ -74,12 +74,11 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate { // called on the consumer with results. void StartOAuthLoginTokenFetch(const std::string& auth_token); - // Start a request to get a particular key from user info. + // Start a request to get user info. // GaiaAuthConsumer will be called back on the same thread when // results come back. // You can't make more than one request at a time. - void StartGetUserInfo(const std::string& lsid, - const std::string& info_key); + void StartGetUserInfo(const std::string& lsid); // Start a TokenAuth request to pre-login the user with the given credentials. void StartTokenAuth(const std::string& auth_token); @@ -292,8 +291,7 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate { // While a fetch is going on: scoped_ptr<content::URLFetcher> fetcher_; std::string request_body_; - std::string requested_service_; // Currently tracked for IssueAuthToken only - std::string requested_info_key_; // Currently tracked for GetUserInfo only + std::string requested_service_; // Currently tracked for IssueAuthToken only. bool fetch_pending_; friend class GaiaAuthFetcherTest; diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index a71bbcd..a35cada 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -34,6 +34,9 @@ const char kHomePage[] = "homepage"; // Did the user change the home page after install? const char kHomePageChanged[] = "homepage_changed"; +// Does this user have a Google+ Profile? +const char kIsGooglePlusUser[] = "is_google_plus_user"; + // Used to determine if the last session exited cleanly. Set to false when // first opened, and to true when closing. On startup if the value is false, // it means the profile didn't exit cleanly. diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 396c649..a68b7d8 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -21,6 +21,7 @@ extern const char kDefaultAppsInstalled[]; extern const char kHomePageIsNewTabPage[]; extern const char kHomePage[]; extern const char kHomePageChanged[]; +extern const char kIsGooglePlusUser[]; extern const char kSessionExitedCleanly[]; extern const char kRestoreOnStartup[]; extern const char kURLsToRestoreOnStartup[]; |