1 // Copyright 2012 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 CHROME_BROWSER_SIGNIN_OAUTH2_TOKEN_SERVICE_H_
6 #define CHROME_BROWSER_SIGNIN_OAUTH2_TOKEN_SERVICE_H_
12 #include "base/basictypes.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/observer_list.h"
17 #include "base/time/time.h"
18 #include "google_apis/gaia/google_service_auth_error.h"
25 class URLRequestContextGetter
;
28 class GoogleServiceAuthError
;
30 // Abstract base class for a service that fetches and caches OAuth2 access
31 // tokens. Concrete subclasses should implement GetRefreshToken to return
32 // the appropriate refresh token.
34 // All calls are expected from the UI thread.
36 // To use this service, call StartRequest() with a given set of scopes and a
37 // consumer of the request results. The consumer is required to outlive the
38 // request. The request can be deleted. The consumer may be called back
39 // asynchronously with the fetch results.
41 // - If the consumer is not called back before the request is deleted, it will
42 // never be called back.
43 // Note in this case, the actual network requests are not canceled and the
44 // cache will be populated with the fetched results; it is just the consumer
45 // callback that is aborted.
47 // - Otherwise the consumer will be called back with the request and the fetch
50 // The caller of StartRequest() owns the returned request and is responsible to
51 // delete the request even once the callback has been invoked.
52 class OAuth2TokenService
{
54 // Class representing a request that fetches an OAuth2 access token.
62 // Class representing the consumer of a Request passed to |StartRequest|,
63 // which will be called back when the request completes.
68 // |request| is a Request that is started by this consumer and has
70 virtual void OnGetTokenSuccess(const Request
* request
,
71 const std::string
& access_token
,
72 const base::Time
& expiration_time
) = 0;
73 virtual void OnGetTokenFailure(const Request
* request
,
74 const GoogleServiceAuthError
& error
) = 0;
77 // Classes that want to listen for token availability should implement this
78 // interface and register with the AddObserver() call.
79 // TODO(rogerta): may get rid of |error| argument for OnRefreshTokenRevoked()
80 // once we stop supporting ClientLogin. Need to evaluate if its still useful.
83 // Called whenever a new login-scoped refresh token is available for
84 // account |account_id|. Once available, access tokens can be retrieved for
85 // this account. This is called during initial startup for each token
87 virtual void OnRefreshTokenAvailable(const std::string
& account_id
) {}
88 // Called whenever the login-scoped refresh token becomes unavailable for
89 // account |account_id|.
90 virtual void OnRefreshTokenRevoked(const std::string
& account_id
,
91 const GoogleServiceAuthError
& error
) {}
92 // Called after all refresh tokens are loaded during OAuth2TokenService
94 virtual void OnRefreshTokensLoaded() {}
95 // Called after all refresh tokens are removed from OAuth2TokenService.
96 virtual void OnRefreshTokensCleared() {}
98 virtual ~Observer() {}
101 // A set of scopes in OAuth2 authentication.
102 typedef std::set
<std::string
> ScopeSet
;
104 explicit OAuth2TokenService(net::URLRequestContextGetter
* getter
);
105 virtual ~OAuth2TokenService();
107 // Add or remove observers of this token service.
108 void AddObserver(Observer
* observer
);
109 void RemoveObserver(Observer
* observer
);
111 // Checks in the cache for a valid access token, and if not found starts
112 // a request for an OAuth2 access token using the OAuth2 refresh token
113 // maintained by this instance. The caller owns the returned Request.
114 // |scopes| is the set of scopes to get an access token for, |consumer| is
115 // the object that will be called back with results if the returned request
117 virtual scoped_ptr
<Request
> StartRequest(const ScopeSet
& scopes
,
120 // Returns true if a refresh token exists. If false, calls to
121 // |StartRequest| will result in a Consumer::OnGetTokenFailure callback.
122 virtual bool RefreshTokenIsAvailable();
124 // Mark an OAuth2 access token as invalid. This should be done if the token
125 // was received from this class, but was not accepted by the server (e.g.,
126 // the server returned 401 Unauthorized). The token will be removed from the
127 // cache for the given scopes.
128 virtual void InvalidateToken(const ScopeSet
& scopes
,
129 const std::string
& invalid_token
);
131 // Return the current number of entries in the cache.
132 int cache_size_for_testing() const;
133 void set_max_authorization_token_fetch_retries_for_testing(int max_retries
);
136 // Implements a cancelable |OAuth2TokenService::Request|, which should be
137 // operated on the UI thread.
138 // TODO(davidroche): move this out of header file.
139 class RequestImpl
: public base::SupportsWeakPtr
<RequestImpl
>,
142 // |consumer| is required to outlive this.
143 explicit RequestImpl(Consumer
* consumer
);
144 virtual ~RequestImpl();
146 // Informs |consumer_| that this request is completed.
147 void InformConsumer(const GoogleServiceAuthError
& error
,
148 const std::string
& access_token
,
149 const base::Time
& expiration_date
);
152 // |consumer_| to call back when this request completes.
153 Consumer
* const consumer_
;
156 // Subclasses should return the refresh token maintained.
157 // If no token is available, return an empty string.
158 virtual std::string
GetRefreshToken() = 0;
160 // Subclasses can override if they want to report errors to the user.
161 virtual void UpdateAuthError(const GoogleServiceAuthError
& error
);
163 // Add a new entry to the cache.
164 // Subclasses can override if there are implementation-specific reasons
165 // that an access token should ever not be cached.
166 virtual void RegisterCacheEntry(const std::string
& refresh_token
,
167 const ScopeSet
& scopes
,
168 const std::string
& access_token
,
169 const base::Time
& expiration_date
);
171 // Returns true if GetCacheEntry would return a valid cache entry for the
173 bool HasCacheEntry(const ScopeSet
& scopes
);
175 // Posts a task to fire the Consumer callback with the cached token. Must
176 // Must only be called if HasCacheEntry() returns true.
177 scoped_ptr
<Request
> StartCacheLookupRequest(const ScopeSet
& scopes
,
180 // Clears the internal token cache.
183 // Called by subclasses to notify observers.
184 void FireRefreshTokenAvailable(const std::string
& account_id
);
185 void FireRefreshTokenRevoked(const std::string
& account_id
,
186 const GoogleServiceAuthError
& error
);
187 void FireRefreshTokensLoaded();
188 void FireRefreshTokensCleared();
191 // Class that fetches an OAuth2 access token for a given set of scopes and
192 // OAuth2 refresh token.
194 friend class Fetcher
;
196 // Struct that contains the information of an OAuth2 access token.
198 std::string access_token
;
199 base::Time expiration_date
;
202 // Returns a currently valid OAuth2 access token for the given set of scopes,
203 // or NULL if none have been cached. Note the user of this method should
204 // ensure no entry with the same |scopes| is added before the usage of the
205 // returned entry is done.
206 const CacheEntry
* GetCacheEntry(const ScopeSet
& scopes
);
209 // Removes an access token for the given set of scopes from the cache.
210 // Returns true if the entry was removed, otherwise false.
211 bool RemoveCacheEntry(const OAuth2TokenService::ScopeSet
& scopes
,
212 const std::string
& token_to_remove
);
215 // Called when |fetcher| finishes fetching.
216 void OnFetchComplete(Fetcher
* fetcher
);
218 // Getter to use for fetchers.
219 scoped_refptr
<net::URLRequestContextGetter
> request_context_getter_
;
221 // The cache of currently valid tokens.
222 typedef std::map
<ScopeSet
, CacheEntry
> TokenCache
;
223 TokenCache token_cache_
;
225 // The parameters (refresh token and scope set) used to fetch an OAuth2 access
227 typedef std::pair
<std::string
, ScopeSet
> FetchParameters
;
228 // A map from fetch parameters to a fetcher that is fetching an OAuth2 access
229 // token using these parameters.
230 std::map
<FetchParameters
, Fetcher
*> pending_fetchers_
;
232 // List of observers to notify when token availiability changes.
233 // Makes sure list is empty on destruction.
234 ObserverList
<Observer
, true> observer_list_
;
236 // Maximum number of retries in fetching an OAuth2 access token.
237 static int max_fetch_retry_num_
;
239 DISALLOW_COPY_AND_ASSIGN(OAuth2TokenService
);
242 #endif // CHROME_BROWSER_SIGNIN_OAUTH2_TOKEN_SERVICE_H_