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" | |
14 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
15 #include "base/memory/weak_ptr.h" | 14 #include "base/memory/weak_ptr.h" |
16 #include "base/observer_list.h" | 15 #include "base/observer_list.h" |
17 #include "base/threading/non_thread_safe.h" | 16 #include "base/threading/non_thread_safe.h" |
18 #include "base/time/time.h" | 17 #include "base/time/time.h" |
19 #include "base/timer/timer.h" | |
20 #include "google_apis/gaia/google_service_auth_error.h" | 18 #include "google_apis/gaia/google_service_auth_error.h" |
21 #include "google_apis/gaia/oauth2_access_token_consumer.h" | |
22 #include "google_apis/gaia/oauth2_access_token_fetcher.h" | |
23 | 19 |
24 namespace net { | 20 namespace net { |
25 class URLRequestContextGetter; | 21 class URLRequestContextGetter; |
26 } | 22 } |
27 | 23 |
28 class GoogleServiceAuthError; | 24 class GoogleServiceAuthError; |
29 | 25 |
30 // Abstract base class for a service that fetches and caches OAuth2 access | 26 // Abstract base class for a service that fetches and caches OAuth2 access |
31 // tokens. Concrete subclasses should implement GetRefreshToken to return | 27 // tokens. Concrete subclasses should implement GetRefreshToken to return |
32 // the appropriate refresh token. | 28 // the appropriate refresh token. |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 // Mark an OAuth2 access token as invalid. This should be done if the token | 138 // Mark an OAuth2 access token as invalid. This should be done if the token |
143 // was received from this class, but was not accepted by the server (e.g., | 139 // was received from this class, but was not accepted by the server (e.g., |
144 // the server returned 401 Unauthorized). The token will be removed from the | 140 // the server returned 401 Unauthorized). The token will be removed from the |
145 // cache for the given scopes. | 141 // cache for the given scopes. |
146 virtual void InvalidateToken(const ScopeSet& scopes, | 142 virtual void InvalidateToken(const ScopeSet& scopes, |
147 const std::string& invalid_token); | 143 const std::string& invalid_token); |
148 | 144 |
149 // Return the current number of entries in the cache. | 145 // Return the current number of entries in the cache. |
150 int cache_size_for_testing() const; | 146 int cache_size_for_testing() const; |
151 void set_max_authorization_token_fetch_retries_for_testing(int max_retries); | 147 void set_max_authorization_token_fetch_retries_for_testing(int max_retries); |
152 // Returns the current number of pending fetchers matching given params. | |
153 size_t GetNumPendingRequestsForTesting( | |
154 const std::string& client_id, | |
155 const std::string& refresh_token, | |
156 const ScopeSet& scopes) const; | |
157 | 148 |
158 protected: | 149 protected: |
159 struct ClientScopeSet { | |
160 ClientScopeSet(const std::string& client_id, | |
161 const ScopeSet& scopes); | |
162 ~ClientScopeSet(); | |
163 bool operator<(const ClientScopeSet& set) const; | |
164 | |
165 std::string client_id; | |
166 ScopeSet scopes; | |
167 }; | |
168 | |
169 // Implements a cancelable |OAuth2TokenService::Request|, which should be | 150 // Implements a cancelable |OAuth2TokenService::Request|, which should be |
170 // operated on the UI thread. | 151 // operated on the UI thread. |
171 // TODO(davidroche): move this out of header file. | 152 // TODO(davidroche): move this out of header file. |
172 class RequestImpl : public base::SupportsWeakPtr<RequestImpl>, | 153 class RequestImpl : public base::SupportsWeakPtr<RequestImpl>, |
173 public base::NonThreadSafe, | 154 public base::NonThreadSafe, |
174 public Request { | 155 public Request { |
175 public: | 156 public: |
176 // |consumer| is required to outlive this. | 157 // |consumer| is required to outlive this. |
177 explicit RequestImpl(Consumer* consumer); | 158 explicit RequestImpl(Consumer* consumer); |
178 virtual ~RequestImpl(); | 159 virtual ~RequestImpl(); |
(...skipping 11 matching lines...) Expand all Loading... |
190 // Subclasses should return the refresh token maintained. | 171 // Subclasses should return the refresh token maintained. |
191 // If no token is available, return an empty string. | 172 // If no token is available, return an empty string. |
192 virtual std::string GetRefreshToken() = 0; | 173 virtual std::string GetRefreshToken() = 0; |
193 | 174 |
194 // Subclasses can override if they want to report errors to the user. | 175 // Subclasses can override if they want to report errors to the user. |
195 virtual void UpdateAuthError(const GoogleServiceAuthError& error); | 176 virtual void UpdateAuthError(const GoogleServiceAuthError& error); |
196 | 177 |
197 // Add a new entry to the cache. | 178 // Add a new entry to the cache. |
198 // Subclasses can override if there are implementation-specific reasons | 179 // Subclasses can override if there are implementation-specific reasons |
199 // that an access token should ever not be cached. | 180 // that an access token should ever not be cached. |
200 virtual void RegisterCacheEntry(const std::string& client_id, | 181 virtual void RegisterCacheEntry(const std::string& refresh_token, |
201 const std::string& refresh_token, | |
202 const ScopeSet& scopes, | 182 const ScopeSet& scopes, |
203 const std::string& access_token, | 183 const std::string& access_token, |
204 const base::Time& expiration_date); | 184 const base::Time& expiration_date); |
205 | 185 |
206 // Returns true if GetCacheEntry would return a valid cache entry for the | 186 // Returns true if GetCacheEntry would return a valid cache entry for the |
207 // given scopes. | 187 // given scopes. |
208 bool HasCacheEntry(const ClientScopeSet& client_scopes); | 188 bool HasCacheEntry(const ScopeSet& scopes); |
209 | 189 |
210 // Posts a task to fire the Consumer callback with the cached token. Must | 190 // Posts a task to fire the Consumer callback with the cached token. Must |
211 // Must only be called if HasCacheEntry() returns true. | 191 // Must only be called if HasCacheEntry() returns true. |
212 void StartCacheLookupRequest(RequestImpl* request, | 192 void StartCacheLookupRequest(RequestImpl* request, |
213 const ClientScopeSet& client_scopes, | 193 const ScopeSet& scopes, |
214 Consumer* consumer); | 194 Consumer* consumer); |
215 | 195 |
216 // Clears the internal token cache. | 196 // Clears the internal token cache. |
217 void ClearCache(); | 197 void ClearCache(); |
218 | 198 |
219 // Cancels all requests that are currently in progress. | 199 // Cancels all requests that are currently in progress. |
220 void CancelAllRequests(); | 200 void CancelAllRequests(); |
221 | 201 |
222 // Cancels all requests related to a given refresh token. | 202 // Cancels all requests related to a given refresh token. |
223 void CancelRequestsForToken(const std::string& refresh_token); | 203 void CancelRequestsForToken(const std::string& refresh_token); |
224 | 204 |
225 // Called by subclasses to notify observers. | 205 // Called by subclasses to notify observers. |
226 void FireRefreshTokenAvailable(const std::string& account_id); | 206 void FireRefreshTokenAvailable(const std::string& account_id); |
227 void FireRefreshTokenRevoked(const std::string& account_id); | 207 void FireRefreshTokenRevoked(const std::string& account_id); |
228 void FireRefreshTokensLoaded(); | 208 void FireRefreshTokensLoaded(); |
229 void FireRefreshTokensCleared(); | 209 void FireRefreshTokensCleared(); |
230 | 210 |
| 211 // Derived classes must provide a request context used for fetching access |
| 212 // tokens with the |StartRequest| method. |
| 213 virtual net::URLRequestContextGetter* GetRequestContext() = 0; |
| 214 |
231 // Fetches an OAuth token for the specified client/scopes. Virtual so it can | 215 // Fetches an OAuth token for the specified client/scopes. Virtual so it can |
232 // be overridden for tests and for platform-specific behavior on Android. | 216 // be overridden for tests and for platform-specific behavior on Android. |
233 virtual void FetchOAuth2Token(RequestImpl* request, | 217 virtual void FetchOAuth2Token(RequestImpl* request, |
234 net::URLRequestContextGetter* getter, | 218 net::URLRequestContextGetter* getter, |
235 const std::string& client_id, | 219 const std::string& client_id, |
236 const std::string& client_secret, | 220 const std::string& client_secret, |
237 const ScopeSet& scopes); | 221 const ScopeSet& scopes); |
| 222 |
238 private: | 223 private: |
| 224 // Class that fetches an OAuth2 access token for a given set of scopes and |
| 225 // OAuth2 refresh token. |
239 class Fetcher; | 226 class Fetcher; |
240 friend class Fetcher; | 227 friend class Fetcher; |
241 | 228 |
242 // The parameters used to fetch an OAuth2 access token. | |
243 struct FetchParameters { | |
244 FetchParameters(const std::string& client_id, | |
245 const std::string& refresh_token, | |
246 const ScopeSet& scopes); | |
247 ~FetchParameters(); | |
248 bool operator<(const FetchParameters& params) const; | |
249 | |
250 // OAuth2 client id. | |
251 std::string client_id; | |
252 // Refresh token used for minting access tokens within this request. | |
253 std::string refresh_token; | |
254 // URL scopes for the requested access token. | |
255 ScopeSet scopes; | |
256 }; | |
257 | |
258 typedef std::map<FetchParameters, Fetcher*> PendingFetcherMap; | |
259 | |
260 // Derived classes must provide a request context used for fetching access | |
261 // tokens with the |StartRequest| method. | |
262 virtual net::URLRequestContextGetter* GetRequestContext() = 0; | |
263 | |
264 // Struct that contains the information of an OAuth2 access token. | 229 // Struct that contains the information of an OAuth2 access token. |
265 struct CacheEntry { | 230 struct CacheEntry { |
266 std::string access_token; | 231 std::string access_token; |
267 base::Time expiration_date; | 232 base::Time expiration_date; |
268 }; | 233 }; |
269 | 234 |
270 // This method does the same as |StartRequestWithContext| except it | 235 // This method does the same as |StartRequestWithContext| except it |
271 // uses |client_id| and |client_secret| to identify OAuth | 236 // uses |client_id| and |client_secret| to identify OAuth |
272 // client app instead of using Chrome's default values. | 237 // client app instead of using Chrome's default values. |
273 scoped_ptr<Request> StartRequestForClientWithContext( | 238 scoped_ptr<Request> StartRequestForClientWithContext( |
274 net::URLRequestContextGetter* getter, | 239 net::URLRequestContextGetter* getter, |
275 const std::string& client_id, | 240 const std::string& client_id, |
276 const std::string& client_secret, | 241 const std::string& client_secret, |
277 const ScopeSet& scopes, | 242 const ScopeSet& scopes, |
278 Consumer* consumer); | 243 Consumer* consumer); |
279 | 244 |
280 // Returns a currently valid OAuth2 access token for the given set of scopes, | 245 // Returns a currently valid OAuth2 access token for the given set of scopes, |
281 // or NULL if none have been cached. Note the user of this method should | 246 // or NULL if none have been cached. Note the user of this method should |
282 // ensure no entry with the same |client_scopes| is added before the usage of | 247 // ensure no entry with the same |scopes| is added before the usage of the |
283 // the returned entry is done. | 248 // returned entry is done. |
284 const CacheEntry* GetCacheEntry(const ClientScopeSet& client_scopes); | 249 const CacheEntry* GetCacheEntry(const ScopeSet& scopes); |
285 | 250 |
286 | 251 |
287 // Removes an access token for the given set of scopes from the cache. | 252 // Removes an access token for the given set of scopes from the cache. |
288 // Returns true if the entry was removed, otherwise false. | 253 // Returns true if the entry was removed, otherwise false. |
289 bool RemoveCacheEntry(const ClientScopeSet& client_scopes, | 254 bool RemoveCacheEntry(const OAuth2TokenService::ScopeSet& scopes, |
290 const std::string& token_to_remove); | 255 const std::string& token_to_remove); |
291 | 256 |
292 | 257 |
293 // Called when |fetcher| finishes fetching. | 258 // Called when |fetcher| finishes fetching. |
294 void OnFetchComplete(Fetcher* fetcher); | 259 void OnFetchComplete(Fetcher* fetcher); |
295 | 260 |
296 // Called when a number of fetchers need to be canceled. | 261 // Called when a number of fetchers need to be canceled. |
297 void CancelFetchers(std::vector<Fetcher*> fetchers_to_cancel); | 262 void CancelFetchers(std::vector<Fetcher*> fetchers_to_cancel); |
298 | 263 |
299 // The cache of currently valid tokens. | 264 // The cache of currently valid tokens. |
300 typedef std::map<ClientScopeSet, CacheEntry> TokenCache; | 265 typedef std::map<ScopeSet, CacheEntry> TokenCache; |
301 TokenCache token_cache_; | 266 TokenCache token_cache_; |
302 | 267 |
| 268 // The parameters (refresh token and scope set) used to fetch an OAuth2 access |
| 269 // token. |
| 270 typedef std::pair<std::string, ScopeSet> FetchParameters; |
303 // A map from fetch parameters to a fetcher that is fetching an OAuth2 access | 271 // A map from fetch parameters to a fetcher that is fetching an OAuth2 access |
304 // token using these parameters. | 272 // token using these parameters. |
305 PendingFetcherMap pending_fetchers_; | 273 std::map<FetchParameters, Fetcher*> pending_fetchers_; |
306 | 274 |
307 // List of observers to notify when token availability changes. | 275 // List of observers to notify when token availability changes. |
308 // Makes sure list is empty on destruction. | 276 // Makes sure list is empty on destruction. |
309 ObserverList<Observer, true> observer_list_; | 277 ObserverList<Observer, true> observer_list_; |
310 | 278 |
311 // Maximum number of retries in fetching an OAuth2 access token. | 279 // Maximum number of retries in fetching an OAuth2 access token. |
312 static int max_fetch_retry_num_; | 280 static int max_fetch_retry_num_; |
313 | 281 |
314 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, ClientScopeSetOrderTest); | |
315 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, FetchParametersOrderTest); | |
316 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, | |
317 SameScopesRequestedForDifferentClients); | |
318 | |
319 DISALLOW_COPY_AND_ASSIGN(OAuth2TokenService); | 282 DISALLOW_COPY_AND_ASSIGN(OAuth2TokenService); |
320 }; | 283 }; |
321 | 284 |
322 #endif // GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_ | 285 #endif // GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_ |
OLD | NEW |