Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / signin / account_reconcilor.h
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 #ifndef CHROME_BROWSER_SIGNIN_ACCOUNT_RECONCILOR_H_
5 #define CHROME_BROWSER_SIGNIN_ACCOUNT_RECONCILOR_H_
6
7 #include <deque>
8 #include <functional>
9 #include <set>
10 #include <string>
11 #include <utility>
12 #include <vector>
13
14 #include "base/basictypes.h"
15 #include "base/callback_forward.h"
16 #include "base/compiler_specific.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/memory/scoped_vector.h"
19 #include "chrome/browser/signin/signin_manager.h"
20 #include "components/keyed_service/core/keyed_service.h"
21 #include "content/public/browser/notification_observer.h"
22 #include "content/public/browser/notification_registrar.h"
23 #include "google_apis/gaia/gaia_auth_consumer.h"
24 #include "google_apis/gaia/google_service_auth_error.h"
25 #include "google_apis/gaia/merge_session_helper.h"
26 #include "google_apis/gaia/oauth2_token_service.h"
27
28 struct ChromeCookieDetails;
29 class GaiaAuthFetcher;
30 class Profile;
31 class SigninOAuthHelper;
32
33 class AccountReconcilor : public KeyedService,
34                           public content::NotificationObserver,
35                           public GaiaAuthConsumer,
36                           public MergeSessionHelper::Observer,
37                           public OAuth2TokenService::Consumer,
38                           public OAuth2TokenService::Observer,
39                           public SigninManagerBase::Observer {
40  public:
41   explicit AccountReconcilor(Profile* profile);
42   virtual ~AccountReconcilor();
43
44   void Initialize(bool start_reconcile_if_tokens_available);
45
46   // KeyedService implementation.
47   virtual void Shutdown() OVERRIDE;
48
49   // Add or remove observers for the merge session notification.
50   void AddMergeSessionObserver(MergeSessionHelper::Observer* observer);
51   void RemoveMergeSessionObserver(MergeSessionHelper::Observer* observer);
52
53   Profile* profile() { return profile_; }
54
55  private:
56   // An std::set<> for use with email addresses that uses
57   // gaia::CanonicalizeEmail() during comparisons.
58   // TODO(rogerta): this is a workaround for the fact that SigninManager and
59   // SigninOAuthHelper use the gaia "email" property when adding accounts to
60   // the token service, whereas gaia::ParseListAccountsData() returns email
61   // addresses that have been passed through gaia::CanonicalizeEmail().  These
62   // two types of email addresses are not directly comparable.
63   class EmailLessFunc : public std::less<std::string> {
64    public:
65     bool operator()(const std::string& s1, const std::string& s2) const;
66   };
67   typedef std::set<std::string, EmailLessFunc> EmailSet;
68
69   class RefreshTokenFetcher;
70   class UserIdFetcher;
71
72   bool IsPeriodicReconciliationRunning() const {
73     return reconciliation_timer_.IsRunning();
74   }
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> >&
85       GetGaiaAccountsForTesting() 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<void(
100       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 RegisterWithCookieMonster();
127   void UnregisterWithCookieMonster();
128   void RegisterWithSigninManager();
129   void UnregisterWithSigninManager();
130   void RegisterWithTokenService();
131   void UnregisterWithTokenService();
132
133   bool IsProfileConnected();
134
135   void DeleteFetchers();
136
137   // Start and stop the periodic reconciliation.
138   void StartPeriodicReconciliation();
139   void StopPeriodicReconciliation();
140   void PeriodicReconciliation();
141
142   // All actions with side effects.  Virtual so that they can be overridden
143   // in tests.
144   virtual void PerformMergeAction(const std::string& account_id);
145   virtual void PerformAddToChromeAction(const std::string& account_id,
146                                         int session_index);
147   virtual void PerformLogoutAllAccountsAction();
148
149   // Used to remove an account from chrome and the cookie jar.
150   virtual void StartRemoveAction(const std::string& account_id);
151   virtual void FinishRemoveAction(
152       const std::string& account_id,
153       const GoogleServiceAuthError& error,
154       const std::vector<std::pair<std::string, bool> >& accounts);
155
156   // Used during periodic reconciliation.
157   void StartReconcile();
158   void FinishReconcile();
159   void AbortReconcile();
160   void CalculateIfReconcileIsDone();
161   void ScheduleStartReconcileIfChromeAccountsChanged();
162   void HandleSuccessfulAccountIdCheck(const std::string& account_id);
163   void HandleFailedAccountIdCheck(const std::string& account_id);
164   void HandleRefreshTokenFetched(const std::string& account_id,
165                                  const std::string& refresh_token);
166
167   void GetAccountsFromCookie(GetAccountsFromCookieCallback callback);
168   void ContinueReconcileActionAfterGetGaiaAccounts(
169       const GoogleServiceAuthError& error,
170       const std::vector<std::pair<std::string, bool> >& accounts);
171   void ValidateAccountsFromTokenService();
172
173   void OnCookieChanged(ChromeCookieDetails* details);
174
175   // Overriden from content::NotificationObserver.
176   virtual void Observe(int type,
177                        const content::NotificationSource& source,
178                        const content::NotificationDetails& details) OVERRIDE;
179
180   // Overriden from GaiaAuthConsumer.
181   virtual void OnListAccountsSuccess(const std::string& data) OVERRIDE;
182   virtual void OnListAccountsFailure(
183       const GoogleServiceAuthError& error) OVERRIDE;
184
185   // Overriden from MergeSessionHelper::Observer.
186   virtual void MergeSessionCompleted(
187       const std::string& account_id,
188       const GoogleServiceAuthError& error) OVERRIDE;
189
190   // Overriden from OAuth2TokenService::Consumer.
191   virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
192                                  const std::string& access_token,
193                                  const base::Time& expiration_time) OVERRIDE;
194   virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
195                                  const GoogleServiceAuthError& error) OVERRIDE;
196
197   // Overriden from OAuth2TokenService::Observer.
198   virtual void OnRefreshTokenAvailable(const std::string& account_id) OVERRIDE;
199   virtual void OnRefreshTokenRevoked(const std::string& account_id) OVERRIDE;
200   virtual void OnRefreshTokensLoaded() OVERRIDE;
201
202   // Overriden from SigninManagerBase::Observer.
203   virtual void GoogleSigninSucceeded(const std::string& username,
204                                      const std::string& password) OVERRIDE;
205   virtual void GoogleSignedOut(const std::string& username) OVERRIDE;
206
207   void MayBeDoNextListAccounts();
208
209   // The profile that this reconcilor belongs to.
210   Profile* profile_;
211   content::NotificationRegistrar registrar_;
212   base::RepeatingTimer<AccountReconcilor> reconciliation_timer_;
213   MergeSessionHelper merge_session_helper_;
214   scoped_ptr<GaiaAuthFetcher> gaia_fetcher_;
215   bool registered_with_token_service_;
216
217   // True while the reconcilor is busy checking or managing the accounts in
218   // this profile.
219   bool is_reconcile_started_;
220
221   // Used during reconcile action.
222   // These members are used used to validate the gaia cookie.  |gaia_accounts_|
223   // holds the state of google accounts in the gaia cookie.  Each element is
224   // a pair that holds the email address of the account and a boolean that
225   // indicates whether the account is valid or not.  The accounts in the vector
226   // are ordered the in same way as the gaia cookie.
227   bool are_gaia_accounts_set_;
228   std::vector<std::pair<std::string, bool> > gaia_accounts_;
229
230   // Used during reconcile action.
231   // These members are used to validate the tokens in OAuth2TokenService.
232   std::string primary_account_;
233   std::vector<std::string> chrome_accounts_;
234   scoped_ptr<OAuth2TokenService::Request>* requests_;
235   ScopedVector<UserIdFetcher> user_id_fetchers_;
236   ScopedVector<SigninOAuthHelper> refresh_token_fetchers_;
237   EmailSet valid_chrome_accounts_;
238   EmailSet invalid_chrome_accounts_;
239   std::vector<std::string> add_to_cookie_;
240   std::vector<std::pair<std::string, int> > add_to_chrome_;
241
242   std::deque<GetAccountsFromCookieCallback> get_gaia_accounts_callbacks_;
243
244   DISALLOW_COPY_AND_ASSIGN(AccountReconcilor);
245 };
246
247 #endif  // CHROME_BROWSER_SIGNIN_ACCOUNT_RECONCILOR_H_