account_reconcilor.h revision 0de6073388f4e2780db8536178b129cd8f6ab386
103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// found in the LICENSE file. 403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_H_ 503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#define COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_H_ 603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <deque> 803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <functional> 903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <set> 1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <string> 1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <utility> 1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <vector> 1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/basictypes.h" 1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/callback_forward.h" 1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/compiler_specific.h" 1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/memory/scoped_vector.h" 1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/keyed_service/core/keyed_service.h" 2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/signin/core/browser/signin_manager.h" 2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "google_apis/gaia/gaia_auth_consumer.h" 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "google_apis/gaia/google_service_auth_error.h" 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "google_apis/gaia/merge_session_helper.h" 2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "google_apis/gaia/oauth2_token_service.h" 2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class GaiaAuthFetcher; 2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class ProfileOAuth2TokenService; 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class SigninClient; 2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class SigninOAuthHelper; 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace net { 3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class CanonicalCookie; 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class AccountReconcilor : public KeyedService, 3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) public GaiaAuthConsumer, 3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) public MergeSessionHelper::Observer, 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) public OAuth2TokenService::Consumer, 39 public OAuth2TokenService::Observer, 40 public SigninManagerBase::Observer { 41 public: 42 AccountReconcilor(ProfileOAuth2TokenService* token_service, 43 SigninManagerBase* signin_manager, 44 SigninClient* client); 45 virtual ~AccountReconcilor(); 46 47 void Initialize(bool start_reconcile_if_tokens_available); 48 49 // KeyedService implementation. 50 virtual void Shutdown() OVERRIDE; 51 52 // Add or remove observers for the merge session notification. 53 void AddMergeSessionObserver(MergeSessionHelper::Observer* observer); 54 void RemoveMergeSessionObserver(MergeSessionHelper::Observer* observer); 55 56 ProfileOAuth2TokenService* token_service() { return token_service_; } 57 SigninClient* client() { return client_; } 58 59 private: 60 // An std::set<> for use with email addresses that uses 61 // gaia::CanonicalizeEmail() during comparisons. 62 // TODO(rogerta): this is a workaround for the fact that SigninManager and 63 // SigninOAuthHelper use the gaia "email" property when adding accounts to 64 // the token service, whereas gaia::ParseListAccountsData() returns email 65 // addresses that have been passed through gaia::CanonicalizeEmail(). These 66 // two types of email addresses are not directly comparable. 67 class EmailLessFunc : public std::less<std::string> { 68 public: 69 bool operator()(const std::string& s1, const std::string& s2) const; 70 }; 71 typedef std::set<std::string, EmailLessFunc> EmailSet; 72 73 class RefreshTokenFetcher; 74 class UserIdFetcher; 75 76 bool IsRegisteredWithTokenService() const { 77 return registered_with_token_service_; 78 } 79 80 bool AreGaiaAccountsSet() const { return are_gaia_accounts_set_; } 81 82 bool AreAllRefreshTokensChecked() const; 83 84 const std::vector<std::pair<std::string, bool> >& GetGaiaAccountsForTesting() 85 const { 86 return gaia_accounts_; 87 } 88 89 const EmailSet& GetValidChromeAccountsForTesting() const { 90 return valid_chrome_accounts_; 91 } 92 93 const EmailSet& GetInvalidChromeAccountsForTesting() const { 94 return invalid_chrome_accounts_; 95 } 96 97 // Used during GetAccountsFromCookie. 98 // Stores a callback for the next action to perform. 99 typedef base::Callback< 100 void(const GoogleServiceAuthError& error, 101 const std::vector<std::pair<std::string, bool> >&)> 102 GetAccountsFromCookieCallback; 103 104 friend class AccountReconcilorTest; 105 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, SigninManagerRegistration); 106 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, Reauth); 107 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, ProfileAlreadyConnected); 108 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, GetAccountsFromCookieSuccess); 109 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, GetAccountsFromCookieFailure); 110 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, ValidateAccountsFromTokens); 111 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, 112 ValidateAccountsFromTokensFailedUserInfo); 113 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, 114 ValidateAccountsFromTokensFailedTokenRequest); 115 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileNoop); 116 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileNoopWithDots); 117 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileNoopMultiple); 118 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileAddToCookie); 119 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileAddToChrome); 120 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileBadPrimary); 121 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileOnlyOnce); 122 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, 123 StartReconcileWithSessionInfoExpiredDefault); 124 125 // Register and unregister with dependent services. 126 void RegisterForCookieChanges(); 127 void UnregisterForCookieChanges(); 128 void RegisterWithSigninManager(); 129 void UnregisterWithSigninManager(); 130 void RegisterWithTokenService(); 131 void UnregisterWithTokenService(); 132 133 bool IsProfileConnected(); 134 135 void DeleteFetchers(); 136 137 // All actions with side effects. Virtual so that they can be overridden 138 // in tests. 139 virtual void PerformMergeAction(const std::string& account_id); 140 virtual void PerformAddToChromeAction(const std::string& account_id, 141 int session_index); 142 virtual void PerformLogoutAllAccountsAction(); 143 144 // Used to remove an account from chrome and the cookie jar. 145 virtual void StartRemoveAction(const std::string& account_id); 146 virtual void FinishRemoveAction( 147 const std::string& account_id, 148 const GoogleServiceAuthError& error, 149 const std::vector<std::pair<std::string, bool> >& accounts); 150 151 // Used during periodic reconciliation. 152 void StartReconcile(); 153 void FinishReconcile(); 154 void AbortReconcile(); 155 void CalculateIfReconcileIsDone(); 156 void ScheduleStartReconcileIfChromeAccountsChanged(); 157 void HandleSuccessfulAccountIdCheck(const std::string& account_id); 158 void HandleFailedAccountIdCheck(const std::string& account_id); 159 void HandleRefreshTokenFetched(const std::string& account_id, 160 const std::string& refresh_token); 161 162 void GetAccountsFromCookie(GetAccountsFromCookieCallback callback); 163 void ContinueReconcileActionAfterGetGaiaAccounts( 164 const GoogleServiceAuthError& error, 165 const std::vector<std::pair<std::string, bool> >& accounts); 166 void ValidateAccountsFromTokenService(); 167 168 void OnCookieChanged(const net::CanonicalCookie* cookie); 169 170 // Overriden from GaiaAuthConsumer. 171 virtual void OnListAccountsSuccess(const std::string& data) OVERRIDE; 172 virtual void OnListAccountsFailure(const GoogleServiceAuthError& error) 173 OVERRIDE; 174 175 // Overriden from MergeSessionHelper::Observer. 176 virtual void MergeSessionCompleted(const std::string& account_id, 177 const GoogleServiceAuthError& error) 178 OVERRIDE; 179 180 // Overriden from OAuth2TokenService::Consumer. 181 virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request, 182 const std::string& access_token, 183 const base::Time& expiration_time) OVERRIDE; 184 virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request, 185 const GoogleServiceAuthError& error) OVERRIDE; 186 187 // Overriden from OAuth2TokenService::Observer. 188 virtual void OnRefreshTokenAvailable(const std::string& account_id) OVERRIDE; 189 virtual void OnRefreshTokenRevoked(const std::string& account_id) OVERRIDE; 190 virtual void OnRefreshTokensLoaded() OVERRIDE; 191 192 // Overriden from SigninManagerBase::Observer. 193 virtual void GoogleSigninSucceeded(const std::string& username, 194 const std::string& password) OVERRIDE; 195 virtual void GoogleSignedOut(const std::string& username) OVERRIDE; 196 197 void MayBeDoNextListAccounts(); 198 199 // The ProfileOAuth2TokenService associated with this reconcilor. 200 ProfileOAuth2TokenService* token_service_; 201 202 // The SigninManager associated with this reconcilor. 203 SigninManagerBase* signin_manager_; 204 205 // The SigninClient associated with this reconcilor. 206 SigninClient* client_; 207 208 MergeSessionHelper merge_session_helper_; 209 scoped_ptr<GaiaAuthFetcher> gaia_fetcher_; 210 bool registered_with_token_service_; 211 212 // True while the reconcilor is busy checking or managing the accounts in 213 // this profile. 214 bool is_reconcile_started_; 215 216 // Used during reconcile action. 217 // These members are used used to validate the gaia cookie. |gaia_accounts_| 218 // holds the state of google accounts in the gaia cookie. Each element is 219 // a pair that holds the email address of the account and a boolean that 220 // indicates whether the account is valid or not. The accounts in the vector 221 // are ordered the in same way as the gaia cookie. 222 bool are_gaia_accounts_set_; 223 std::vector<std::pair<std::string, bool> > gaia_accounts_; 224 225 // Used during reconcile action. 226 // These members are used to validate the tokens in OAuth2TokenService. 227 std::string primary_account_; 228 std::vector<std::string> chrome_accounts_; 229 scoped_ptr<OAuth2TokenService::Request>* requests_; 230 ScopedVector<UserIdFetcher> user_id_fetchers_; 231 ScopedVector<SigninOAuthHelper> refresh_token_fetchers_; 232 EmailSet valid_chrome_accounts_; 233 EmailSet invalid_chrome_accounts_; 234 std::vector<std::string> add_to_cookie_; 235 std::vector<std::pair<std::string, int> > add_to_chrome_; 236 237 std::deque<GetAccountsFromCookieCallback> get_gaia_accounts_callbacks_; 238 239 DISALLOW_COPY_AND_ASSIGN(AccountReconcilor); 240}; 241 242#endif // COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_H_ 243