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
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/ubertoken_fetcher.h"
15 #include "net/base/backoff_entry.h"
16 #include "net/url_request/url_fetcher_delegate.h"
18 class GaiaAuthFetcher
;
19 class GoogleServiceAuthError
;
20 class OAuth2TokenService
;
26 // Merges a Google account known to Chrome into the cookie jar. When merging
27 // multiple accounts, one instance of the helper is better than multiple
28 // instances if there is the possibility that they run concurrently, since
29 // changes to the cookie must be serialized.
31 // Also checks the External CC result to ensure no services that consume the
32 // GAIA cookie are blocked (such as youtube). This is executed once for the
33 // lifetime of this object, when the first call is made to AddAccountToCookie.
34 class GaiaCookieManagerService
: public KeyedService
,
35 public GaiaAuthConsumer
,
36 public UbertokenConsumer
,
37 public net::URLFetcherDelegate
{
41 // Called whenever a merge session is completed. The account that was
42 // merged is given by |account_id|. If |error| is equal to
43 // GoogleServiceAuthError::AuthErrorNone() then the merge succeeeded.
44 virtual void OnAddAccountToCookieCompleted(
45 const std::string
& account_id
,
46 const GoogleServiceAuthError
& error
) = 0;
48 // Called when ExternalCcResultFetcher completes. From this moment
49 // forward calls to AddAccountToCookie() will use the result in merge
50 // session calls. If |succeeded| is false, not all connections were checked,
51 // but some may have been. AddAccountToCookie() will proceed with whatever
52 // partial results were retrieved.
53 virtual void GetCheckConnectionInfoCompleted(bool succeeded
) {}
56 virtual ~Observer() {}
59 // Class to retrieve the external connection check results from gaia.
60 // Declared publicly for unit tests.
61 class ExternalCcResultFetcher
: public GaiaAuthConsumer
,
62 public net::URLFetcherDelegate
{
64 // Maps connection URLs, as returned by StartGetCheckConnectionInfo() to
65 // token and URLFetcher used to fetch the URL.
66 typedef std::map
<GURL
, std::pair
<std::string
, net::URLFetcher
*>>
69 // Maps tokens to the fetched result for that token.
70 typedef std::map
<std::string
, std::string
> ResultMap
;
72 ExternalCcResultFetcher(GaiaCookieManagerService
* helper
);
73 ~ExternalCcResultFetcher() override
;
75 // Gets the current value of the external connection check result string.
76 std::string
GetExternalCcResult();
78 // Start fetching the external CC result. If a fetch is already in progress
82 // Are external URLs still being checked?
85 // Returns a copy of the internal token to fetcher map.
86 URLToTokenAndFetcher
get_fetcher_map_for_testing() { return fetchers_
; }
88 // Simulate a timeout for tests.
89 void TimeoutForTests();
92 // Overridden from GaiaAuthConsumer.
93 void OnGetCheckConnectionInfoSuccess(const std::string
& data
) override
;
94 void OnGetCheckConnectionInfoError(
95 const GoogleServiceAuthError
& error
) override
;
97 // Creates and initializes a URL fetcher for doing a connection check.
98 net::URLFetcher
* CreateFetcher(const GURL
& url
);
100 // Overridden from URLFetcherDelgate.
101 void OnURLFetchComplete(const net::URLFetcher
* source
) override
;
103 // Any fetches still ongoing after this call are considered timed out.
106 void CleanupTransientState();
108 void FireGetCheckConnectionInfoCompleted(bool succeeded
);
110 GaiaCookieManagerService
* helper_
;
111 base::OneShotTimer
<ExternalCcResultFetcher
> timer_
;
112 scoped_ptr
<GaiaAuthFetcher
> gaia_auth_fetcher_
;
113 URLToTokenAndFetcher fetchers_
;
115 base::Time m_external_cc_result_start_time_
;
117 DISALLOW_COPY_AND_ASSIGN(ExternalCcResultFetcher
);
120 GaiaCookieManagerService(OAuth2TokenService
* token_service
,
121 const std::string
& source
,
122 SigninClient
* signin_client
);
123 ~GaiaCookieManagerService() override
;
125 void AddAccountToCookie(const std::string
& account_id
);
127 // Add or remove observers of this helper.
128 void AddObserver(Observer
* observer
);
129 void RemoveObserver(Observer
* observer
);
131 // Cancel all login requests.
134 // Signout of |account_id| given a list of accounts already signed in.
135 // Since this involves signing out of all accounts and resigning back in,
136 // the order which |accounts| are given is important as it will dictate
137 // the sign in order. |account_id| does not have to be in |accounts|.
138 void LogOut(const std::string
& account_id
,
139 const std::vector
<std::string
>& accounts
);
141 // Signout all accounts.
142 void LogOutAllAccounts();
144 // Call observers when merge session completes. This public so that callers
145 // that know that a given account is already in the cookie jar can simply
146 // inform the observers.
147 void SignalComplete(const std::string
& account_id
,
148 const GoogleServiceAuthError
& error
);
150 // Returns true of there are pending log ins or outs.
151 bool is_running() const { return accounts_
.size() > 0; }
153 // Start the process of fetching the external check connection result so that
154 // its ready when we try to perform a merge session.
155 void StartFetchingExternalCcResult();
158 net::URLRequestContextGetter
* request_context() {
159 return signin_client_
->GetURLRequestContext();
162 // Overridden from UbertokenConsumer.
163 void OnUbertokenSuccess(const std::string
& token
) override
;
164 void OnUbertokenFailure(const GoogleServiceAuthError
& error
) override
;
166 // Overridden from GaiaAuthConsumer.
167 void OnMergeSessionSuccess(const std::string
& data
) override
;
168 void OnMergeSessionFailure(const GoogleServiceAuthError
& error
) override
;
170 void LogOutInternal(const std::string
& account_id
,
171 const std::vector
<std::string
>& accounts
);
173 // Starts the process of fetching the uber token and then performing a merge
174 // session for the next account. Virtual so that it can be overriden in tests.
175 virtual void StartFetching();
177 // Virtual for testing purposes.
178 virtual void StartFetchingMergeSession();
180 // Virtual for testing purpose.
181 virtual void StartLogOutUrlFetch();
183 // Start the next merge session, if needed.
184 void HandleNextAccount();
186 // Overridden from URLFetcherDelgate.
187 void OnURLFetchComplete(const net::URLFetcher
* source
) override
;
189 OAuth2TokenService
* token_service_
;
190 SigninClient
* signin_client_
;
191 scoped_ptr
<GaiaAuthFetcher
> gaia_auth_fetcher_
;
192 scoped_ptr
<UbertokenFetcher
> uber_token_fetcher_
;
193 ExternalCcResultFetcher external_cc_result_fetcher_
;
195 // If the GaiaAuthFetcher fails, retry with exponential backoff.
196 net::BackoffEntry gaia_auth_fetcher_backoff_
;
197 base::OneShotTimer
<GaiaCookieManagerService
> gaia_auth_fetcher_timer_
;
198 int gaia_auth_fetcher_retries_
;
200 // The last fetched ubertoken, for use in MergeSession retries.
201 std::string uber_token_
;
203 // A worklist for this class. Accounts names are stored here if
204 // we are pending a signin action for that account. Empty strings
205 // represent a signout request.
206 std::deque
<std::string
> accounts_
;
208 // List of observers to notify when merge session completes.
209 // Makes sure list is empty on destruction.
210 ObserverList
<Observer
, true> observer_list_
;
212 // Source to use with GAIA endpoints for accounting.
215 DISALLOW_COPY_AND_ASSIGN(GaiaCookieManagerService
);
218 #endif // COMPONENTS_SIGNIN_CORE_BROWSER_GAIA_COOKIE_MANAGER_SERVICE_H