[chromedriver] Don't evaluate document.readyState if we already know it is loading.
[chromium-blink-merge.git] / google_apis / gaia / oauth2_token_service.h
blob85c3fc85852c340670268f8e62eb38874ca1f4a4
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.
5 #ifndef GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_
6 #define GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_
8 #include <map>
9 #include <set>
10 #include <string>
12 #include "base/basictypes.h"
13 #include "base/gtest_prod_util.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/observer_list.h"
17 #include "base/threading/non_thread_safe.h"
18 #include "base/time/time.h"
19 #include "google_apis/gaia/google_service_auth_error.h"
20 #include "google_apis/gaia/oauth2_access_token_consumer.h"
21 #include "google_apis/gaia/oauth2_access_token_fetcher.h"
23 namespace net {
24 class URLRequestContextGetter;
27 class GoogleServiceAuthError;
28 class OAuth2AccessTokenFetcher;
29 class OAuth2TokenServiceDelegate;
31 // Abstract base class for a service that fetches and caches OAuth2 access
32 // tokens. Concrete subclasses should implement GetRefreshToken to return
33 // the appropriate refresh token. Derived services might maintain refresh tokens
34 // for multiple accounts.
36 // All calls are expected from the UI thread.
38 // To use this service, call StartRequest() with a given set of scopes and a
39 // consumer of the request results. The consumer is required to outlive the
40 // request. The request can be deleted. The consumer may be called back
41 // asynchronously with the fetch results.
43 // - If the consumer is not called back before the request is deleted, it will
44 // never be called back.
45 // Note in this case, the actual network requests are not canceled and the
46 // cache will be populated with the fetched results; it is just the consumer
47 // callback that is aborted.
49 // - Otherwise the consumer will be called back with the request and the fetch
50 // results.
52 // The caller of StartRequest() owns the returned request and is responsible to
53 // delete the request even once the callback has been invoked.
54 class OAuth2TokenService : public base::NonThreadSafe {
55 public:
56 // A set of scopes in OAuth2 authentication.
57 typedef std::set<std::string> ScopeSet;
59 // Class representing a request that fetches an OAuth2 access token.
60 class Request {
61 public:
62 virtual ~Request();
63 virtual std::string GetAccountId() const = 0;
64 protected:
65 Request();
68 // Class representing the consumer of a Request passed to |StartRequest|,
69 // which will be called back when the request completes.
70 class Consumer {
71 public:
72 explicit Consumer(const std::string& id);
73 virtual ~Consumer();
75 std::string id() const { return id_; }
77 // |request| is a Request that is started by this consumer and has
78 // completed.
79 virtual void OnGetTokenSuccess(const Request* request,
80 const std::string& access_token,
81 const base::Time& expiration_time) = 0;
82 virtual void OnGetTokenFailure(const Request* request,
83 const GoogleServiceAuthError& error) = 0;
84 private:
85 std::string id_;
88 // Classes that want to listen for refresh token availability should
89 // implement this interface and register with the AddObserver() call.
90 class Observer {
91 public:
92 // Called whenever a new login-scoped refresh token is available for
93 // account |account_id|. Once available, access tokens can be retrieved for
94 // this account. This is called during initial startup for each token
95 // loaded.
96 virtual void OnRefreshTokenAvailable(const std::string& account_id) {}
97 // Called whenever the login-scoped refresh token becomes unavailable for
98 // account |account_id|.
99 virtual void OnRefreshTokenRevoked(const std::string& account_id) {}
100 // Called after all refresh tokens are loaded during OAuth2TokenService
101 // startup.
102 virtual void OnRefreshTokensLoaded() {}
103 // Sent before starting a batch of refresh token changes.
104 virtual void OnStartBatchChanges() {}
105 // Sent after a batch of refresh token changes is done.
106 virtual void OnEndBatchChanges() {}
108 protected:
109 virtual ~Observer() {}
112 // Classes that want to monitor status of access token and access token
113 // request should implement this interface and register with the
114 // AddDiagnosticsObserver() call.
115 class DiagnosticsObserver {
116 public:
117 // Called when receiving request for access token.
118 virtual void OnAccessTokenRequested(const std::string& account_id,
119 const std::string& consumer_id,
120 const ScopeSet& scopes) = 0;
121 // Called when access token fetching finished successfully or
122 // unsuccessfully. |expiration_time| are only valid with
123 // successful completion.
124 virtual void OnFetchAccessTokenComplete(const std::string& account_id,
125 const std::string& consumer_id,
126 const ScopeSet& scopes,
127 GoogleServiceAuthError error,
128 base::Time expiration_time) = 0;
129 virtual void OnTokenRemoved(const std::string& account_id,
130 const ScopeSet& scopes) = 0;
133 explicit OAuth2TokenService(OAuth2TokenServiceDelegate* delegate);
134 virtual ~OAuth2TokenService();
136 // Add or remove observers of this token service.
137 void AddObserver(Observer* observer);
138 void RemoveObserver(Observer* observer);
140 // Add or remove observers of this token service.
141 void AddDiagnosticsObserver(DiagnosticsObserver* observer);
142 void RemoveDiagnosticsObserver(DiagnosticsObserver* observer);
144 // Checks in the cache for a valid access token for a specified |account_id|
145 // and |scopes|, and if not found starts a request for an OAuth2 access token
146 // using the OAuth2 refresh token maintained by this instance for that
147 // |account_id|. The caller owns the returned Request.
148 // |scopes| is the set of scopes to get an access token for, |consumer| is
149 // the object that will be called back with results if the returned request
150 // is not deleted. Virtual for mocking.
151 virtual scoped_ptr<Request> StartRequest(const std::string& account_id,
152 const ScopeSet& scopes,
153 Consumer* consumer);
155 // This method does the same as |StartRequest| except it uses |client_id| and
156 // |client_secret| to identify OAuth client app instead of using
157 // Chrome's default values.
158 scoped_ptr<Request> StartRequestForClient(
159 const std::string& account_id,
160 const std::string& client_id,
161 const std::string& client_secret,
162 const ScopeSet& scopes,
163 Consumer* consumer);
165 // This method does the same as |StartRequest| except it uses the request
166 // context given by |getter| instead of using the one returned by
167 // |GetRequestContext| implemented by derived classes.
168 scoped_ptr<Request> StartRequestWithContext(
169 const std::string& account_id,
170 net::URLRequestContextGetter* getter,
171 const ScopeSet& scopes,
172 Consumer* consumer);
174 // Lists account IDs of all accounts with a refresh token maintained by this
175 // instance.
176 std::vector<std::string> GetAccounts() const;
178 // Returns true if a refresh token exists for |account_id|. If false, calls to
179 // |StartRequest| will result in a Consumer::OnGetTokenFailure callback.
180 bool RefreshTokenIsAvailable(const std::string& account_id) const;
182 // This method cancels all token requests, revoke all refresh tokens and
183 // cached access tokens.
184 void RevokeAllCredentials();
186 // Mark an OAuth2 |access_token| issued for |account_id| and |scopes| as
187 // invalid. This should be done if the token was received from this class,
188 // but was not accepted by the server (e.g., the server returned
189 // 401 Unauthorized). The token will be removed from the cache for the given
190 // scopes.
191 void InvalidateAccessToken(const std::string& account_id,
192 const ScopeSet& scopes,
193 const std::string& access_token);
195 // Like |InvalidateToken| except is uses |client_id| to identity OAuth2 client
196 // app that issued the request instead of Chrome's default values.
197 void InvalidateAccessTokenForClient(const std::string& account_id,
198 const std::string& client_id,
199 const ScopeSet& scopes,
200 const std::string& access_token);
202 void set_max_authorization_token_fetch_retries_for_testing(int max_retries);
203 // Returns the current number of pending fetchers matching given params.
204 size_t GetNumPendingRequestsForTesting(
205 const std::string& client_id,
206 const std::string& account_id,
207 const ScopeSet& scopes) const;
209 OAuth2TokenServiceDelegate* GetDelegate();
211 protected:
212 // Implements a cancelable |OAuth2TokenService::Request|, which should be
213 // operated on the UI thread.
214 // TODO(davidroche): move this out of header file.
215 class RequestImpl : public base::SupportsWeakPtr<RequestImpl>,
216 public base::NonThreadSafe,
217 public Request {
218 public:
219 // |consumer| is required to outlive this.
220 RequestImpl(const std::string& account_id, Consumer* consumer);
221 ~RequestImpl() override;
223 // Overridden from Request:
224 std::string GetAccountId() const override;
226 std::string GetConsumerId() const;
228 // Informs |consumer_| that this request is completed.
229 void InformConsumer(const GoogleServiceAuthError& error,
230 const std::string& access_token,
231 const base::Time& expiration_date);
233 private:
234 // |consumer_| to call back when this request completes.
235 const std::string account_id_;
236 Consumer* const consumer_;
239 // Implement it in delegates if they want to report errors to the user.
240 void UpdateAuthError(const std::string& account_id,
241 const GoogleServiceAuthError& error);
243 // Add a new entry to the cache.
244 // Subclasses can override if there are implementation-specific reasons
245 // that an access token should ever not be cached.
246 virtual void RegisterCacheEntry(const std::string& client_id,
247 const std::string& account_id,
248 const ScopeSet& scopes,
249 const std::string& access_token,
250 const base::Time& expiration_date);
252 // Clears the internal token cache.
253 void ClearCache();
255 // Clears all of the tokens belonging to |account_id| from the internal token
256 // cache. It does not matter what other parameters, like |client_id| were
257 // used to request the tokens.
258 void ClearCacheForAccount(const std::string& account_id);
260 // Cancels all requests that are currently in progress.
261 void CancelAllRequests();
263 // Cancels all requests related to a given |account_id|.
264 void CancelRequestsForAccount(const std::string& account_id);
266 // Fetches an OAuth token for the specified client/scopes. Virtual so it can
267 // be overridden for tests and for platform-specific behavior.
268 virtual void FetchOAuth2Token(RequestImpl* request,
269 const std::string& account_id,
270 net::URLRequestContextGetter* getter,
271 const std::string& client_id,
272 const std::string& client_secret,
273 const ScopeSet& scopes);
275 // Create an access token fetcher for the given account id.
276 OAuth2AccessTokenFetcher* CreateAccessTokenFetcher(
277 const std::string& account_id,
278 net::URLRequestContextGetter* getter,
279 OAuth2AccessTokenConsumer* consumer);
281 // Invalidates the |access_token| issued for |account_id|, |client_id| and
282 // |scopes|. Virtual so it can be overriden for tests and for platform-
283 // specifc behavior.
284 virtual void InvalidateAccessTokenImpl(const std::string& account_id,
285 const std::string& client_id,
286 const ScopeSet& scopes,
287 const std::string& access_token);
289 private:
290 class Fetcher;
291 friend class Fetcher;
292 friend class OAuth2TokenServiceDelegate;
294 // The parameters used to fetch an OAuth2 access token.
295 struct RequestParameters {
296 RequestParameters(const std::string& client_id,
297 const std::string& account_id,
298 const ScopeSet& scopes);
299 ~RequestParameters();
300 bool operator<(const RequestParameters& params) const;
302 // OAuth2 client id.
303 std::string client_id;
304 // Account id for which the request is made.
305 std::string account_id;
306 // URL scopes for the requested access token.
307 ScopeSet scopes;
310 typedef std::map<RequestParameters, Fetcher*> PendingFetcherMap;
312 // Provide a request context used for fetching access tokens with the
313 // |StartRequest| method.
314 net::URLRequestContextGetter* GetRequestContext() const;
316 // Struct that contains the information of an OAuth2 access token.
317 struct CacheEntry {
318 std::string access_token;
319 base::Time expiration_date;
322 // This method does the same as |StartRequestWithContext| except it
323 // uses |client_id| and |client_secret| to identify OAuth
324 // client app instead of using Chrome's default values.
325 scoped_ptr<Request> StartRequestForClientWithContext(
326 const std::string& account_id,
327 net::URLRequestContextGetter* getter,
328 const std::string& client_id,
329 const std::string& client_secret,
330 const ScopeSet& scopes,
331 Consumer* consumer);
333 // Returns true if GetCacheEntry would return a valid cache entry for the
334 // given scopes.
335 bool HasCacheEntry(const RequestParameters& client_scopes);
337 // Posts a task to fire the Consumer callback with the cached token. Must
338 // Must only be called if HasCacheEntry() returns true.
339 void StartCacheLookupRequest(RequestImpl* request,
340 const RequestParameters& client_scopes,
341 Consumer* consumer);
343 // Returns a currently valid OAuth2 access token for the given set of scopes,
344 // or NULL if none have been cached. Note the user of this method should
345 // ensure no entry with the same |client_scopes| is added before the usage of
346 // the returned entry is done.
347 const CacheEntry* GetCacheEntry(const RequestParameters& client_scopes);
349 // Removes an access token for the given set of scopes from the cache.
350 // Returns true if the entry was removed, otherwise false.
351 bool RemoveCacheEntry(const RequestParameters& client_scopes,
352 const std::string& token_to_remove);
354 // Called when |fetcher| finishes fetching.
355 void OnFetchComplete(Fetcher* fetcher);
357 // Called when a number of fetchers need to be canceled.
358 void CancelFetchers(std::vector<Fetcher*> fetchers_to_cancel);
360 // The cache of currently valid tokens.
361 typedef std::map<RequestParameters, CacheEntry> TokenCache;
362 TokenCache token_cache_;
364 scoped_ptr<OAuth2TokenServiceDelegate> delegate_;
366 // A map from fetch parameters to a fetcher that is fetching an OAuth2 access
367 // token using these parameters.
368 PendingFetcherMap pending_fetchers_;
370 // List of observers to notify when access token status changes.
371 base::ObserverList<DiagnosticsObserver, true> diagnostics_observer_list_;
373 // The depth of batch changes.
374 int batch_change_depth_;
376 // Maximum number of retries in fetching an OAuth2 access token.
377 static int max_fetch_retry_num_;
379 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, RequestParametersOrderTest);
380 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest,
381 SameScopesRequestedForDifferentClients);
382 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, UpdateClearsCache);
384 DISALLOW_COPY_AND_ASSIGN(OAuth2TokenService);
387 #endif // GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_