Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / google_apis / gaia / oauth2_token_service.h
blobecef9e4530b209d0dbab5a274187d69e939a29f3
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 "base/timer/timer.h"
20 #include "google_apis/gaia/google_service_auth_error.h"
21 #include "google_apis/gaia/oauth2_access_token_consumer.h"
22 #include "google_apis/gaia/oauth2_access_token_fetcher.h"
24 namespace net {
25 class URLRequestContextGetter;
28 class GoogleServiceAuthError;
29 class OAuth2AccessTokenFetcher;
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 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 OAuth2TokenService();
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.
151 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 virtual std::vector<std::string> GetAccounts();
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 virtual bool RefreshTokenIsAvailable(const std::string& account_id) const = 0;
182 // Mark an OAuth2 |access_token| issued for |account_id| and |scopes| as
183 // invalid. This should be done if the token was received from this class,
184 // but was not accepted by the server (e.g., the server returned
185 // 401 Unauthorized). The token will be removed from the cache for the given
186 // scopes.
187 void InvalidateToken(const std::string& account_id,
188 const ScopeSet& scopes,
189 const std::string& access_token);
191 // Like |InvalidateToken| except is uses |client_id| to identity OAuth2 client
192 // app that issued the request instead of Chrome's default values.
193 void InvalidateTokenForClient(const std::string& account_id,
194 const std::string& client_id,
195 const ScopeSet& scopes,
196 const std::string& access_token);
199 // Return the current number of entries in the cache.
200 int cache_size_for_testing() const;
201 void set_max_authorization_token_fetch_retries_for_testing(int max_retries);
202 // Returns the current number of pending fetchers matching given params.
203 size_t GetNumPendingRequestsForTesting(
204 const std::string& client_id,
205 const std::string& account_id,
206 const ScopeSet& scopes) const;
208 protected:
209 // Implements a cancelable |OAuth2TokenService::Request|, which should be
210 // operated on the UI thread.
211 // TODO(davidroche): move this out of header file.
212 class RequestImpl : public base::SupportsWeakPtr<RequestImpl>,
213 public base::NonThreadSafe,
214 public Request {
215 public:
216 // |consumer| is required to outlive this.
217 explicit RequestImpl(const std::string& account_id, Consumer* consumer);
218 virtual ~RequestImpl();
220 // Overridden from Request:
221 virtual std::string GetAccountId() const OVERRIDE;
223 std::string GetConsumerId() const;
225 // Informs |consumer_| that this request is completed.
226 void InformConsumer(const GoogleServiceAuthError& error,
227 const std::string& access_token,
228 const base::Time& expiration_date);
230 private:
231 // |consumer_| to call back when this request completes.
232 const std::string account_id_;
233 Consumer* const consumer_;
236 // Helper class to scope batch changes.
237 class ScopedBacthChange {
238 public:
239 ScopedBacthChange(OAuth2TokenService* token_service);
240 ~ScopedBacthChange();
241 private:
242 OAuth2TokenService* token_service_; // Weak.
243 DISALLOW_COPY_AND_ASSIGN(ScopedBacthChange);
246 // Subclasses can override if they want to report errors to the user.
247 virtual void UpdateAuthError(
248 const std::string& account_id,
249 const GoogleServiceAuthError& error);
251 // Add a new entry to the cache.
252 // Subclasses can override if there are implementation-specific reasons
253 // that an access token should ever not be cached.
254 virtual void RegisterCacheEntry(const std::string& client_id,
255 const std::string& account_id,
256 const ScopeSet& scopes,
257 const std::string& access_token,
258 const base::Time& expiration_date);
260 // Clears the internal token cache.
261 void ClearCache();
263 // Clears all of the tokens belonging to |account_id| from the internal token
264 // cache. It does not matter what other parameters, like |client_id| were
265 // used to request the tokens.
266 void ClearCacheForAccount(const std::string& account_id);
268 // Cancels all requests that are currently in progress.
269 void CancelAllRequests();
271 // Cancels all requests related to a given |account_id|.
272 void CancelRequestsForAccount(const std::string& account_id);
274 // Called by subclasses to notify observers.
275 virtual void FireRefreshTokenAvailable(const std::string& account_id);
276 virtual void FireRefreshTokenRevoked(const std::string& account_id);
277 virtual void FireRefreshTokensLoaded();
279 virtual void StartBatchChanges();
280 virtual void EndBatchChanges();
282 // Fetches an OAuth token for the specified client/scopes. Virtual so it can
283 // be overridden for tests and for platform-specific behavior on Android.
284 virtual void FetchOAuth2Token(RequestImpl* request,
285 const std::string& account_id,
286 net::URLRequestContextGetter* getter,
287 const std::string& client_id,
288 const std::string& client_secret,
289 const ScopeSet& scopes);
291 // Creates an access token fetcher for the given account id.
293 // Subclasses should override to create an access token fetcher for the given
294 // |account_id|. This method is only called if subclasses use the default
295 // implementation of |FetchOAuth2Token|.
296 virtual OAuth2AccessTokenFetcher* CreateAccessTokenFetcher(
297 const std::string& account_id,
298 net::URLRequestContextGetter* getter,
299 OAuth2AccessTokenConsumer* consumer) = 0;
301 // Invalidates the |access_token| issued for |account_id|, |client_id| and
302 // |scopes|. Virtual so it can be overriden for tests and for platform-
303 // specifc behavior.
304 virtual void InvalidateOAuth2Token(const std::string& account_id,
305 const std::string& client_id,
306 const ScopeSet& scopes,
307 const std::string& access_token);
309 private:
310 class Fetcher;
311 friend class Fetcher;
313 // The parameters used to fetch an OAuth2 access token.
314 struct RequestParameters {
315 RequestParameters(const std::string& client_id,
316 const std::string& account_id,
317 const ScopeSet& scopes);
318 ~RequestParameters();
319 bool operator<(const RequestParameters& params) const;
321 // OAuth2 client id.
322 std::string client_id;
323 // Account id for which the request is made.
324 std::string account_id;
325 // URL scopes for the requested access token.
326 ScopeSet scopes;
329 typedef std::map<RequestParameters, Fetcher*> PendingFetcherMap;
331 // Derived classes must provide a request context used for fetching access
332 // tokens with the |StartRequest| method.
333 virtual net::URLRequestContextGetter* GetRequestContext() = 0;
335 // Struct that contains the information of an OAuth2 access token.
336 struct CacheEntry {
337 std::string access_token;
338 base::Time expiration_date;
341 // This method does the same as |StartRequestWithContext| except it
342 // uses |client_id| and |client_secret| to identify OAuth
343 // client app instead of using Chrome's default values.
344 scoped_ptr<Request> StartRequestForClientWithContext(
345 const std::string& account_id,
346 net::URLRequestContextGetter* getter,
347 const std::string& client_id,
348 const std::string& client_secret,
349 const ScopeSet& scopes,
350 Consumer* consumer);
352 // Returns true if GetCacheEntry would return a valid cache entry for the
353 // given scopes.
354 bool HasCacheEntry(const RequestParameters& client_scopes);
356 // Posts a task to fire the Consumer callback with the cached token. Must
357 // Must only be called if HasCacheEntry() returns true.
358 void StartCacheLookupRequest(RequestImpl* request,
359 const RequestParameters& client_scopes,
360 Consumer* consumer);
362 // Returns a currently valid OAuth2 access token for the given set of scopes,
363 // or NULL if none have been cached. Note the user of this method should
364 // ensure no entry with the same |client_scopes| is added before the usage of
365 // the returned entry is done.
366 const CacheEntry* GetCacheEntry(const RequestParameters& client_scopes);
368 // Removes an access token for the given set of scopes from the cache.
369 // Returns true if the entry was removed, otherwise false.
370 bool RemoveCacheEntry(const RequestParameters& client_scopes,
371 const std::string& token_to_remove);
373 // Called when |fetcher| finishes fetching.
374 void OnFetchComplete(Fetcher* fetcher);
376 // Called when a number of fetchers need to be canceled.
377 void CancelFetchers(std::vector<Fetcher*> fetchers_to_cancel);
379 // The cache of currently valid tokens.
380 typedef std::map<RequestParameters, CacheEntry> TokenCache;
381 TokenCache token_cache_;
383 // A map from fetch parameters to a fetcher that is fetching an OAuth2 access
384 // token using these parameters.
385 PendingFetcherMap pending_fetchers_;
387 // List of observers to notify when refresh token availability changes.
388 // Makes sure list is empty on destruction.
389 ObserverList<Observer, true> observer_list_;
391 // List of observers to notify when access token status changes.
392 ObserverList<DiagnosticsObserver, true> diagnostics_observer_list_;
394 // The depth of batch changes.
395 int batch_change_depth_;
397 // Maximum number of retries in fetching an OAuth2 access token.
398 static int max_fetch_retry_num_;
400 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, RequestParametersOrderTest);
401 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest,
402 SameScopesRequestedForDifferentClients);
404 DISALLOW_COPY_AND_ASSIGN(OAuth2TokenService);
407 #endif // GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_