summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormlerman <mlerman@chromium.org>2014-12-07 09:34:49 -0800
committerCommit bot <commit-bot@chromium.org>2014-12-07 17:35:20 +0000
commit86ffbbf837c62778b9695f944471d055e8405716 (patch)
treeebb6ea00ef309a3fbacb61b4823eb7cf5e0622ce
parent78222454fd92c13c99ff03ae6a1255e14a2e7577 (diff)
downloadchromium_src-86ffbbf837c62778b9695f944471d055e8405716.zip
chromium_src-86ffbbf837c62778b9695f944471d055e8405716.tar.gz
chromium_src-86ffbbf837c62778b9695f944471d055e8405716.tar.bz2
The Account Tracker now collects Hosted Domain information. The Signin
Manager observes the Account Tracker, so that a new PostSignedIn method is called only after both OnSignedIn is done and the AccountTrackerService has called ClientInfo. This is used to save a hash of the user's password only when Profile Lock is available. The next CL will clean up the GAIAInfoUpdateService, ProfileDownloader and profile_window so that the hosted_domain is only acquired through the AccountTracker. (TBR of pavely@ and bartfab@ since their files only involve specifying fake signin factories for unit tests) BUG=432286 TBR=pavely@chromium.org, bartfab@chromium.org Review URL: https://codereview.chromium.org/753243003 Cr-Commit-Position: refs/heads/master@{#307188}
-rw-r--r--chrome/browser/invalidation/gcm_invalidation_bridge_unittest.cc8
-rw-r--r--chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc8
-rw-r--r--chrome/browser/profiles/profile_window.cc20
-rw-r--r--chrome/browser/services/gcm/fake_signin_manager.cc8
-rw-r--r--chrome/browser/signin/account_tracker_service_factory.cc5
-rw-r--r--chrome/browser/signin/chrome_signin_client.cc23
-rw-r--r--chrome/browser/signin/chrome_signin_client.h9
-rw-r--r--chrome/browser/signin/fake_account_tracker_service.cc17
-rw-r--r--chrome/browser/signin/fake_account_tracker_service.h5
-rw-r--r--chrome/browser/signin/fake_signin_manager.cc10
-rw-r--r--chrome/browser/signin/signin_manager_factory.cc4
-rw-r--r--chrome/browser/signin/signin_manager_unittest.cc54
-rw-r--r--chrome/browser/sync/profile_sync_auth_provider_unittest.cc8
-rw-r--r--chrome/browser/ui/webui/signin/inline_login_handler_impl.cc5
-rw-r--r--components/signin/core/browser/account_tracker_service.cc81
-rw-r--r--components/signin/core/browser/account_tracker_service.h32
-rw-r--r--components/signin/core/browser/account_tracker_service_unittest.cc56
-rw-r--r--components/signin/core/browser/signin_client.h13
-rw-r--r--components/signin/core/browser/signin_manager.cc48
-rw-r--r--components/signin/core/browser/signin_manager.h27
-rw-r--r--components/signin/core/browser/test_signin_client.cc7
-rw-r--r--components/signin/core/browser/test_signin_client.h10
-rw-r--r--components/signin/core/common/signin_pref_names.cc4
23 files changed, 361 insertions, 101 deletions
diff --git a/chrome/browser/invalidation/gcm_invalidation_bridge_unittest.cc b/chrome/browser/invalidation/gcm_invalidation_bridge_unittest.cc
index 3cb9046..2552b14 100644
--- a/chrome/browser/invalidation/gcm_invalidation_bridge_unittest.cc
+++ b/chrome/browser/invalidation/gcm_invalidation_bridge_unittest.cc
@@ -3,9 +3,13 @@
// found in the LICENSE file.
#include "base/run_loop.h"
+#include "chrome/browser/signin/account_tracker_service_factory.h"
+#include "chrome/browser/signin/chrome_signin_client_factory.h"
+#include "chrome/browser/signin/fake_account_tracker_service.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
+#include "chrome/browser/signin/test_signin_client_builder.h"
#include "chrome/test/base/testing_profile.h"
#include "components/gcm_driver/fake_gcm_driver.h"
#include "components/gcm_driver/gcm_driver.h"
@@ -54,6 +58,10 @@ class GCMInvalidationBridgeTest : public ::testing::Test {
TestingProfile::Builder builder;
builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
&BuildAutoIssuingFakeProfileOAuth2TokenService);
+ builder.AddTestingFactory(AccountTrackerServiceFactory::GetInstance(),
+ FakeAccountTrackerService::Build);
+ builder.AddTestingFactory(ChromeSigninClientFactory::GetInstance(),
+ signin::BuildTestSigninClient);
profile_ = builder.Build();
FakeProfileOAuth2TokenService* token_service =
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 c5e7f2ba..9bd3908 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
@@ -14,11 +14,15 @@
#include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/account_tracker_service_factory.h"
+#include "chrome/browser/signin/chrome_signin_client_factory.h"
+#include "chrome/browser/signin/fake_account_tracker_service.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
#include "chrome/browser/signin/fake_signin_manager.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/signin/test_signin_client_builder.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_pref_service_syncable.h"
#include "chrome/test/base/testing_profile.h"
@@ -177,6 +181,10 @@ class UserPolicySigninServiceTest : public testing::Test {
SigninManagerFake::Build);
builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
BuildFakeProfileOAuth2TokenService);
+ builder.AddTestingFactory(AccountTrackerServiceFactory::GetInstance(),
+ FakeAccountTrackerService::Build);
+ builder.AddTestingFactory(ChromeSigninClientFactory::GetInstance(),
+ signin::BuildTestSigninClient);
profile_ = builder.Build().Pass();
url_factory_.set_remove_fetcher_on_delete(true);
diff --git a/chrome/browser/profiles/profile_window.cc b/chrome/browser/profiles/profile_window.cc
index 96310bd..1b4c131 100644
--- a/chrome/browser/profiles/profile_window.cc
+++ b/chrome/browser/profiles/profile_window.cc
@@ -17,6 +17,7 @@
#include "chrome/browser/profiles/profile_avatar_icon_util.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/signin/account_reconcilor_factory.h"
+#include "chrome/browser/signin/account_tracker_service_factory.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/ui/browser.h"
@@ -27,6 +28,7 @@
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "components/signin/core/browser/account_reconcilor.h"
+#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/common/profile_management_switches.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/user_metrics.h"
@@ -364,8 +366,22 @@ bool IsLockAvailable(Profile* profile) {
if (!switches::IsNewProfileManagement())
return false;
- const std::string& hosted_domain = profile->GetPrefs()->
+ if (profile->IsGuestSession())
+ return false;
+
+ const ProfileInfoCache& cache =
+ g_browser_process->profile_manager()->GetProfileInfoCache();
+ std::string hosted_domain = profile->GetPrefs()->
GetString(prefs::kGoogleServicesHostedDomain);
+ // TODO(mlerman): After one release remove any hosted_domain reference to the
+ // pref, since all users will have this in the AccountTrackerService.
+ if (hosted_domain.empty()) {
+ AccountTrackerService* account_tracker =
+ AccountTrackerServiceFactory::GetForProfile(profile);
+ int profile_index = cache.GetIndexOfProfileWithPath(profile->GetPath());
+ hosted_domain = account_tracker->FindAccountInfoByEmail(base::UTF16ToUTF8(
+ cache.GetUserNameOfProfileAtIndex(profile_index))).hosted_domain;
+ }
// TODO(mlerman): Prohibit only users who authenticate using SAML. Until then,
// prohibited users who use hosted domains (aside from google.com).
if (hosted_domain != Profile::kNoHostedDomainFound &&
@@ -373,8 +389,6 @@ bool IsLockAvailable(Profile* profile) {
return false;
}
- const ProfileInfoCache& cache =
- g_browser_process->profile_manager()->GetProfileInfoCache();
for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) {
if (cache.ProfileIsSupervisedAtIndex(i))
return true;
diff --git a/chrome/browser/services/gcm/fake_signin_manager.cc b/chrome/browser/services/gcm/fake_signin_manager.cc
index 049b415..28ea3fd 100644
--- a/chrome/browser/services/gcm/fake_signin_manager.cc
+++ b/chrome/browser/services/gcm/fake_signin_manager.cc
@@ -7,6 +7,7 @@
#include "base/observer_list.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/account_tracker_service_factory.h"
#include "chrome/browser/signin/chrome_signin_client_factory.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/signin/core/common/signin_pref_names.h"
@@ -25,7 +26,8 @@ FakeSigninManager::FakeSigninManager(Profile* profile)
#else
: SigninManager(
ChromeSigninClientFactory::GetInstance()->GetForProfile(profile),
- ProfileOAuth2TokenServiceFactory::GetForProfile(profile)),
+ ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
+ AccountTrackerServiceFactory::GetForProfile(profile)),
#endif
profile_(profile) {
Initialize(NULL);
@@ -36,7 +38,7 @@ FakeSigninManager::~FakeSigninManager() {
void FakeSigninManager::SignIn(const std::string& username) {
SetAuthenticatedUsername(username);
- FOR_EACH_OBSERVER(Observer,
+ FOR_EACH_OBSERVER(SigninManagerBase::Observer,
observer_list_,
GoogleSigninSucceeded(username, username, std::string()));
}
@@ -47,7 +49,7 @@ void FakeSigninManager::SignOut(
const std::string username = GetAuthenticatedUsername();
ClearAuthenticatedUsername();
profile_->GetPrefs()->ClearPref(prefs::kGoogleServicesUsername);
- FOR_EACH_OBSERVER(Observer,
+ FOR_EACH_OBSERVER(SigninManagerBase::Observer,
observer_list_,
GoogleSignedOut(account_id, username));
}
diff --git a/chrome/browser/signin/account_tracker_service_factory.cc b/chrome/browser/signin/account_tracker_service_factory.cc
index 1869834..60ddfff 100644
--- a/chrome/browser/signin/account_tracker_service_factory.cc
+++ b/chrome/browser/signin/account_tracker_service_factory.cc
@@ -6,6 +6,7 @@
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/chrome_signin_client_factory.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/pref_registry/pref_registry_syncable.h"
@@ -17,6 +18,7 @@ AccountTrackerServiceFactory::AccountTrackerServiceFactory()
: BrowserContextKeyedServiceFactory(
"AccountTrackerServiceFactory",
BrowserContextDependencyManager::GetInstance()) {
+ DependsOn(ChromeSigninClientFactory::GetInstance());
DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
}
@@ -52,7 +54,6 @@ KeyedService* AccountTrackerServiceFactory::BuildServiceInstanceFor(
AccountTrackerService* service = new AccountTrackerService();
service->Initialize(
ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
- profile->GetPrefs(),
- profile->GetRequestContext());
+ ChromeSigninClientFactory::GetForProfile(profile));
return service;
}
diff --git a/chrome/browser/signin/chrome_signin_client.cc b/chrome/browser/signin/chrome_signin_client.cc
index 077f601..412f3ed 100644
--- a/chrome/browser/signin/chrome_signin_client.cc
+++ b/chrome/browser/signin/chrome_signin_client.cc
@@ -14,6 +14,7 @@
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_metrics.h"
+#include "chrome/browser/profiles/profile_window.h"
#include "chrome/browser/signin/local_auth.h"
#include "chrome/browser/signin/signin_cookie_changed_subscription.h"
#include "chrome/browser/webdata/web_data_service_factory.h"
@@ -209,15 +210,9 @@ ChromeSigninClient::AddCookieChangedCallback(
return subscription.Pass();
}
-void ChromeSigninClient::GoogleSigninSucceeded(const std::string& account_id,
- const std::string& username,
- const std::string& password) {
-#if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS)
- // Don't store password hash except for users of new profile management.
- if (switches::IsNewProfileManagement() && !password.empty())
- chrome::SetLocalAuthCredentials(profile_, password);
-#endif
-
+void ChromeSigninClient::OnSignedIn(const std::string& account_id,
+ const std::string& username,
+ const std::string& password) {
ProfileManager* profile_manager = g_browser_process->profile_manager();
ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
size_t index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
@@ -226,3 +221,13 @@ void ChromeSigninClient::GoogleSigninSucceeded(const std::string& account_id,
ProfileMetrics::UpdateReportedProfilesStatistics(profile_manager);
}
}
+
+void ChromeSigninClient::PostSignedIn(const std::string& account_id,
+ const std::string& username,
+ const std::string& password) {
+#if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS)
+ // Don't store password hash except when lock is available for the user.
+ if (!password.empty() && profiles::IsLockAvailable(profile_))
+ chrome::SetLocalAuthCredentials(profile_, password);
+#endif
+}
diff --git a/chrome/browser/signin/chrome_signin_client.h b/chrome/browser/signin/chrome_signin_client.h
index 81b4abf..3a21c0b 100644
--- a/chrome/browser/signin/chrome_signin_client.h
+++ b/chrome/browser/signin/chrome_signin_client.h
@@ -58,9 +58,12 @@ class ChromeSigninClient : public SigninClient,
const GURL& url,
const std::string& name,
const net::CookieStore::CookieChangedCallback& callback) override;
- void GoogleSigninSucceeded(const std::string& account_id,
- const std::string& username,
- const std::string& password) override;
+ void OnSignedIn(const std::string& account_id,
+ const std::string& username,
+ const std::string& password) override;
+ void PostSignedIn(const std::string& account_id,
+ const std::string& username,
+ const std::string& password) override;
private:
Profile* profile_;
diff --git a/chrome/browser/signin/fake_account_tracker_service.cc b/chrome/browser/signin/fake_account_tracker_service.cc
index 0b80661..b6ec07b 100644
--- a/chrome/browser/signin/fake_account_tracker_service.cc
+++ b/chrome/browser/signin/fake_account_tracker_service.cc
@@ -4,7 +4,9 @@
#include "chrome/browser/signin/fake_account_tracker_service.h"
+#include "base/values.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/chrome_signin_client_factory.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
@@ -15,8 +17,7 @@ KeyedService* FakeAccountTrackerService::Build(
FakeAccountTrackerService* service = new FakeAccountTrackerService();
service->Initialize(
ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
- profile->GetPrefs(),
- profile->GetRequestContext());
+ ChromeSigninClientFactory::GetForProfile(profile));
return service;
}
@@ -28,3 +29,15 @@ void FakeAccountTrackerService::StartFetchingUserInfo(
const std::string& account_id) {
// In tests, don't do actual network fetch.
}
+
+void FakeAccountTrackerService::FakeUserInfoFetchSuccess(
+ const std::string& account_id,
+ const std::string& email,
+ const std::string& gaia,
+ const std::string& hosted_domain) {
+ base::DictionaryValue user_info;
+ user_info.SetString("id", gaia);
+ user_info.SetString("email", email);
+ user_info.SetString("hd", hosted_domain);
+ SetAccountStateFromUserInfo(account_id, &user_info);
+}
diff --git a/chrome/browser/signin/fake_account_tracker_service.h b/chrome/browser/signin/fake_account_tracker_service.h
index b25a850..fe0b11a 100644
--- a/chrome/browser/signin/fake_account_tracker_service.h
+++ b/chrome/browser/signin/fake_account_tracker_service.h
@@ -20,6 +20,11 @@ class FakeAccountTrackerService : public AccountTrackerService {
public:
static KeyedService* Build(content::BrowserContext* context);
+ void FakeUserInfoFetchSuccess(const std::string& account_id,
+ const std::string& email,
+ const std::string& gaia,
+ const std::string& hosted_domain);
+
private:
FakeAccountTrackerService();
~FakeAccountTrackerService() override;
diff --git a/chrome/browser/signin/fake_signin_manager.cc b/chrome/browser/signin/fake_signin_manager.cc
index 43de553..5704738 100644
--- a/chrome/browser/signin/fake_signin_manager.cc
+++ b/chrome/browser/signin/fake_signin_manager.cc
@@ -7,6 +7,7 @@
#include "base/callback_helpers.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/account_tracker_service_factory.h"
#include "chrome/browser/signin/chrome_signin_client_factory.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
@@ -40,7 +41,8 @@ KeyedService* FakeSigninManagerBase::Build(content::BrowserContext* context) {
FakeSigninManager::FakeSigninManager(Profile* profile)
: SigninManager(
ChromeSigninClientFactory::GetInstance()->GetForProfile(profile),
- ProfileOAuth2TokenServiceFactory::GetForProfile(profile)) {}
+ ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
+ AccountTrackerServiceFactory::GetForProfile(profile)) {}
FakeSigninManager::~FakeSigninManager() {
}
@@ -60,7 +62,7 @@ void FakeSigninManager::StartSignInWithRefreshToken(
void FakeSigninManager::CompletePendingSignin() {
SetAuthenticatedUsername(GetUsernameForAuthInProgress());
set_auth_in_progress(std::string());
- FOR_EACH_OBSERVER(Observer,
+ FOR_EACH_OBSERVER(SigninManagerBase::Observer,
observer_list_,
GoogleSigninSucceeded(authenticated_username_,
authenticated_username_,
@@ -75,7 +77,9 @@ void FakeSigninManager::SignIn(const std::string& username,
}
void FakeSigninManager::FailSignin(const GoogleServiceAuthError& error) {
- FOR_EACH_OBSERVER(Observer, observer_list_, GoogleSigninFailed(error));
+ FOR_EACH_OBSERVER(SigninManagerBase::Observer,
+ observer_list_,
+ GoogleSigninFailed(error));
}
void FakeSigninManager::SignOut(
diff --git a/chrome/browser/signin/signin_manager_factory.cc b/chrome/browser/signin/signin_manager_factory.cc
index 499fbc4..0774902 100644
--- a/chrome/browser/signin/signin_manager_factory.cc
+++ b/chrome/browser/signin/signin_manager_factory.cc
@@ -131,7 +131,9 @@ KeyedService* SigninManagerFactory::BuildServiceInstanceFor(
service = new SigninManagerBase(client);
#else
service = new SigninManager(
- client, ProfileOAuth2TokenServiceFactory::GetForProfile(profile));
+ client,
+ ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
+ AccountTrackerServiceFactory::GetForProfile(profile));
#endif
service->Initialize(g_browser_process->local_state());
FOR_EACH_OBSERVER(Observer, observer_list_, SigninManagerCreated(service));
diff --git a/chrome/browser/signin/signin_manager_unittest.cc b/chrome/browser/signin/signin_manager_unittest.cc
index f1bee6f..500c1d6 100644
--- a/chrome/browser/signin/signin_manager_unittest.cc
+++ b/chrome/browser/signin/signin_manager_unittest.cc
@@ -16,7 +16,9 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/prefs/browser_prefs.h"
+#include "chrome/browser/signin/account_tracker_service_factory.h"
#include "chrome/browser/signin/chrome_signin_client_factory.h"
+#include "chrome/browser/signin/fake_account_tracker_service.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
@@ -49,7 +51,8 @@ KeyedService* SigninManagerBuild(content::BrowserContext* context) {
Profile* profile = static_cast<Profile*>(context);
service = new SigninManager(
ChromeSigninClientFactory::GetInstance()->GetForProfile(profile),
- ProfileOAuth2TokenServiceFactory::GetForProfile(profile));
+ ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
+ AccountTrackerServiceFactory::GetForProfile(profile));
service->Initialize(NULL);
return service;
}
@@ -106,11 +109,11 @@ class SigninManagerTest : public testing::Test {
signin::BuildTestSigninClient);
builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
SigninManagerBuild);
+ builder.AddTestingFactory(AccountTrackerServiceFactory::GetInstance(),
+ FakeAccountTrackerService::Build);
profile_ = builder.Build();
- static_cast<TestSigninClient*>(
- ChromeSigninClientFactory::GetInstance()->GetForProfile(profile()))->
- SetURLRequestContext(profile_->GetRequestContext());
+ signin_client()->SetURLRequestContext(profile_->GetRequestContext());
}
void TearDown() override {
@@ -134,6 +137,11 @@ class SigninManagerTest : public testing::Test {
TestingProfile* profile() { return profile_.get(); }
+ TestSigninClient* signin_client() {
+ return static_cast<TestSigninClient*>(
+ ChromeSigninClientFactory::GetInstance()->GetForProfile(profile()));
+ }
+
// Sets up the signin manager as a service if other code will try to get it as
// a PKS.
void SetUpSigninManagerAsService() {
@@ -149,7 +157,8 @@ class SigninManagerTest : public testing::Test {
DCHECK(!manager_);
naked_manager_.reset(new SigninManager(
ChromeSigninClientFactory::GetInstance()->GetForProfile(profile()),
- ProfileOAuth2TokenServiceFactory::GetForProfile(profile())));
+ ProfileOAuth2TokenServiceFactory::GetForProfile(profile()),
+ AccountTrackerServiceFactory::GetForProfile(profile())));
manager_ = naked_manager_.get();
manager_->AddObserver(&test_observer_);
@@ -232,6 +241,41 @@ TEST_F(SigninManagerTest, SignInWithRefreshTokenCallbackComplete) {
EXPECT_EQ(oauth_tokens_fetched_[0], "rt1");
}
+TEST_F(SigninManagerTest, SignInWithRefreshTokenCallsPostSignout) {
+ SetUpSigninManagerAsService();
+ EXPECT_FALSE(manager_->IsAuthenticated());
+
+ std::string gaia_id = "12345";
+ std::string email = "user@google.com";
+
+ FakeAccountTrackerService* account_tracker_service =
+ static_cast<FakeAccountTrackerService*>(
+ AccountTrackerServiceFactory::GetForProfile(profile()));
+ account_tracker_service->SeedAccountInfo(gaia_id, email);
+ std::string account_id = account_tracker_service->PickAccountIdForAccount(
+ gaia_id, email);
+
+ ASSERT_TRUE(signin_client()->get_signed_in_password().empty());
+
+ manager_->StartSignInWithRefreshToken(
+ "rt1",
+ email,
+ "password",
+ SigninManager::OAuthTokenFetchedCallback());
+
+ // PostSignedIn is not called until the AccountTrackerService returns.
+ ASSERT_EQ("", signin_client()->get_signed_in_password());
+
+ account_tracker_service->FakeUserInfoFetchSuccess(
+ account_id, email, gaia_id, "google.com");
+
+ // AccountTracker and SigninManager are both done and PostSignedIn was called.
+ ASSERT_EQ("password", signin_client()->get_signed_in_password());
+
+ ExpectSignInWithRefreshTokenSuccess();
+
+}
+
TEST_F(SigninManagerTest, SignOut) {
SetUpSigninManagerAsService();
manager_->StartSignInWithRefreshToken(
diff --git a/chrome/browser/sync/profile_sync_auth_provider_unittest.cc b/chrome/browser/sync/profile_sync_auth_provider_unittest.cc
index c216090e..595756c 100644
--- a/chrome/browser/sync/profile_sync_auth_provider_unittest.cc
+++ b/chrome/browser/sync/profile_sync_auth_provider_unittest.cc
@@ -3,9 +3,13 @@
// found in the LICENSE file.
#include "base/run_loop.h"
+#include "chrome/browser/signin/account_tracker_service_factory.h"
+#include "chrome/browser/signin/chrome_signin_client_factory.h"
+#include "chrome/browser/signin/fake_account_tracker_service.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
+#include "chrome/browser/signin/test_signin_client_builder.h"
#include "chrome/browser/sync/profile_sync_auth_provider.h"
#include "chrome/test/base/testing_profile.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
@@ -26,6 +30,10 @@ class ProfileSyncAuthProviderTest : public ::testing::Test {
TestingProfile::Builder builder;
builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
&BuildAutoIssuingFakeProfileOAuth2TokenService);
+ builder.AddTestingFactory(AccountTrackerServiceFactory::GetInstance(),
+ FakeAccountTrackerService::Build);
+ builder.AddTestingFactory(ChromeSigninClientFactory::GetInstance(),
+ signin::BuildTestSigninClient);
profile_ = builder.Build();
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
index 6c45aa9..ab7b8f1 100644
--- a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
@@ -12,6 +12,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_window.h"
#include "chrome/browser/signin/about_signin_internals_factory.h"
#include "chrome/browser/signin/account_tracker_service_factory.h"
#include "chrome/browser/signin/chrome_signin_client_factory.h"
@@ -135,7 +136,9 @@ void InlineSigninHelper::OnClientOAuthSuccess(const ClientOAuthResult& result) {
SigninManagerFactory::GetForProfile(profile_)->GetAuthenticatedUsername();
if (gaia::AreEmailsSame(email_, primary_email) &&
source == signin::SOURCE_REAUTH &&
- switches::IsNewProfileManagement() && !password_.empty()) {
+ switches::IsNewProfileManagement() &&
+ !password_.empty() &&
+ profiles::IsLockAvailable(profile_)) {
chrome::SetLocalAuthCredentials(profile_, password_);
}
diff --git a/components/signin/core/browser/account_tracker_service.cc b/components/signin/core/browser/account_tracker_service.cc
index 5d09b40..ecbeb29 100644
--- a/components/signin/core/browser/account_tracker_service.cc
+++ b/components/signin/core/browser/account_tracker_service.cc
@@ -6,16 +6,15 @@
#include "base/debug/trace_event.h"
#include "base/logging.h"
-#include "base/prefs/pref_service.h"
#include "base/prefs/scoped_user_pref_update.h"
#include "base/profiler/scoped_tracker.h"
#include "base/strings/utf_string_conversions.h"
+#include "components/signin/core/browser/signin_client.h"
#include "components/signin/core/browser/signin_manager.h"
#include "components/signin/core/common/signin_pref_names.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/gaia_oauth_client.h"
-#include "google_apis/gaia/oauth2_token_service.h"
#include "net/url_request/url_request_context_getter.h"
namespace {
@@ -23,9 +22,13 @@ namespace {
const char kAccountKeyPath[] = "account_id";
const char kAccountEmailPath[] = "email";
const char kAccountGaiaPath[] = "gaia";
+const char kAccountHostedDomainPath[] = "hd";
}
+// This must be a string which can never be a valid domain.
+const char AccountTrackerService::kNoHostedDomainFound[] = "NO_HOSTED_DOMAIN";
+
class AccountInfoFetcher : public OAuth2TokenService::Consumer,
public gaia::GaiaOAuthClient::Delegate {
public:
@@ -146,12 +149,20 @@ void AccountInfoFetcher::OnNetworkError(int response_code) {
service_->OnUserInfoFetchFailure(this);
}
+AccountTrackerService::AccountInfo::AccountInfo() {}
+AccountTrackerService::AccountInfo::~AccountInfo() {}
+
+bool AccountTrackerService::AccountInfo::IsValid() {
+ return account_id.empty() || email.empty() || gaia.empty() ||
+ hosted_domain.empty();
+}
+
const char AccountTrackerService::kAccountInfoPref[] = "account_info";
AccountTrackerService::AccountTrackerService()
: token_service_(NULL),
- pref_service_(NULL),
+ signin_client_(NULL),
shutdown_called_(false) {
}
@@ -161,15 +172,13 @@ AccountTrackerService::~AccountTrackerService() {
void AccountTrackerService::Initialize(
OAuth2TokenService* token_service,
- PrefService* pref_service,
- net::URLRequestContextGetter* request_context_getter) {
+ SigninClient* signin_client) {
DCHECK(token_service);
DCHECK(!token_service_);
- DCHECK(pref_service);
- DCHECK(!pref_service_);
+ DCHECK(signin_client);
+ DCHECK(!signin_client_);
token_service_ = token_service;
- pref_service_ = pref_service;
- request_context_getter_ = request_context_getter;
+ signin_client_ = signin_client;
token_service_->AddObserver(this);
LoadFromPrefs();
LoadFromTokenService();
@@ -247,7 +256,7 @@ AccountTrackerService::FindAccountInfoByEmail(
AccountTrackerService::AccountIdMigrationState
AccountTrackerService::GetMigrationState() {
- return GetMigrationState(pref_service_);
+ return GetMigrationState(signin_client_->GetPrefs());
}
// static
@@ -273,7 +282,7 @@ void AccountTrackerService::OnRefreshTokenAvailable(
StartTrackingAccount(account_id);
AccountState& state = accounts_[account_id];
- if (state.info.gaia.empty())
+ if (state.info.IsValid())
StartFetchingUserInfo(account_id);
}
@@ -294,6 +303,12 @@ void AccountTrackerService::NotifyAccountUpdated(const AccountState& state) {
Observer, observer_list_, OnAccountUpdated(state.info));
}
+void AccountTrackerService::NotifyAccountUpdateFailed(
+ const std::string& account_id) {
+ FOR_EACH_OBSERVER(
+ Observer, observer_list_, OnAccountUpdateFailed(account_id));
+}
+
void AccountTrackerService::NotifyAccountRemoved(const AccountState& state) {
DCHECK(!state.info.gaia.empty());
FOR_EACH_OBSERVER(
@@ -340,18 +355,16 @@ void AccountTrackerService::StartFetchingUserInfo(
DVLOG(1) << "StartFetching " << account_id;
AccountInfoFetcher* fetcher =
new AccountInfoFetcher(token_service_,
- request_context_getter_.get(),
+ signin_client_->GetURLRequestContext(),
this,
account_id);
user_info_requests_[account_id] = fetcher;
fetcher->Start();
}
-void AccountTrackerService::OnUserInfoFetchSuccess(
- AccountInfoFetcher* fetcher,
+void AccountTrackerService::SetAccountStateFromUserInfo(
+ const std::string& account_id,
const base::DictionaryValue* user_info) {
- const std::string& account_id = fetcher->account_id();
- DCHECK(ContainsKey(accounts_, account_id));
AccountState& state = accounts_[account_id];
std::string gaia_id;
@@ -361,15 +374,32 @@ void AccountTrackerService::OnUserInfoFetchSuccess(
state.info.gaia = gaia_id;
state.info.email = email;
+ std::string hosted_domain;
+ if (user_info->GetString("hd", &hosted_domain) && !hosted_domain.empty()) {
+ state.info.hosted_domain = hosted_domain;
+ } else {
+ state.info.hosted_domain = kNoHostedDomainFound;
+ }
+
NotifyAccountUpdated(state);
SaveToPrefs(state);
}
+}
+
+void AccountTrackerService::OnUserInfoFetchSuccess(
+ AccountInfoFetcher* fetcher,
+ const base::DictionaryValue* user_info) {
+ const std::string& account_id = fetcher->account_id();
+ DCHECK(ContainsKey(accounts_, account_id));
+
+ SetAccountStateFromUserInfo(account_id, user_info);
DeleteFetcher(fetcher);
}
void AccountTrackerService::OnUserInfoFetchFailure(
AccountInfoFetcher* fetcher) {
LOG(WARNING) << "Failed to get UserInfo for " << fetcher->account_id();
+ NotifyAccountUpdateFailed(fetcher->account_id());
DeleteFetcher(fetcher);
// TODO(rogerta): figure out when to retry.
}
@@ -384,7 +414,8 @@ void AccountTrackerService::DeleteFetcher(AccountInfoFetcher* fetcher) {
}
void AccountTrackerService::LoadFromPrefs() {
- const base::ListValue* list = pref_service_->GetList(kAccountInfoPref);
+ const base::ListValue* list =
+ signin_client_->GetPrefs()->GetList(kAccountInfoPref);
for (size_t i = 0; i < list->GetSize(); ++i) {
const base::DictionaryValue* dict;
if (list->GetDictionary(i, &dict)) {
@@ -398,8 +429,9 @@ void AccountTrackerService::LoadFromPrefs() {
state.info.gaia = base::UTF16ToUTF8(value);
if (dict->GetString(kAccountEmailPath, &value))
state.info.email = base::UTF16ToUTF8(value);
-
- if (!state.info.gaia.empty())
+ if (dict->GetString(kAccountHostedDomainPath, &value))
+ state.info.hosted_domain = base::UTF16ToUTF8(value);
+ if (!state.info.IsValid())
NotifyAccountUpdated(state);
}
}
@@ -407,12 +439,12 @@ void AccountTrackerService::LoadFromPrefs() {
}
void AccountTrackerService::SaveToPrefs(const AccountState& state) {
- if (!pref_service_)
+ if (!signin_client_->GetPrefs())
return;
base::DictionaryValue* dict = NULL;
base::string16 account_id_16 = base::UTF8ToUTF16(state.info.account_id);
- ListPrefUpdate update(pref_service_, kAccountInfoPref);
+ ListPrefUpdate update(signin_client_->GetPrefs(), kAccountInfoPref);
for(size_t i = 0; i < update->GetSize(); ++i, dict = NULL) {
if (update->GetDictionary(i, &dict)) {
base::string16 value;
@@ -429,14 +461,15 @@ void AccountTrackerService::SaveToPrefs(const AccountState& state) {
dict->SetString(kAccountEmailPath, state.info.email);
dict->SetString(kAccountGaiaPath, state.info.gaia);
+ dict->SetString(kAccountHostedDomainPath, state.info.hosted_domain);
}
void AccountTrackerService::RemoveFromPrefs(const AccountState& state) {
- if (!pref_service_)
+ if (!signin_client_->GetPrefs())
return;
base::string16 account_id_16 = base::UTF8ToUTF16(state.info.account_id);
- ListPrefUpdate update(pref_service_, kAccountInfoPref);
+ ListPrefUpdate update(signin_client_->GetPrefs(), kAccountInfoPref);
for(size_t i = 0; i < update->GetSize(); ++i) {
base::DictionaryValue* dict = NULL;
if (update->GetDictionary(i, &dict)) {
@@ -460,7 +493,7 @@ void AccountTrackerService::LoadFromTokenService() {
std::string AccountTrackerService::PickAccountIdForAccount(
const std::string& gaia,
const std::string& email) {
- return PickAccountIdForAccount(pref_service_, gaia, email);
+ return PickAccountIdForAccount(signin_client_->GetPrefs(), gaia, email);
}
// static
diff --git a/components/signin/core/browser/account_tracker_service.h b/components/signin/core/browser/account_tracker_service.h
index c65ed01..f1790ad 100644
--- a/components/signin/core/browser/account_tracker_service.h
+++ b/components/signin/core/browser/account_tracker_service.h
@@ -16,6 +16,7 @@
class AccountInfoFetcher;
class OAuth2TokenService;
class PrefService;
+class SigninClient;
namespace base {
class DictionaryValue;
@@ -30,13 +31,24 @@ class AccountTrackerService : public KeyedService,
// tracked by this service.
static const char kAccountInfoPref[];
+ // TODO(mlerman): Remove all references to Profile::kNoHostedDomainFound in
+ // favour of this.
+ // Value representing no hosted domain in the kProfileHostedDomain preference.
+ static const char kNoHostedDomainFound[];
+
// Information about a specific account.
struct AccountInfo {
+ AccountInfo();
+ ~AccountInfo();
+
std::string account_id; // The account ID used by OAuth2TokenService.
std::string gaia;
std::string email;
+ std::string hosted_domain;
// TODO(rogerta): eventually this structure will include other information
// about the account, like full name, profile picture URL, etc.
+
+ bool IsValid();
};
// Clients of AccountTrackerService can implement this interface and register
@@ -44,8 +56,9 @@ class AccountTrackerService : public KeyedService,
class Observer {
public:
virtual ~Observer() {}
- virtual void OnAccountUpdated(const AccountInfo& info) = 0;
- virtual void OnAccountRemoved(const AccountInfo& info) = 0;
+ virtual void OnAccountUpdated(const AccountInfo& info) {}
+ virtual void OnAccountUpdateFailed(const std::string& account_id) {}
+ virtual void OnAccountRemoved(const AccountInfo& info) {}
};
// Possible values for the kAccountIdMigrationState preference.
@@ -64,9 +77,11 @@ class AccountTrackerService : public KeyedService,
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
+ // Take a SigninClient rather than a PrefService and a URLRequestContextGetter
+ // since RequestContext cannot be created at startup.
+ // (see http://crbug.com/171406)
void Initialize(OAuth2TokenService* token_service,
- PrefService* pref_service,
- net::URLRequestContextGetter* request_context_getter);
+ SigninClient* signin_client);
// Returns the list of known accounts and for which gaia IDs
// have been fetched.
@@ -94,6 +109,11 @@ class AccountTrackerService : public KeyedService,
AccountIdMigrationState GetMigrationState();
static AccountIdMigrationState GetMigrationState(PrefService* pref_service);
+ protected:
+ // Available to be called in tests.
+ void SetAccountStateFromUserInfo(const std::string& account_id,
+ const base::DictionaryValue* user_info);
+
private:
friend class AccountInfoFetcher;
@@ -111,6 +131,7 @@ class AccountTrackerService : public KeyedService,
};
void NotifyAccountUpdated(const AccountState& state);
+ void NotifyAccountUpdateFailed(const std::string& account_id);
void NotifyAccountRemoved(const AccountState& state);
void StartTrackingAccount(const std::string& account_id);
@@ -128,8 +149,7 @@ class AccountTrackerService : public KeyedService,
void LoadFromTokenService();
OAuth2TokenService* token_service_; // Not owned.
- PrefService* pref_service_; // Not owned.
- scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
+ SigninClient* signin_client_; // Not owned.
std::map<std::string, AccountInfoFetcher*> user_info_requests_;
std::map<std::string, AccountState> accounts_;
ObserverList<Observer> observer_list_;
diff --git a/components/signin/core/browser/account_tracker_service_unittest.cc b/components/signin/core/browser/account_tracker_service_unittest.cc
index 356f06f..c990b1a 100644
--- a/components/signin/core/browser/account_tracker_service_unittest.cc
+++ b/components/signin/core/browser/account_tracker_service_unittest.cc
@@ -10,6 +10,7 @@
#include "base/prefs/testing_pref_service.h"
#include "base/strings/stringprintf.h"
#include "components/signin/core/browser/account_tracker_service.h"
+#include "components/signin/core/browser/test_signin_client.h"
#include "components/signin/core/common/signin_pref_names.h"
#include "google_apis/gaia/fake_oauth2_token_service.h"
#include "google_apis/gaia/gaia_oauth_client.h"
@@ -202,12 +203,14 @@ class AccountTrackerServiceTest : public testing::Test {
pref_service_.registry()->RegisterIntegerPref(
prefs::kAccountIdMigrationState,
AccountTrackerService::MIGRATION_NOT_STARTED);
+ signin_client_.reset(new TestSigninClient(&pref_service_));
+ signin_client_.get()->SetURLRequestContext(
+ new net::TestURLRequestContextGetter(
+ message_loop_.message_loop_proxy()));
account_tracker_.reset(new AccountTrackerService());
account_tracker_->Initialize(fake_oauth2_token_service_.get(),
- &pref_service_,
- new net::TestURLRequestContextGetter(
- message_loop_.message_loop_proxy()));
+ signin_client_.get());
account_tracker_->AddObserver(&observer_);
}
@@ -231,9 +234,10 @@ class AccountTrackerServiceTest : public testing::Test {
}
std::string GenerateValidTokenInfoResponse(const std::string& account_id) {
- return base::StringPrintf("{\"id\": \"%s\", \"email\": \"%s\"}",
- AccountIdToGaiaId(account_id).c_str(),
- AccountIdToEmail(account_id).c_str());
+ return base::StringPrintf(
+ "{\"id\": \"%s\", \"email\": \"%s\", \"hd\": \"\"}",
+ AccountIdToGaiaId(account_id).c_str(),
+ AccountIdToEmail(account_id).c_str());
}
void ReturnOAuthUrlFetchSuccess(const std::string& account_id);
@@ -246,6 +250,7 @@ class AccountTrackerServiceTest : public testing::Test {
return fake_oauth2_token_service_.get();
}
TestingPrefServiceSimple* pref_service() { return &pref_service_; }
+ SigninClient* signin_client() { return signin_client_.get(); }
private:
void ReturnOAuthUrlFetchResults(int fetcher_id,
@@ -258,6 +263,7 @@ class AccountTrackerServiceTest : public testing::Test {
TestingPrefServiceSimple pref_service_;
scoped_ptr<AccountTrackerService> account_tracker_;
AccountTrackerObserver observer_;
+ scoped_ptr<TestSigninClient> signin_client_;
};
void AccountTrackerServiceTest::ReturnOAuthUrlFetchResults(
@@ -326,15 +332,23 @@ TEST_F(AccountTrackerServiceTest, TokenAvailable_UserInfoFailed) {
ASSERT_TRUE(observer()->CheckEvents());
}
+TEST_F(AccountTrackerServiceTest, TokenAvailableTwice_UserInfoOnce) {
+ SimulateTokenAvailable("alpha");
+ ReturnOAuthUrlFetchSuccess("alpha");
+ ASSERT_TRUE(account_tracker()->IsAllUserInfoFetched());
+ ASSERT_TRUE(observer()->CheckEvents(TrackingEvent(UPDATED, "alpha")));
+
+ SimulateTokenAvailable("alpha");
+ ASSERT_TRUE(account_tracker()->IsAllUserInfoFetched());
+ ASSERT_TRUE(observer()->CheckEvents());
+}
+
TEST_F(AccountTrackerServiceTest, TokenAlreadyExists) {
SimulateTokenAvailable("alpha");
AccountTrackerService tracker;
AccountTrackerObserver observer;
tracker.AddObserver(&observer);
- tracker.Initialize(token_service(),
- pref_service(),
- new net::TestURLRequestContextGetter(
- message_loop()->message_loop_proxy()));
+ tracker.Initialize(token_service(), signin_client());
ASSERT_FALSE(tracker.IsAllUserInfoFetched());
ASSERT_TRUE(observer.CheckEvents());
tracker.RemoveObserver(&observer);
@@ -377,12 +391,18 @@ TEST_F(AccountTrackerServiceTest, GetAccounts) {
EXPECT_EQ("alpha", infos[0].account_id);
EXPECT_EQ(AccountIdToGaiaId("alpha"), infos[0].gaia);
EXPECT_EQ(AccountIdToEmail("alpha"), infos[0].email);
+ EXPECT_EQ(AccountTrackerService::kNoHostedDomainFound,
+ infos[0].hosted_domain);
EXPECT_EQ("beta", infos[1].account_id);
EXPECT_EQ(AccountIdToGaiaId("beta"), infos[1].gaia);
EXPECT_EQ(AccountIdToEmail("beta"), infos[1].email);
+ EXPECT_EQ(AccountTrackerService::kNoHostedDomainFound,
+ infos[1].hosted_domain);
EXPECT_EQ("gamma", infos[2].account_id);
EXPECT_EQ(AccountIdToGaiaId("gamma"), infos[2].gaia);
EXPECT_EQ(AccountIdToEmail("gamma"), infos[2].email);
+ EXPECT_EQ(AccountTrackerService::kNoHostedDomainFound,
+ infos[2].hosted_domain);
}
TEST_F(AccountTrackerServiceTest, GetAccountInfo_Empty) {
@@ -408,6 +428,7 @@ TEST_F(AccountTrackerServiceTest, GetAccountInfo_TokenAvailable_UserInfo) {
ASSERT_EQ("alpha", info.account_id);
ASSERT_EQ(AccountIdToGaiaId("alpha"), info.gaia);
ASSERT_EQ(AccountIdToEmail("alpha"), info.email);
+ ASSERT_EQ(AccountTrackerService::kNoHostedDomainFound, info.hosted_domain);
}
TEST_F(AccountTrackerServiceTest, FindAccountInfoByGaiaId) {
@@ -453,10 +474,7 @@ TEST_F(AccountTrackerServiceTest, Persistence) {
// to be saved to persistence.
{
AccountTrackerService tracker;
- tracker.Initialize(token_service(),
- pref_service(),
- new net::TestURLRequestContextGetter(
- message_loop()->message_loop_proxy()));
+ tracker.Initialize(token_service(), signin_client());
SimulateTokenAvailable("alpha");
ReturnOAuthUrlFetchSuccess("alpha");
SimulateTokenAvailable("beta");
@@ -469,10 +487,7 @@ TEST_F(AccountTrackerServiceTest, Persistence) {
{
AccountTrackerService tracker;
tracker.AddObserver(observer());
- tracker.Initialize(token_service(),
- pref_service(),
- new net::TestURLRequestContextGetter(
- message_loop()->message_loop_proxy()));
+ tracker.Initialize(token_service(), signin_client());
ASSERT_TRUE(observer()->CheckEvents(TrackingEvent(UPDATED, "alpha"),
TrackingEvent(UPDATED, "beta")));
@@ -495,10 +510,7 @@ TEST_F(AccountTrackerServiceTest, Persistence) {
// persistence.
{
AccountTrackerService tracker;
- tracker.Initialize(token_service(),
- pref_service(),
- new net::TestURLRequestContextGetter(
- message_loop()->message_loop_proxy()));
+ tracker.Initialize(token_service(), signin_client());
std::vector<AccountTrackerService::AccountInfo> infos =
tracker.GetAccounts();
diff --git a/components/signin/core/browser/signin_client.h b/components/signin/core/browser/signin_client.h
index 282b31c..c8f8a4d 100644
--- a/components/signin/core/browser/signin_client.h
+++ b/components/signin/core/browser/signin_client.h
@@ -80,10 +80,15 @@ class SigninClient : public KeyedService {
const std::string& name,
const net::CookieStore::CookieChangedCallback& callback) = 0;
- // Called when Google signin has succeeded.
- virtual void GoogleSigninSucceeded(const std::string& account_id,
- const std::string& username,
- const std::string& password) {}
+ // Called after Google signin has succeeded.
+ virtual void OnSignedIn(const std::string& account_id,
+ const std::string& username,
+ const std::string& password) {}
+
+ // Called after Google signin has succeeded and GetUserInfo has returned.
+ virtual void PostSignedIn(const std::string& account_id,
+ const std::string& username,
+ const std::string& password) {}
virtual void SetSigninProcess(int host_id) = 0;
virtual void ClearSigninProcess() = 0;
diff --git a/components/signin/core/browser/signin_manager.cc b/components/signin/core/browser/signin_manager.cc
index 8376f2e..5fe774d 100644
--- a/components/signin/core/browser/signin_manager.cc
+++ b/components/signin/core/browser/signin_manager.cc
@@ -60,12 +60,14 @@ bool SigninManager::IsWebBasedSigninFlowURL(const GURL& url) {
}
SigninManager::SigninManager(SigninClient* client,
- ProfileOAuth2TokenService* token_service)
+ ProfileOAuth2TokenService* token_service,
+ AccountTrackerService* account_tracker_service)
: SigninManagerBase(client),
prohibit_signout_(false),
type_(SIGNIN_TYPE_NONE),
client_(client),
token_service_(token_service),
+ account_tracker_service_(account_tracker_service),
weak_pointer_factory_(this) {}
void SigninManager::AddMergeSessionObserver(
@@ -122,6 +124,8 @@ bool SigninManager::PrepareForSignin(SigninType type,
type_ = type;
possibly_invalid_username_.assign(username);
password_.assign(password);
+ signin_manager_signed_in_ = false;
+ user_info_fetched_by_account_tracker_ = false;
NotifyDiagnosticsObservers(SIGNIN_TYPE, SigninTypeToString(type));
return true;
}
@@ -170,7 +174,9 @@ void SigninManager::ClearTransientSigninData() {
void SigninManager::HandleAuthError(const GoogleServiceAuthError& error) {
ClearTransientSigninData();
- FOR_EACH_OBSERVER(Observer, observer_list_, GoogleSigninFailed(error));
+ FOR_EACH_OBSERVER(SigninManagerBase::Observer,
+ observer_list_,
+ GoogleSigninFailed(error));
}
void SigninManager::SignOut(
@@ -229,7 +235,7 @@ void SigninManager::SignOut(
<< "IsSigninAllowed: " << IsSigninAllowed();
token_service_->RevokeAllCredentials();
- FOR_EACH_OBSERVER(Observer,
+ FOR_EACH_OBSERVER(SigninManagerBase::Observer,
observer_list_,
GoogleSignedOut(account_id, username));
}
@@ -261,9 +267,12 @@ void SigninManager::Initialize(PrefService* local_state) {
InitTokenService();
account_id_helper_.reset(
new SigninAccountIdHelper(client_, token_service_, this));
+
+ account_tracker_service_->AddObserver(this);
}
void SigninManager::Shutdown() {
+ account_tracker_service_->RemoveObserver(this);
if (merge_session_helper_)
merge_session_helper_->CancelAll();
@@ -374,23 +383,46 @@ void SigninManager::OnSignedIn(const std::string& username) {
base::Time::Now().ToInternalValue());
SetAuthenticatedUsername(username);
possibly_invalid_username_.clear();
+ signin_manager_signed_in_ = true;
FOR_EACH_OBSERVER(
- Observer,
+ SigninManagerBase::Observer,
observer_list_,
GoogleSigninSucceeded(GetAuthenticatedAccountId(),
GetAuthenticatedUsername(),
password_));
- client_->GoogleSigninSucceeded(GetAuthenticatedAccountId(),
- GetAuthenticatedUsername(),
- password_);
+ client_->OnSignedIn(GetAuthenticatedAccountId(),
+ GetAuthenticatedUsername(),
+ password_);
signin_metrics::LogSigninProfile(client_->IsFirstRun(),
client_->GetInstallDate());
- password_.clear(); // Don't need it anymore.
DisableOneClickSignIn(client_->GetPrefs()); // Don't ever offer again.
+
+ PostSignedIn();
+}
+
+void SigninManager::PostSignedIn() {
+ if (!signin_manager_signed_in_ || !user_info_fetched_by_account_tracker_)
+ return;
+
+ client_->PostSignedIn(GetAuthenticatedAccountId(),
+ GetAuthenticatedUsername(),
+ password_);
+ password_.clear();
+}
+
+void SigninManager::OnAccountUpdated(
+ const AccountTrackerService::AccountInfo& info) {
+ user_info_fetched_by_account_tracker_ = true;
+ PostSignedIn();
+}
+
+void SigninManager::OnAccountUpdateFailed(const std::string& account_id) {
+ user_info_fetched_by_account_tracker_ = true;
+ PostSignedIn();
}
void SigninManager::ProhibitSignout(bool prohibit_signout) {
diff --git a/components/signin/core/browser/signin_manager.h b/components/signin/core/browser/signin_manager.h
index 57f3813..04b645a 100644
--- a/components/signin/core/browser/signin_manager.h
+++ b/components/signin/core/browser/signin_manager.h
@@ -32,6 +32,7 @@
#include "base/prefs/pref_change_registrar.h"
#include "base/prefs/pref_member.h"
#include "components/keyed_service/core/keyed_service.h"
+#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/signin_internals_util.h"
#include "components/signin/core/browser/signin_manager_base.h"
#include "components/signin/core/browser/signin_metrics.h"
@@ -44,7 +45,8 @@ class ProfileOAuth2TokenService;
class SigninAccountIdHelper;
class SigninClient;
-class SigninManager : public SigninManagerBase {
+class SigninManager : public SigninManagerBase,
+ public AccountTrackerService::Observer {
public:
// The callback invoked once the OAuth token has been fetched during signin,
// but before the profile transitions to the "signed-in" state. This allows
@@ -63,7 +65,9 @@ class SigninManager : public SigninManagerBase {
// OneClickSigninHelper.
static const char kChromeSigninEffectiveSite[];
- SigninManager(SigninClient* client, ProfileOAuth2TokenService* token_service);
+ SigninManager(SigninClient* client,
+ ProfileOAuth2TokenService* token_service,
+ AccountTrackerService* account_tracker_service);
~SigninManager() override;
// Returns true if the username is allowed based on the policy string.
@@ -162,6 +166,15 @@ class SigninManager : public SigninManagerBase {
// a sign-in success notification.
void OnSignedIn(const std::string& username);
+ // Waits for the AccountTrackerService, then sends GoogleSigninSucceeded to
+ // the client and clears the local password.
+ void PostSignedIn();
+
+ // AccountTrackerService::Observer implementation.
+ void OnAccountUpdated(const AccountTrackerService::AccountInfo& info)
+ override;
+ void OnAccountUpdateFailed(const std::string& account_id) override;
+
// Called when a new request to re-authenticate a user is in progress.
// Will clear in memory data but leaves the db as such so when the browser
// restarts we can use the old token(which might throw a password error).
@@ -199,6 +212,10 @@ class SigninManager : public SigninManagerBase {
// outlive this object.
ProfileOAuth2TokenService* token_service_;
+ // The AccountTrackerService instance associated with this object. Must
+ // outlive this object.
+ AccountTrackerService* account_tracker_service_;
+
// Helper object to listen for changes to signin preferences stored in non-
// profile-specific local prefs (like kGoogleServicesUsernamePattern).
PrefChangeRegistrar local_state_pref_registrar_;
@@ -211,6 +228,12 @@ class SigninManager : public SigninManagerBase {
base::WeakPtrFactory<SigninManager> weak_pointer_factory_;
+ // Two gate conditions for when PostSignedIn should be called. Verify
+ // that the SigninManager has reached OnSignedIn() and the AccountTracker
+ // has completed calling GetUserInfo.
+ bool signin_manager_signed_in_;
+ bool user_info_fetched_by_account_tracker_;
+
DISALLOW_COPY_AND_ASSIGN(SigninManager);
};
diff --git a/components/signin/core/browser/test_signin_client.cc b/components/signin/core/browser/test_signin_client.cc
index 68b32df..6c16931 100644
--- a/components/signin/core/browser/test_signin_client.cc
+++ b/components/signin/core/browser/test_signin_client.cc
@@ -45,7 +45,12 @@ std::string TestSigninClient::GetSigninScopedDeviceId() {
return std::string();
}
-void TestSigninClient::OnSignedOut() {
+void TestSigninClient::OnSignedOut() {}
+
+void TestSigninClient::PostSignedIn(const std::string& account_id,
+ const std::string& username,
+ const std::string& password) {
+ signed_in_password_ = password;
}
net::URLRequestContextGetter* TestSigninClient::GetURLRequestContext() {
diff --git a/components/signin/core/browser/test_signin_client.h b/components/signin/core/browser/test_signin_client.h
index a359804..8f52f20 100644
--- a/components/signin/core/browser/test_signin_client.h
+++ b/components/signin/core/browser/test_signin_client.h
@@ -47,6 +47,13 @@ class TestSigninClient : public SigninClient {
// Does nothing.
void OnSignedOut() override;
+ // Trace that this was called.
+ void PostSignedIn(const std::string& account_id,
+ const std::string& username,
+ const std::string& password) override;
+
+ std::string get_signed_in_password() { return signed_in_password_; }
+
// Returns the empty string.
std::string GetProductVersion() override;
@@ -94,6 +101,9 @@ class TestSigninClient : public SigninClient {
int signin_host_id_;
PrefService* pref_service_;
+ // Pointer to be filled by PostSignedIn.
+ std::string signed_in_password_;
+
#if defined(OS_IOS)
scoped_ptr<ios::FakeProfileOAuth2TokenServiceIOSProvider> iosProvider_;
#endif
diff --git a/components/signin/core/common/signin_pref_names.cc b/components/signin/core/common/signin_pref_names.cc
index 3348d27..5d2ea19 100644
--- a/components/signin/core/common/signin_pref_names.cc
+++ b/components/signin/core/common/signin_pref_names.cc
@@ -14,8 +14,8 @@ const char kAccountIdMigrationState[] = "account_id_migration_state";
// Boolean identifying whether reverse auto-login is enabled.
const char kAutologinEnabled[] = "autologin.enabled";
-// The profile's hosted domain; empty if unset; Profile::kNoHostedDomainFound
-// if there is none.
+// The profile's hosted domain; empty if unset;
+// AccountTrackerService::kNoHostedDomainFound if there is none.
const char kGoogleServicesHostedDomain[] = "google.services.hosted_domain";
// String the identifies the last user that logged into sync and other