| 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 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(); |
| 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 void RevokeAllCredentials(); |
| 180 | 183 |
| 181 // Mark an OAuth2 |access_token| issued for |account_id| and |scopes| as | 184 // 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, | 185 // 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 | 186 // 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 | 187 // 401 Unauthorized). The token will be removed from the cache for the given |
| 185 // scopes. | 188 // scopes. |
| 186 void InvalidateToken(const std::string& account_id, | 189 void InvalidateToken(const std::string& account_id, |
| 187 const ScopeSet& scopes, | 190 const ScopeSet& scopes, |
| 188 const std::string& access_token); | 191 const std::string& access_token); |
| 189 | 192 |
| 190 // Like |InvalidateToken| except is uses |client_id| to identity OAuth2 client | 193 // Like |InvalidateToken| except is uses |client_id| to identity OAuth2 client |
| 191 // app that issued the request instead of Chrome's default values. | 194 // app that issued the request instead of Chrome's default values. |
| 192 void InvalidateTokenForClient(const std::string& account_id, | 195 void InvalidateTokenForClient(const std::string& account_id, |
| 193 const std::string& client_id, | 196 const std::string& client_id, |
| 194 const ScopeSet& scopes, | 197 const ScopeSet& scopes, |
| 195 const std::string& access_token); | 198 const std::string& access_token); |
| 196 | 199 |
| 197 | 200 |
| 198 // Return the current number of entries in the cache. | 201 // Return the current number of entries in the cache. |
| 199 int cache_size_for_testing() const; | 202 int cache_size_for_testing() const; |
| 200 void set_max_authorization_token_fetch_retries_for_testing(int max_retries); | 203 void set_max_authorization_token_fetch_retries_for_testing(int max_retries); |
| 201 // Returns the current number of pending fetchers matching given params. | 204 // Returns the current number of pending fetchers matching given params. |
| 202 size_t GetNumPendingRequestsForTesting( | 205 size_t GetNumPendingRequestsForTesting( |
| 203 const std::string& client_id, | 206 const std::string& client_id, |
| 204 const std::string& account_id, | 207 const std::string& account_id, |
| 205 const ScopeSet& scopes) const; | 208 const ScopeSet& scopes) const; |
| 206 | 209 |
| 210 OAuth2TokenServiceDelegate* GetDelegate(); |
| 211 |
| 207 protected: | 212 protected: |
| 208 // Implements a cancelable |OAuth2TokenService::Request|, which should be | 213 // Implements a cancelable |OAuth2TokenService::Request|, which should be |
| 209 // operated on the UI thread. | 214 // operated on the UI thread. |
| 210 // TODO(davidroche): move this out of header file. | 215 // TODO(davidroche): move this out of header file. |
| 211 class RequestImpl : public base::SupportsWeakPtr<RequestImpl>, | 216 class RequestImpl : public base::SupportsWeakPtr<RequestImpl>, |
| 212 public base::NonThreadSafe, | 217 public base::NonThreadSafe, |
| 213 public Request { | 218 public Request { |
| 214 public: | 219 public: |
| 215 // |consumer| is required to outlive this. | 220 // |consumer| is required to outlive this. |
| 216 RequestImpl(const std::string& account_id, Consumer* consumer); | 221 RequestImpl(const std::string& account_id, Consumer* consumer); |
| 217 ~RequestImpl() override; | 222 ~RequestImpl() override; |
| 218 | 223 |
| 219 // Overridden from Request: | 224 // Overridden from Request: |
| 220 std::string GetAccountId() const override; | 225 std::string GetAccountId() const override; |
| 221 | 226 |
| 222 std::string GetConsumerId() const; | 227 std::string GetConsumerId() const; |
| 223 | 228 |
| 224 // Informs |consumer_| that this request is completed. | 229 // Informs |consumer_| that this request is completed. |
| 225 void InformConsumer(const GoogleServiceAuthError& error, | 230 void InformConsumer(const GoogleServiceAuthError& error, |
| 226 const std::string& access_token, | 231 const std::string& access_token, |
| 227 const base::Time& expiration_date); | 232 const base::Time& expiration_date); |
| 228 | 233 |
| 229 private: | 234 private: |
| 230 // |consumer_| to call back when this request completes. | 235 // |consumer_| to call back when this request completes. |
| 231 const std::string account_id_; | 236 const std::string account_id_; |
| 232 Consumer* const consumer_; | 237 Consumer* const consumer_; |
| 233 }; | 238 }; |
| 234 | 239 |
| 235 // Helper class to scope batch changes. | 240 // Implement it in delegates if they want to report errors to the user. |
| 236 class ScopedBatchChange { | 241 void UpdateAuthError(const std::string& account_id, |
| 237 public: | 242 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 | 243 |
| 250 // Add a new entry to the cache. | 244 // Add a new entry to the cache. |
| 251 // Subclasses can override if there are implementation-specific reasons | 245 // Subclasses can override if there are implementation-specific reasons |
| 252 // that an access token should ever not be cached. | 246 // that an access token should ever not be cached. |
| 253 virtual void RegisterCacheEntry(const std::string& client_id, | 247 virtual void RegisterCacheEntry(const std::string& client_id, |
| 254 const std::string& account_id, | 248 const std::string& account_id, |
| 255 const ScopeSet& scopes, | 249 const ScopeSet& scopes, |
| 256 const std::string& access_token, | 250 const std::string& access_token, |
| 257 const base::Time& expiration_date); | 251 const base::Time& expiration_date); |
| 258 | 252 |
| 259 // Clears the internal token cache. | 253 // Clears the internal token cache. |
| 260 void ClearCache(); | 254 void ClearCache(); |
| 261 | 255 |
| 262 // Clears all of the tokens belonging to |account_id| from the internal token | 256 // 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 | 257 // cache. It does not matter what other parameters, like |client_id| were |
| 264 // used to request the tokens. | 258 // used to request the tokens. |
| 265 void ClearCacheForAccount(const std::string& account_id); | 259 void ClearCacheForAccount(const std::string& account_id); |
| 266 | 260 |
| 267 // Cancels all requests that are currently in progress. | 261 // Cancels all requests that are currently in progress. |
| 268 void CancelAllRequests(); | 262 void CancelAllRequests(); |
| 269 | 263 |
| 270 // Cancels all requests related to a given |account_id|. | 264 // Cancels all requests related to a given |account_id|. |
| 271 void CancelRequestsForAccount(const std::string& account_id); | 265 void CancelRequestsForAccount(const std::string& account_id); |
| 272 | 266 |
| 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 | 267 // 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. | 268 // be overridden for tests and for platform-specific behavior. |
| 283 virtual void FetchOAuth2Token(RequestImpl* request, | 269 virtual void FetchOAuth2Token(RequestImpl* request, |
| 284 const std::string& account_id, | 270 const std::string& account_id, |
| 285 net::URLRequestContextGetter* getter, | 271 net::URLRequestContextGetter* getter, |
| 286 const std::string& client_id, | 272 const std::string& client_id, |
| 287 const std::string& client_secret, | 273 const std::string& client_secret, |
| 288 const ScopeSet& scopes); | 274 const ScopeSet& scopes); |
| 289 | 275 |
| 290 // Creates an access token fetcher for the given account id. | 276 // Create an access token fetcher for the given account id. |
| 291 // | 277 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, | 278 const std::string& account_id, |
| 297 net::URLRequestContextGetter* getter, | 279 net::URLRequestContextGetter* getter, |
| 298 OAuth2AccessTokenConsumer* consumer) = 0; | 280 OAuth2AccessTokenConsumer* consumer); |
| 299 | 281 |
| 300 // Invalidates the |access_token| issued for |account_id|, |client_id| and | 282 // Invalidates the |access_token| issued for |account_id|, |client_id| and |
| 301 // |scopes|. Virtual so it can be overriden for tests and for platform- | 283 // |scopes|. Virtual so it can be overriden for tests and for platform- |
| 302 // specifc behavior. | 284 // specifc behavior. |
| 303 virtual void InvalidateOAuth2Token(const std::string& account_id, | 285 virtual void InvalidateOAuth2Token(const std::string& account_id, |
| 304 const std::string& client_id, | 286 const std::string& client_id, |
| 305 const ScopeSet& scopes, | 287 const ScopeSet& scopes, |
| 306 const std::string& access_token); | 288 const std::string& access_token); |
| 307 | |
| 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 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 ObserverList<DiagnosticsObserver, true> diagnostics_observer_list_; | 371 ObserverList<DiagnosticsObserver, true> diagnostics_observer_list_; |
| 392 | 372 |
| 393 // The depth of batch changes. | |
| 394 int batch_change_depth_; | |
| 395 | |
| 396 // Maximum number of retries in fetching an OAuth2 access token. | 373 // Maximum number of retries in fetching an OAuth2 access token. |
| 397 static int max_fetch_retry_num_; | 374 static int max_fetch_retry_num_; |
| 398 | 375 |
| 399 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, RequestParametersOrderTest); | 376 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, RequestParametersOrderTest); |
| 400 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, | 377 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, |
| 401 SameScopesRequestedForDifferentClients); | 378 SameScopesRequestedForDifferentClients); |
| 402 | 379 |
| 403 DISALLOW_COPY_AND_ASSIGN(OAuth2TokenService); | 380 DISALLOW_COPY_AND_ASSIGN(OAuth2TokenService); |
| 404 }; | 381 }; |
| 405 | 382 |
| 406 #endif // GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_ | 383 #endif // GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_ |
| OLD | NEW |