1424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#ifndef GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_ 6424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#define GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_ 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <map> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <set> 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/basictypes.h" 1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/gtest_prod_util.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/weak_ptr.h" 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/observer_list.h" 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/threading/non_thread_safe.h" 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/timer/timer.h" 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "google_apis/gaia/google_service_auth_error.h" 2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "google_apis/gaia/oauth2_access_token_consumer.h" 2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "google_apis/gaia/oauth2_access_token_fetcher.h" 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace net { 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class URLRequestContextGetter; 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GoogleServiceAuthError; 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class OAuth2AccessTokenFetcher; 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Abstract base class for a service that fetches and caches OAuth2 access 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// tokens. Concrete subclasses should implement GetRefreshToken to return 3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// the appropriate refresh token. Derived services might maintain refresh tokens 3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// for multiple accounts. 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// All calls are expected from the UI thread. 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// To use this service, call StartRequest() with a given set of scopes and a 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// consumer of the request results. The consumer is required to outlive the 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// request. The request can be deleted. The consumer may be called back 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// asynchronously with the fetch results. 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - If the consumer is not called back before the request is deleted, it will 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// never be called back. 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Note in this case, the actual network requests are not canceled and the 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// cache will be populated with the fetched results; it is just the consumer 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// callback that is aborted. 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Otherwise the consumer will be called back with the request and the fetch 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// results. 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The caller of StartRequest() owns the returned request and is responsible to 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// delete the request even once the callback has been invoked. 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class OAuth2TokenService : public base::NonThreadSafe { 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // A set of scopes in OAuth2 authentication. 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef std::set<std::string> ScopeSet; 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Class representing a request that fetches an OAuth2 access token. 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class Request { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~Request(); 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual std::string GetAccountId() const = 0; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Request(); 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Class representing the consumer of a Request passed to |StartRequest|, 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // which will be called back when the request completes. 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class Consumer { 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Consumer(const std::string& id); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~Consumer(); 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string id() const { return id_; } 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |request| is a Request that is started by this consumer and has 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // completed. 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnGetTokenSuccess(const Request* request, 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& access_token, 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Time& expiration_time) = 0; 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnGetTokenFailure(const Request* request, 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GoogleServiceAuthError& error) = 0; 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string id_; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Classes that want to listen for refresh token availability should 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // implement this interface and register with the AddObserver() call. 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch class Observer { 917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public: 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Called whenever a new login-scoped refresh token is available for 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // account |account_id|. Once available, access tokens can be retrieved for 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // this account. This is called during initial startup for each token 957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // loaded. 967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual void OnRefreshTokenAvailable(const std::string& account_id) {} 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Called whenever the login-scoped refresh token becomes unavailable for 987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // account |account_id|. 993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual void OnRefreshTokenRevoked(const std::string& account_id) {} 1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Called after all refresh tokens are loaded during OAuth2TokenService 1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // startup. 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual void OnRefreshTokensLoaded() {} 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Sent before starting a batch of refresh token changes. 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual void OnStartBatchChanges() {} 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Sent after a batch of refresh token changes is done. 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual void OnEndBatchChanges() {} 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch protected: 1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual ~Observer() {} 1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch }; 1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Classes that want to monitor status of access token and access token 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // request should implement this interface and register with the 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // AddDiagnosticsObserver() call. 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) class DiagnosticsObserver { 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Called when receiving request for access token. 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnAccessTokenRequested(const std::string& account_id, 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& consumer_id, 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ScopeSet& scopes) = 0; 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Called when access token fetching finished successfully or 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // unsuccessfully. |expiration_time| are only valid with 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // successful completion. 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnFetchAccessTokenComplete(const std::string& account_id, 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& consumer_id, 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ScopeSet& scopes, 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GoogleServiceAuthError error, 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time expiration_time) = 0; 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnTokenRemoved(const std::string& account_id, 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ScopeSet& scopes) = 0; 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 133ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch OAuth2TokenService(); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~OAuth2TokenService(); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Add or remove observers of this token service. 1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void AddObserver(Observer* observer); 1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void RemoveObserver(Observer* observer); 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Add or remove observers of this token service. 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void AddDiagnosticsObserver(DiagnosticsObserver* observer); 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void RemoveDiagnosticsObserver(DiagnosticsObserver* observer); 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Checks in the cache for a valid access token for a specified |account_id| 14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // and |scopes|, and if not found starts a request for an OAuth2 access token 14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // using the OAuth2 refresh token maintained by this instance for that 14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // |account_id|. The caller owns the returned Request. 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |scopes| is the set of scopes to get an access token for, |consumer| is 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the object that will be called back with results if the returned request 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // is not deleted. 15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_ptr<Request> StartRequest(const std::string& account_id, 15268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ScopeSet& scopes, 15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Consumer* consumer); 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // This method does the same as |StartRequest| except it uses |client_id| and 156a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // |client_secret| to identify OAuth client app instead of using 157a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Chrome's default values. 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<Request> StartRequestForClient( 15968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 160a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_id, 161a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_secret, 162a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const ScopeSet& scopes, 163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Consumer* consumer); 164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 16558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch // This method does the same as |StartRequest| except it uses the request 16658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch // context given by |getter| instead of using the one returned by 16758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch // |GetRequestContext| implemented by derived classes. 1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<Request> StartRequestWithContext( 16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 17058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch net::URLRequestContextGetter* getter, 17158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch const ScopeSet& scopes, 17258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch Consumer* consumer); 17358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch 17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Lists account IDs of all accounts with a refresh token maintained by this 17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // instance. 17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) virtual std::vector<std::string> GetAccounts(); 17768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Returns true if a refresh token exists for |account_id|. If false, calls to 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |StartRequest| will result in a Consumer::OnGetTokenFailure callback. 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool RefreshTokenIsAvailable(const std::string& account_id) const = 0; 18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 18268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Mark an OAuth2 |access_token| issued for |account_id| and |scopes| as 18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // invalid. This should be done if the token was received from this class, 18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // but was not accepted by the server (e.g., the server returned 18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // 401 Unauthorized). The token will be removed from the cache for the given 18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // scopes. 18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void InvalidateToken(const std::string& account_id, 18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ScopeSet& scopes, 18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& access_token); 19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Like |InvalidateToken| except is uses |client_id| to identity OAuth2 client 19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // app that issued the request instead of Chrome's default values. 19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void InvalidateTokenForClient(const std::string& account_id, 19468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& client_id, 19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ScopeSet& scopes, 19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& access_token); 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Return the current number of entries in the cache. 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int cache_size_for_testing() const; 201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void set_max_authorization_token_fetch_retries_for_testing(int max_retries); 20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Returns the current number of pending fetchers matching given params. 20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) size_t GetNumPendingRequestsForTesting( 20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_id, 20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const ScopeSet& scopes) const; 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Implements a cancelable |OAuth2TokenService::Request|, which should be 210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // operated on the UI thread. 211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(davidroche): move this out of header file. 212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch class RequestImpl : public base::SupportsWeakPtr<RequestImpl>, 213424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) public base::NonThreadSafe, 214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public Request { 215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // |consumer| is required to outlive this. 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) explicit RequestImpl(const std::string& account_id, Consumer* consumer); 218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual ~RequestImpl(); 219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Overridden from Request: 221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual std::string GetAccountId() const OVERRIDE; 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string GetConsumerId() const; 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Informs |consumer_| that this request is completed. 226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void InformConsumer(const GoogleServiceAuthError& error, 227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& access_token, 228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::Time& expiration_date); 229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // |consumer_| to call back when this request completes. 232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string account_id_; 233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Consumer* const consumer_; 234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Helper class to scope batch changes. 237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch class ScopedBacthChange { 238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public: 239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ScopedBacthChange(OAuth2TokenService* token_service); 240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ~ScopedBacthChange(); 241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private: 242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch OAuth2TokenService* token_service_; // Weak. 243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DISALLOW_COPY_AND_ASSIGN(ScopedBacthChange); 244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }; 245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Subclasses can override if they want to report errors to the user. 24768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) virtual void UpdateAuthError( 24868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 24968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const GoogleServiceAuthError& error); 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add a new entry to the cache. 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Subclasses can override if there are implementation-specific reasons 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // that an access token should ever not be cached. 25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual void RegisterCacheEntry(const std::string& client_id, 25568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ScopeSet& scopes, 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& access_token, 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Time& expiration_date); 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Clears the internal token cache. 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ClearCache(); 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 26368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Clears all of the tokens belonging to |account_id| from the internal token 26468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // cache. It does not matter what other parameters, like |client_id| were 26568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // used to request the tokens. 26668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void ClearCacheForAccount(const std::string& account_id); 26768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Cancels all requests that are currently in progress. 269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void CancelAllRequests(); 270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 27168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Cancels all requests related to a given |account_id|. 27268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void CancelRequestsForAccount(const std::string& account_id); 273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Called by subclasses to notify observers. 2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void FireRefreshTokenAvailable(const std::string& account_id); 2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void FireRefreshTokenRevoked(const std::string& account_id); 2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void FireRefreshTokensLoaded(); 27868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual void StartBatchChanges(); 280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual void EndBatchChanges(); 281116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Fetches an OAuth token for the specified client/scopes. Virtual so it can 2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // be overridden for tests and for platform-specific behavior on Android. 2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual void FetchOAuth2Token(RequestImpl* request, 28568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) net::URLRequestContextGetter* getter, 2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& client_id, 2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& client_secret, 2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const ScopeSet& scopes); 29068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Creates an access token fetcher for the given account id. 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Subclasses should override to create an access token fetcher for the given 294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // |account_id|. This method is only called if subclasses use the default 295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // implementation of |FetchOAuth2Token|. 296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual OAuth2AccessTokenFetcher* CreateAccessTokenFetcher( 297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& account_id, 298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLRequestContextGetter* getter, 299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OAuth2AccessTokenConsumer* consumer) = 0; 300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 30168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Invalidates the |access_token| issued for |account_id|, |client_id| and 30268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // |scopes|. Virtual so it can be overriden for tests and for platform- 30368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // specifc behavior. 30468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) virtual void InvalidateOAuth2Token(const std::string& account_id, 30568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& client_id, 30668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ScopeSet& scopes, 30768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& access_token); 30868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private: 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class Fetcher; 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class Fetcher; 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The parameters used to fetch an OAuth2 access token. 31468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) struct RequestParameters { 31568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RequestParameters(const std::string& client_id, 31668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 31768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ScopeSet& scopes); 31868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ~RequestParameters(); 31968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool operator<(const RequestParameters& params) const; 32058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 32158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // OAuth2 client id. 32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string client_id; 32368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Account id for which the request is made. 32468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::string account_id; 32558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // URL scopes for the requested access token. 32658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ScopeSet scopes; 32758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) }; 32858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 32968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) typedef std::map<RequestParameters, Fetcher*> PendingFetcherMap; 33058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 33158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Derived classes must provide a request context used for fetching access 33258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // tokens with the |StartRequest| method. 33358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual net::URLRequestContextGetter* GetRequestContext() = 0; 33458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Struct that contains the information of an OAuth2 access token. 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct CacheEntry { 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string access_token; 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time expiration_date; 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 341a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // This method does the same as |StartRequestWithContext| except it 342a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // uses |client_id| and |client_secret| to identify OAuth 343a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // client app instead of using Chrome's default values. 344a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<Request> StartRequestForClientWithContext( 34568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 346a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) net::URLRequestContextGetter* getter, 347a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_id, 348a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_secret, 349a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const ScopeSet& scopes, 350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Consumer* consumer); 351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 35268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Returns true if GetCacheEntry would return a valid cache entry for the 35368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // given scopes. 35468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool HasCacheEntry(const RequestParameters& client_scopes); 35568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 35668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Posts a task to fire the Consumer callback with the cached token. Must 35768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Must only be called if HasCacheEntry() returns true. 35868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void StartCacheLookupRequest(RequestImpl* request, 35968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const RequestParameters& client_scopes, 36068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Consumer* consumer); 36168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns a currently valid OAuth2 access token for the given set of scopes, 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // or NULL if none have been cached. Note the user of this method should 36458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // ensure no entry with the same |client_scopes| is added before the usage of 36558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // the returned entry is done. 36668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const CacheEntry* GetCacheEntry(const RequestParameters& client_scopes); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Removes an access token for the given set of scopes from the cache. 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Returns true if the entry was removed, otherwise false. 37068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool RemoveCacheEntry(const RequestParameters& client_scopes, 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& token_to_remove); 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Called when |fetcher| finishes fetching. 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void OnFetchComplete(Fetcher* fetcher); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 376a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Called when a number of fetchers need to be canceled. 377a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void CancelFetchers(std::vector<Fetcher*> fetchers_to_cancel); 378a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The cache of currently valid tokens. 38068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) typedef std::map<RequestParameters, CacheEntry> TokenCache; 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TokenCache token_cache_; 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A map from fetch parameters to a fetcher that is fetching an OAuth2 access 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // token using these parameters. 38558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) PendingFetcherMap pending_fetchers_; 3867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // List of observers to notify when refresh token availability changes. 3887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Makes sure list is empty on destruction. 3897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ObserverList<Observer, true> observer_list_; 3907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // List of observers to notify when access token status changes. 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ObserverList<DiagnosticsObserver, true> diagnostics_observer_list_; 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The depth of batch changes. 395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int batch_change_depth_; 396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 397eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Maximum number of retries in fetching an OAuth2 access token. 398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static int max_fetch_retry_num_; 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 40068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, RequestParametersOrderTest); 40158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, 40258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) SameScopesRequestedForDifferentClients); 40358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(OAuth2TokenService); 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 407424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif // GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_ 408