OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_ | 5 #ifndef GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_ |
6 #define GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_ | 6 #define GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 #include <set> | 9 #include <set> |
10 #include <string> | 10 #include <string> |
11 | 11 |
12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
13 #include "base/gtest_prod_util.h" | 13 #include "base/gtest_prod_util.h" |
14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
15 #include "base/memory/weak_ptr.h" | 15 #include "base/memory/weak_ptr.h" |
16 #include "base/observer_list.h" | 16 #include "base/observer_list.h" |
17 #include "base/threading/non_thread_safe.h" | 17 #include "base/threading/non_thread_safe.h" |
18 #include "base/time/time.h" | 18 #include "base/time/time.h" |
19 #include "google_apis/gaia/google_service_auth_error.h" | 19 #include "google_apis/gaia/google_service_auth_error.h" |
20 #include "google_apis/gaia/oauth2_access_token_consumer.h" | 20 #include "google_apis/gaia/oauth2_access_token_consumer.h" |
21 #include "google_apis/gaia/oauth2_access_token_fetcher.h" | 21 #include "google_apis/gaia/oauth2_access_token_fetcher.h" |
22 | 22 |
23 namespace net { | 23 namespace net { |
24 class URLRequestContextGetter; | 24 class URLRequestContextGetter; |
25 } | 25 } |
26 | 26 |
27 class GoogleServiceAuthError; | 27 class GoogleServiceAuthError; |
28 class OAuth2AccessTokenFetcher; | 28 class OAuth2AccessTokenFetcher; |
| 29 class OAuth2TokenServiceDelegate; |
29 | 30 |
30 // Abstract base class for a service that fetches and caches OAuth2 access | 31 // Abstract base class for a service that fetches and caches OAuth2 access |
31 // tokens. Concrete subclasses should implement GetRefreshToken to return | 32 // tokens. Concrete subclasses should implement GetRefreshToken to return |
32 // the appropriate refresh token. Derived services might maintain refresh tokens | 33 // the appropriate refresh token. Derived services might maintain refresh tokens |
33 // for multiple accounts. | 34 // for multiple accounts. |
34 // | 35 // |
35 // All calls are expected from the UI thread. | 36 // All calls are expected from the UI thread. |
36 // | 37 // |
37 // To use this service, call StartRequest() with a given set of scopes and a | 38 // To use this service, call StartRequest() with a given set of scopes and a |
38 // consumer of the request results. The consumer is required to outlive the | 39 // consumer of the request results. The consumer is required to outlive the |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 // successful completion. | 123 // successful completion. |
123 virtual void OnFetchAccessTokenComplete(const std::string& account_id, | 124 virtual void OnFetchAccessTokenComplete(const std::string& account_id, |
124 const std::string& consumer_id, | 125 const std::string& consumer_id, |
125 const ScopeSet& scopes, | 126 const ScopeSet& scopes, |
126 GoogleServiceAuthError error, | 127 GoogleServiceAuthError error, |
127 base::Time expiration_time) = 0; | 128 base::Time expiration_time) = 0; |
128 virtual void OnTokenRemoved(const std::string& account_id, | 129 virtual void OnTokenRemoved(const std::string& account_id, |
129 const ScopeSet& scopes) = 0; | 130 const ScopeSet& scopes) = 0; |
130 }; | 131 }; |
131 | 132 |
132 OAuth2TokenService(); | 133 explicit OAuth2TokenService(OAuth2TokenServiceDelegate* delegate); |
133 virtual ~OAuth2TokenService(); | 134 virtual ~OAuth2TokenService(); |
134 | 135 |
135 // Add or remove observers of this token service. | 136 // Add or remove observers of this token service. |
136 void AddObserver(Observer* observer); | 137 void AddObserver(Observer* observer); |
137 void RemoveObserver(Observer* observer); | 138 void RemoveObserver(Observer* observer); |
138 | 139 |
139 // Add or remove observers of this token service. | 140 // Add or remove observers of this token service. |
140 void AddDiagnosticsObserver(DiagnosticsObserver* observer); | 141 void AddDiagnosticsObserver(DiagnosticsObserver* observer); |
141 void RemoveDiagnosticsObserver(DiagnosticsObserver* observer); | 142 void RemoveDiagnosticsObserver(DiagnosticsObserver* observer); |
142 | 143 |
(...skipping 22 matching lines...) Expand all Loading... |
165 // context given by |getter| instead of using the one returned by | 166 // context given by |getter| instead of using the one returned by |
166 // |GetRequestContext| implemented by derived classes. | 167 // |GetRequestContext| implemented by derived classes. |
167 scoped_ptr<Request> StartRequestWithContext( | 168 scoped_ptr<Request> StartRequestWithContext( |
168 const std::string& account_id, | 169 const std::string& account_id, |
169 net::URLRequestContextGetter* getter, | 170 net::URLRequestContextGetter* getter, |
170 const ScopeSet& scopes, | 171 const ScopeSet& scopes, |
171 Consumer* consumer); | 172 Consumer* consumer); |
172 | 173 |
173 // Lists account IDs of all accounts with a refresh token maintained by this | 174 // Lists account IDs of all accounts with a refresh token maintained by this |
174 // instance. | 175 // instance. |
175 virtual std::vector<std::string> GetAccounts(); | 176 std::vector<std::string> GetAccounts() const; |
176 | 177 |
177 // Returns true if a refresh token exists for |account_id|. If false, calls to | 178 // Returns true if a refresh token exists for |account_id|. If false, calls to |
178 // |StartRequest| will result in a Consumer::OnGetTokenFailure callback. | 179 // |StartRequest| will result in a Consumer::OnGetTokenFailure callback. |
179 virtual bool RefreshTokenIsAvailable(const std::string& account_id) const = 0; | 180 bool RefreshTokenIsAvailable(const std::string& account_id) const; |
| 181 |
| 182 // This method cancels all token requests, revoke all refresh tokens and |
| 183 // cached access tokens. |
| 184 void RevokeAllCredentials(); |
180 | 185 |
181 // Mark an OAuth2 |access_token| issued for |account_id| and |scopes| as | 186 // Mark an OAuth2 |access_token| issued for |account_id| and |scopes| as |
182 // invalid. This should be done if the token was received from this class, | 187 // invalid. This should be done if the token was received from this class, |
183 // but was not accepted by the server (e.g., the server returned | 188 // but was not accepted by the server (e.g., the server returned |
184 // 401 Unauthorized). The token will be removed from the cache for the given | 189 // 401 Unauthorized). The token will be removed from the cache for the given |
185 // scopes. | 190 // scopes. |
186 void InvalidateToken(const std::string& account_id, | 191 void InvalidateAccessToken(const std::string& account_id, |
187 const ScopeSet& scopes, | 192 const ScopeSet& scopes, |
188 const std::string& access_token); | 193 const std::string& access_token); |
189 | 194 |
190 // Like |InvalidateToken| except is uses |client_id| to identity OAuth2 client | 195 // Like |InvalidateToken| except is uses |client_id| to identity OAuth2 client |
191 // app that issued the request instead of Chrome's default values. | 196 // app that issued the request instead of Chrome's default values. |
192 void InvalidateTokenForClient(const std::string& account_id, | 197 void InvalidateAccessTokenForClient(const std::string& account_id, |
193 const std::string& client_id, | 198 const std::string& client_id, |
194 const ScopeSet& scopes, | 199 const ScopeSet& scopes, |
195 const std::string& access_token); | 200 const std::string& access_token); |
196 | 201 |
197 | |
198 // Return the current number of entries in the cache. | |
199 int cache_size_for_testing() const; | |
200 void set_max_authorization_token_fetch_retries_for_testing(int max_retries); | 202 void set_max_authorization_token_fetch_retries_for_testing(int max_retries); |
201 // Returns the current number of pending fetchers matching given params. | 203 // Returns the current number of pending fetchers matching given params. |
202 size_t GetNumPendingRequestsForTesting( | 204 size_t GetNumPendingRequestsForTesting( |
203 const std::string& client_id, | 205 const std::string& client_id, |
204 const std::string& account_id, | 206 const std::string& account_id, |
205 const ScopeSet& scopes) const; | 207 const ScopeSet& scopes) const; |
206 | 208 |
| 209 OAuth2TokenServiceDelegate* GetDelegate(); |
| 210 |
207 protected: | 211 protected: |
208 // Implements a cancelable |OAuth2TokenService::Request|, which should be | 212 // Implements a cancelable |OAuth2TokenService::Request|, which should be |
209 // operated on the UI thread. | 213 // operated on the UI thread. |
210 // TODO(davidroche): move this out of header file. | 214 // TODO(davidroche): move this out of header file. |
211 class RequestImpl : public base::SupportsWeakPtr<RequestImpl>, | 215 class RequestImpl : public base::SupportsWeakPtr<RequestImpl>, |
212 public base::NonThreadSafe, | 216 public base::NonThreadSafe, |
213 public Request { | 217 public Request { |
214 public: | 218 public: |
215 // |consumer| is required to outlive this. | 219 // |consumer| is required to outlive this. |
216 RequestImpl(const std::string& account_id, Consumer* consumer); | 220 RequestImpl(const std::string& account_id, Consumer* consumer); |
217 ~RequestImpl() override; | 221 ~RequestImpl() override; |
218 | 222 |
219 // Overridden from Request: | 223 // Overridden from Request: |
220 std::string GetAccountId() const override; | 224 std::string GetAccountId() const override; |
221 | 225 |
222 std::string GetConsumerId() const; | 226 std::string GetConsumerId() const; |
223 | 227 |
224 // Informs |consumer_| that this request is completed. | 228 // Informs |consumer_| that this request is completed. |
225 void InformConsumer(const GoogleServiceAuthError& error, | 229 void InformConsumer(const GoogleServiceAuthError& error, |
226 const std::string& access_token, | 230 const std::string& access_token, |
227 const base::Time& expiration_date); | 231 const base::Time& expiration_date); |
228 | 232 |
229 private: | 233 private: |
230 // |consumer_| to call back when this request completes. | 234 // |consumer_| to call back when this request completes. |
231 const std::string account_id_; | 235 const std::string account_id_; |
232 Consumer* const consumer_; | 236 Consumer* const consumer_; |
233 }; | 237 }; |
234 | 238 |
235 // Helper class to scope batch changes. | 239 // Implement it in delegates if they want to report errors to the user. |
236 class ScopedBatchChange { | 240 void UpdateAuthError(const std::string& account_id, |
237 public: | 241 const GoogleServiceAuthError& error); |
238 explicit ScopedBatchChange(OAuth2TokenService* token_service); | |
239 ~ScopedBatchChange(); | |
240 private: | |
241 OAuth2TokenService* token_service_; // Weak. | |
242 DISALLOW_COPY_AND_ASSIGN(ScopedBatchChange); | |
243 }; | |
244 | |
245 // Subclasses can override if they want to report errors to the user. | |
246 virtual void UpdateAuthError( | |
247 const std::string& account_id, | |
248 const GoogleServiceAuthError& error); | |
249 | 242 |
250 // Add a new entry to the cache. | 243 // Add a new entry to the cache. |
251 // Subclasses can override if there are implementation-specific reasons | 244 // Subclasses can override if there are implementation-specific reasons |
252 // that an access token should ever not be cached. | 245 // that an access token should ever not be cached. |
253 virtual void RegisterCacheEntry(const std::string& client_id, | 246 virtual void RegisterCacheEntry(const std::string& client_id, |
254 const std::string& account_id, | 247 const std::string& account_id, |
255 const ScopeSet& scopes, | 248 const ScopeSet& scopes, |
256 const std::string& access_token, | 249 const std::string& access_token, |
257 const base::Time& expiration_date); | 250 const base::Time& expiration_date); |
258 | 251 |
259 // Clears the internal token cache. | 252 // Clears the internal token cache. |
260 void ClearCache(); | 253 void ClearCache(); |
261 | 254 |
262 // Clears all of the tokens belonging to |account_id| from the internal token | 255 // Clears all of the tokens belonging to |account_id| from the internal token |
263 // cache. It does not matter what other parameters, like |client_id| were | 256 // cache. It does not matter what other parameters, like |client_id| were |
264 // used to request the tokens. | 257 // used to request the tokens. |
265 void ClearCacheForAccount(const std::string& account_id); | 258 void ClearCacheForAccount(const std::string& account_id); |
266 | 259 |
267 // Cancels all requests that are currently in progress. | 260 // Cancels all requests that are currently in progress. |
268 void CancelAllRequests(); | 261 void CancelAllRequests(); |
269 | 262 |
270 // Cancels all requests related to a given |account_id|. | 263 // Cancels all requests related to a given |account_id|. |
271 void CancelRequestsForAccount(const std::string& account_id); | 264 void CancelRequestsForAccount(const std::string& account_id); |
272 | 265 |
273 // Called by subclasses to notify observers. | |
274 virtual void FireRefreshTokenAvailable(const std::string& account_id); | |
275 virtual void FireRefreshTokenRevoked(const std::string& account_id); | |
276 virtual void FireRefreshTokensLoaded(); | |
277 | |
278 virtual void StartBatchChanges(); | |
279 virtual void EndBatchChanges(); | |
280 | |
281 // Fetches an OAuth token for the specified client/scopes. Virtual so it can | 266 // Fetches an OAuth token for the specified client/scopes. Virtual so it can |
282 // be overridden for tests and for platform-specific behavior on Android. | 267 // be overridden for tests and for platform-specific behavior. |
283 virtual void FetchOAuth2Token(RequestImpl* request, | 268 virtual void FetchOAuth2Token(RequestImpl* request, |
284 const std::string& account_id, | 269 const std::string& account_id, |
285 net::URLRequestContextGetter* getter, | 270 net::URLRequestContextGetter* getter, |
286 const std::string& client_id, | 271 const std::string& client_id, |
287 const std::string& client_secret, | 272 const std::string& client_secret, |
288 const ScopeSet& scopes); | 273 const ScopeSet& scopes); |
289 | 274 |
290 // Creates an access token fetcher for the given account id. | 275 // Create an access token fetcher for the given account id. |
291 // | 276 OAuth2AccessTokenFetcher* CreateAccessTokenFetcher( |
292 // Subclasses should override to create an access token fetcher for the given | |
293 // |account_id|. This method is only called if subclasses use the default | |
294 // implementation of |FetchOAuth2Token|. | |
295 virtual OAuth2AccessTokenFetcher* CreateAccessTokenFetcher( | |
296 const std::string& account_id, | 277 const std::string& account_id, |
297 net::URLRequestContextGetter* getter, | 278 net::URLRequestContextGetter* getter, |
298 OAuth2AccessTokenConsumer* consumer) = 0; | 279 OAuth2AccessTokenConsumer* consumer); |
299 | 280 |
300 // Invalidates the |access_token| issued for |account_id|, |client_id| and | 281 // Invalidates the |access_token| issued for |account_id|, |client_id| and |
301 // |scopes|. Virtual so it can be overriden for tests and for platform- | 282 // |scopes|. Virtual so it can be overriden for tests and for platform- |
302 // specifc behavior. | 283 // specifc behavior. |
303 virtual void InvalidateOAuth2Token(const std::string& account_id, | 284 virtual void InvalidateAccessTokenImpl(const std::string& account_id, |
304 const std::string& client_id, | 285 const std::string& client_id, |
305 const ScopeSet& scopes, | 286 const ScopeSet& scopes, |
306 const std::string& access_token); | 287 const std::string& access_token); |
307 | 288 |
308 private: | 289 private: |
309 class Fetcher; | 290 class Fetcher; |
310 friend class Fetcher; | 291 friend class Fetcher; |
| 292 friend class OAuth2TokenServiceDelegate; |
311 | 293 |
312 // The parameters used to fetch an OAuth2 access token. | 294 // The parameters used to fetch an OAuth2 access token. |
313 struct RequestParameters { | 295 struct RequestParameters { |
314 RequestParameters(const std::string& client_id, | 296 RequestParameters(const std::string& client_id, |
315 const std::string& account_id, | 297 const std::string& account_id, |
316 const ScopeSet& scopes); | 298 const ScopeSet& scopes); |
317 ~RequestParameters(); | 299 ~RequestParameters(); |
318 bool operator<(const RequestParameters& params) const; | 300 bool operator<(const RequestParameters& params) const; |
319 | 301 |
320 // OAuth2 client id. | 302 // OAuth2 client id. |
321 std::string client_id; | 303 std::string client_id; |
322 // Account id for which the request is made. | 304 // Account id for which the request is made. |
323 std::string account_id; | 305 std::string account_id; |
324 // URL scopes for the requested access token. | 306 // URL scopes for the requested access token. |
325 ScopeSet scopes; | 307 ScopeSet scopes; |
326 }; | 308 }; |
327 | 309 |
328 typedef std::map<RequestParameters, Fetcher*> PendingFetcherMap; | 310 typedef std::map<RequestParameters, Fetcher*> PendingFetcherMap; |
329 | 311 |
330 // Derived classes must provide a request context used for fetching access | 312 // Provide a request context used for fetching access tokens with the |
331 // tokens with the |StartRequest| method. | 313 // |StartRequest| method. |
332 virtual net::URLRequestContextGetter* GetRequestContext() = 0; | 314 net::URLRequestContextGetter* GetRequestContext() const; |
333 | 315 |
334 // Struct that contains the information of an OAuth2 access token. | 316 // Struct that contains the information of an OAuth2 access token. |
335 struct CacheEntry { | 317 struct CacheEntry { |
336 std::string access_token; | 318 std::string access_token; |
337 base::Time expiration_date; | 319 base::Time expiration_date; |
338 }; | 320 }; |
339 | 321 |
340 // This method does the same as |StartRequestWithContext| except it | 322 // This method does the same as |StartRequestWithContext| except it |
341 // uses |client_id| and |client_secret| to identify OAuth | 323 // uses |client_id| and |client_secret| to identify OAuth |
342 // client app instead of using Chrome's default values. | 324 // client app instead of using Chrome's default values. |
(...skipping 29 matching lines...) Expand all Loading... |
372 // Called when |fetcher| finishes fetching. | 354 // Called when |fetcher| finishes fetching. |
373 void OnFetchComplete(Fetcher* fetcher); | 355 void OnFetchComplete(Fetcher* fetcher); |
374 | 356 |
375 // Called when a number of fetchers need to be canceled. | 357 // Called when a number of fetchers need to be canceled. |
376 void CancelFetchers(std::vector<Fetcher*> fetchers_to_cancel); | 358 void CancelFetchers(std::vector<Fetcher*> fetchers_to_cancel); |
377 | 359 |
378 // The cache of currently valid tokens. | 360 // The cache of currently valid tokens. |
379 typedef std::map<RequestParameters, CacheEntry> TokenCache; | 361 typedef std::map<RequestParameters, CacheEntry> TokenCache; |
380 TokenCache token_cache_; | 362 TokenCache token_cache_; |
381 | 363 |
| 364 scoped_ptr<OAuth2TokenServiceDelegate> delegate_; |
| 365 |
382 // A map from fetch parameters to a fetcher that is fetching an OAuth2 access | 366 // A map from fetch parameters to a fetcher that is fetching an OAuth2 access |
383 // token using these parameters. | 367 // token using these parameters. |
384 PendingFetcherMap pending_fetchers_; | 368 PendingFetcherMap pending_fetchers_; |
385 | 369 |
386 // List of observers to notify when refresh token availability changes. | |
387 // Makes sure list is empty on destruction. | |
388 base::ObserverList<Observer, true> observer_list_; | |
389 | |
390 // List of observers to notify when access token status changes. | 370 // List of observers to notify when access token status changes. |
391 base::ObserverList<DiagnosticsObserver, true> diagnostics_observer_list_; | 371 base::ObserverList<DiagnosticsObserver, true> diagnostics_observer_list_; |
392 | 372 |
393 // The depth of batch changes. | 373 // The depth of batch changes. |
394 int batch_change_depth_; | 374 int batch_change_depth_; |
395 | 375 |
396 // Maximum number of retries in fetching an OAuth2 access token. | 376 // Maximum number of retries in fetching an OAuth2 access token. |
397 static int max_fetch_retry_num_; | 377 static int max_fetch_retry_num_; |
398 | 378 |
399 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, RequestParametersOrderTest); | 379 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, RequestParametersOrderTest); |
400 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, | 380 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, |
401 SameScopesRequestedForDifferentClients); | 381 SameScopesRequestedForDifferentClients); |
| 382 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, UpdateClearsCache); |
402 | 383 |
403 DISALLOW_COPY_AND_ASSIGN(OAuth2TokenService); | 384 DISALLOW_COPY_AND_ASSIGN(OAuth2TokenService); |
404 }; | 385 }; |
405 | 386 |
406 #endif // GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_ | 387 #endif // GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_ |
OLD | NEW |