Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / signin / core / browser / gaia_cookie_manager_service.h
blob484493719f8295b44ff30ad8bbaafbb305e84ada
1 // Copyright 2014 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.
5 #ifndef COMPONENTS_SIGNIN_CORE_BROWSER_GAIA_COOKIE_MANAGER_SERVICE_H
6 #define COMPONENTS_SIGNIN_CORE_BROWSER_GAIA_COOKIE_MANAGER_SERVICE_H
8 #include <deque>
10 #include "base/observer_list.h"
11 #include "base/timer/timer.h"
12 #include "components/signin/core/browser/signin_client.h"
13 #include "google_apis/gaia/gaia_auth_consumer.h"
14 #include "google_apis/gaia/gaia_auth_util.h"
15 #include "google_apis/gaia/ubertoken_fetcher.h"
16 #include "net/base/backoff_entry.h"
17 #include "net/url_request/url_fetcher_delegate.h"
19 class GaiaAuthFetcher;
20 class GaiaCookieRequest;
21 class GoogleServiceAuthError;
22 class OAuth2TokenService;
24 namespace net {
25 class URLFetcher;
28 // Merges a Google account known to Chrome into the cookie jar. When merging
29 // multiple accounts, one instance of the helper is better than multiple
30 // instances if there is the possibility that they run concurrently, since
31 // changes to the cookie must be serialized.
33 // Also checks the External CC result to ensure no services that consume the
34 // GAIA cookie are blocked (such as youtube). This is executed once for the
35 // lifetime of this object, when the first call is made to AddAccountToCookie.
36 class GaiaCookieManagerService : public KeyedService,
37 public GaiaAuthConsumer,
38 public UbertokenConsumer {
39 public:
40 enum GaiaCookieRequestType {
41 ADD_ACCOUNT,
42 LOG_OUT,
43 LIST_ACCOUNTS
46 // Contains the information and parameters for any request.
47 class GaiaCookieRequest {
48 public:
49 ~GaiaCookieRequest();
51 GaiaCookieRequestType request_type() const { return request_type_; }
52 const std::string& account_id() const {return account_id_; }
54 static GaiaCookieRequest CreateAddAccountRequest(
55 const std::string& account_id);
56 static GaiaCookieRequest CreateLogOutRequest();
57 static GaiaCookieRequest CreateListAccountsRequest();
59 private:
60 GaiaCookieRequest(
61 GaiaCookieRequestType request_type,
62 const std::string& account_id);
64 GaiaCookieRequestType request_type_;
65 std::string account_id_;
68 class Observer {
69 public:
70 // Called whenever a merge session is completed. The account that was
71 // merged is given by |account_id|. If |error| is equal to
72 // GoogleServiceAuthError::AuthErrorNone() then the merge succeeeded.
73 virtual void OnAddAccountToCookieCompleted(
74 const std::string& account_id,
75 const GoogleServiceAuthError& error) {}
77 // Called whenever the GaiaCookieManagerService's list of GAIA accounts is
78 // updated. The GCMS monitors the APISID cookie and triggers a /ListAccounts
79 // call on change. The GCMS will also call ListAccounts upon the first call
80 // to ListAccounts(). The GCMS will delay calling ListAccounts if other
81 // requests are in queue that would modify the APISID cookie.
82 // If the ListAccounts call fails and the GCMS cannot recover, the reason
83 // is passed in |error|.
84 virtual void OnGaiaAccountsInCookieUpdated(
85 const std::vector<gaia::ListedAccount>& accounts,
86 const GoogleServiceAuthError& error) {}
88 protected:
89 virtual ~Observer() {}
92 // Class to retrieve the external connection check results from gaia.
93 // Declared publicly for unit tests.
94 class ExternalCcResultFetcher : public GaiaAuthConsumer,
95 public net::URLFetcherDelegate {
96 public:
97 // Maps connection URLs, as returned by StartGetCheckConnectionInfo() to
98 // token and URLFetcher used to fetch the URL.
99 typedef std::map<GURL, std::pair<std::string, net::URLFetcher*>>
100 URLToTokenAndFetcher;
102 // Maps tokens to the fetched result for that token.
103 typedef std::map<std::string, std::string> ResultMap;
105 ExternalCcResultFetcher(GaiaCookieManagerService* helper);
106 ~ExternalCcResultFetcher() override;
108 // Gets the current value of the external connection check result string.
109 std::string GetExternalCcResult();
111 // Start fetching the external CC result. If a fetch is already in progress
112 // it is canceled.
113 void Start();
115 // Are external URLs still being checked?
116 bool IsRunning();
118 // Returns a copy of the internal token to fetcher map.
119 URLToTokenAndFetcher get_fetcher_map_for_testing() { return fetchers_; }
121 // Simulate a timeout for tests.
122 void TimeoutForTests();
124 private:
125 // Overridden from GaiaAuthConsumer.
126 void OnGetCheckConnectionInfoSuccess(const std::string& data) override;
127 void OnGetCheckConnectionInfoError(
128 const GoogleServiceAuthError& error) override;
130 // Creates and initializes a URL fetcher for doing a connection check.
131 scoped_ptr<net::URLFetcher> CreateFetcher(const GURL& url);
133 // Overridden from URLFetcherDelgate.
134 void OnURLFetchComplete(const net::URLFetcher* source) override;
136 // Any fetches still ongoing after this call are considered timed out.
137 void Timeout();
139 void CleanupTransientState();
141 void GetCheckConnectionInfoCompleted(bool succeeded);
143 GaiaCookieManagerService* helper_;
144 base::OneShotTimer<ExternalCcResultFetcher> timer_;
145 URLToTokenAndFetcher fetchers_;
146 ResultMap results_;
147 base::Time m_external_cc_result_start_time_;
149 base::OneShotTimer<ExternalCcResultFetcher> gaia_auth_fetcher_timer_;
151 DISALLOW_COPY_AND_ASSIGN(ExternalCcResultFetcher);
154 GaiaCookieManagerService(OAuth2TokenService* token_service,
155 const std::string& source,
156 SigninClient* signin_client);
157 ~GaiaCookieManagerService() override;
159 void Init();
160 void Shutdown() override;
162 void AddAccountToCookie(const std::string& account_id);
163 void AddAccountToCookieWithToken(const std::string& account_id,
164 const std::string& access_token);
166 // Returns if the listed accounts are up to date or not (ignore the out
167 // parameter if return is false). The parameter will be assigned the current
168 // cached accounts. If the accounts are not up to date, a ListAccounts fetch
169 // is sent GAIA and Observer::OnGaiaAccountsInCookieUpdated will be called.
170 bool ListAccounts(std::vector<gaia::ListedAccount>* accounts);
172 // Add or remove observers of this helper.
173 void AddObserver(Observer* observer);
174 void RemoveObserver(Observer* observer);
176 // Cancel all login requests.
177 void CancelAll();
179 // Signout all accounts.
180 void LogOutAllAccounts();
182 // Call observers when merge session completes. This public so that callers
183 // that know that a given account is already in the cookie jar can simply
184 // inform the observers.
185 void SignalComplete(const std::string& account_id,
186 const GoogleServiceAuthError& error);
188 // Returns true of there are pending log ins or outs.
189 bool is_running() const { return requests_.size() > 0; }
191 // Access the internal object during tests.
192 ExternalCcResultFetcher* external_cc_result_fetcher_for_testing() {
193 return &external_cc_result_fetcher_;
196 void set_list_accounts_fetched_once_for_testing(bool fetched) {
197 list_accounts_fetched_once_ = fetched;
200 private:
201 net::URLRequestContextGetter* request_context() {
202 return signin_client_->GetURLRequestContext();
205 // Called when a cookie changes. If the cookie relates to a GAIA APISID
206 // cookie, then we call ListAccounts and fire OnGaiaAccountsInCookieUpdated.
207 void OnCookieChanged(const net::CanonicalCookie& cookie, bool removed);
209 // Overridden from UbertokenConsumer.
210 void OnUbertokenSuccess(const std::string& token) override;
211 void OnUbertokenFailure(const GoogleServiceAuthError& error) override;
213 // Overridden from GaiaAuthConsumer.
214 void OnMergeSessionSuccess(const std::string& data) override;
215 void OnMergeSessionFailure(const GoogleServiceAuthError& error) override;
216 void OnListAccountsSuccess(const std::string& data) override;
217 void OnListAccountsFailure(const GoogleServiceAuthError& error) override;
218 void OnLogOutSuccess() override;
219 void OnLogOutFailure(const GoogleServiceAuthError& error) override;
221 // Helper method for AddAccountToCookie* methods.
222 void AddAccountToCookieInternal(const std::string& account_id);
224 // Starts the proess of fetching the uber token and performing a merge session
225 // for the next account. Virtual so that it can be overriden in tests.
226 virtual void StartFetchingUbertoken();
228 // Virtual for testing purposes.
229 virtual void StartFetchingMergeSession();
231 // Virtual for testing purposes.
232 virtual void StartFetchingListAccounts();
234 // Virtual for testing purpose.
235 virtual void StartFetchingLogOut();
237 // Start the next request, if needed.
238 void HandleNextRequest();
240 OAuth2TokenService* token_service_;
241 SigninClient* signin_client_;
242 scoped_ptr<GaiaAuthFetcher> gaia_auth_fetcher_;
243 scoped_ptr<UbertokenFetcher> uber_token_fetcher_;
244 ExternalCcResultFetcher external_cc_result_fetcher_;
246 // If the GaiaAuthFetcher or URLFetcher fails, retry with exponential backoff
247 // and network delay.
248 net::BackoffEntry fetcher_backoff_;
249 // We can safely depend on the SigninClient here because there is an explicit
250 // dependency, as noted in the GaiaCookieManagerServiceFactory.
251 base::OneShotTimer<SigninClient> fetcher_timer_;
252 int fetcher_retries_;
254 // The last fetched ubertoken, for use in MergeSession retries.
255 std::string uber_token_;
257 // The access token that can be used to prime the UberToken fetch.
258 std::string access_token_;
260 // Subscription to be called whenever the GAIA cookies change.
261 scoped_ptr<SigninClient::CookieChangedSubscription>
262 cookie_changed_subscription_;
264 // A worklist for this class. Stores any pending requests that couldn't be
265 // executed right away, since this class only permits one request to be
266 // executed at a time.
267 std::deque<GaiaCookieRequest> requests_;
269 // List of observers to notify when merge session completes.
270 // Makes sure list is empty on destruction.
271 base::ObserverList<Observer, true> observer_list_;
273 // Source to use with GAIA endpoints for accounting.
274 std::string source_;
276 // True once the ExternalCCResultFetcher has completed once.
277 bool external_cc_result_fetched_;
279 std::vector<gaia::ListedAccount> listed_accounts_;
281 bool list_accounts_fetched_once_;
283 DISALLOW_COPY_AND_ASSIGN(GaiaCookieManagerService);
286 #endif // COMPONENTS_SIGNIN_CORE_BROWSER_GAIA_COOKIE_MANAGER_SERVICE_H