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