Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: google_apis/gaia/oauth2_token_service.h

Issue 23382008: Making OAuth2TokenService multi-login aware, updating callers, minor fixes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebasing to include the update to ProfileSyncService: r224220 Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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>
(...skipping 11 matching lines...) Expand all
22 #include "google_apis/gaia/oauth2_access_token_fetcher.h" 22 #include "google_apis/gaia/oauth2_access_token_fetcher.h"
23 23
24 namespace net { 24 namespace net {
25 class URLRequestContextGetter; 25 class URLRequestContextGetter;
26 } 26 }
27 27
28 class GoogleServiceAuthError; 28 class GoogleServiceAuthError;
29 29
30 // 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
31 // tokens. Concrete subclasses should implement GetRefreshToken to return 31 // tokens. Concrete subclasses should implement GetRefreshToken to return
32 // the appropriate refresh token. 32 // the appropriate refresh token. Derived services might maintain refresh tokens
33 // for multiple accounts.
33 // 34 //
34 // All calls are expected from the UI thread. 35 // All calls are expected from the UI thread.
35 // 36 //
36 // To use this service, call StartRequest() with a given set of scopes and a 37 // 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 // 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 // request. The request can be deleted. The consumer may be called back
39 // asynchronously with the fetch results. 40 // asynchronously with the fetch results.
40 // 41 //
41 // - If the consumer is not called back before the request is deleted, it will 42 // - If the consumer is not called back before the request is deleted, it will
42 // never be called back. 43 // never be called back.
(...skipping 26 matching lines...) Expand all
69 // completed. 70 // completed.
70 virtual void OnGetTokenSuccess(const Request* request, 71 virtual void OnGetTokenSuccess(const Request* request,
71 const std::string& access_token, 72 const std::string& access_token,
72 const base::Time& expiration_time) = 0; 73 const base::Time& expiration_time) = 0;
73 virtual void OnGetTokenFailure(const Request* request, 74 virtual void OnGetTokenFailure(const Request* request,
74 const GoogleServiceAuthError& error) = 0; 75 const GoogleServiceAuthError& error) = 0;
75 }; 76 };
76 77
77 // Classes that want to listen for token availability should implement this 78 // Classes that want to listen for token availability should implement this
78 // interface and register with the AddObserver() call. 79 // 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.
81 class Observer { 80 class Observer {
82 public: 81 public:
83 // Called whenever a new login-scoped refresh token is available for 82 // Called whenever a new login-scoped refresh token is available for
84 // account |account_id|. Once available, access tokens can be retrieved for 83 // account |account_id|. Once available, access tokens can be retrieved for
85 // this account. This is called during initial startup for each token 84 // this account. This is called during initial startup for each token
86 // loaded. 85 // loaded.
87 virtual void OnRefreshTokenAvailable(const std::string& account_id) {} 86 virtual void OnRefreshTokenAvailable(const std::string& account_id) {}
88 // Called whenever the login-scoped refresh token becomes unavailable for 87 // Called whenever the login-scoped refresh token becomes unavailable for
89 // account |account_id|. 88 // account |account_id|.
90 virtual void OnRefreshTokenRevoked(const std::string& account_id) {} 89 virtual void OnRefreshTokenRevoked(const std::string& account_id) {}
91 // Called after all refresh tokens are loaded during OAuth2TokenService 90 // Called after all refresh tokens are loaded during OAuth2TokenService
92 // startup. 91 // startup.
93 virtual void OnRefreshTokensLoaded() {} 92 virtual void OnRefreshTokensLoaded() {}
94 // Called after all refresh tokens are removed from OAuth2TokenService.
95 virtual void OnRefreshTokensCleared() {}
96 protected: 93 protected:
97 virtual ~Observer() {} 94 virtual ~Observer() {}
98 }; 95 };
99 96
100 // A set of scopes in OAuth2 authentication. 97 // A set of scopes in OAuth2 authentication.
101 typedef std::set<std::string> ScopeSet; 98 typedef std::set<std::string> ScopeSet;
102 99
103 OAuth2TokenService(); 100 OAuth2TokenService();
104 virtual ~OAuth2TokenService(); 101 virtual ~OAuth2TokenService();
105 102
106 // Add or remove observers of this token service. 103 // Add or remove observers of this token service.
107 void AddObserver(Observer* observer); 104 void AddObserver(Observer* observer);
108 void RemoveObserver(Observer* observer); 105 void RemoveObserver(Observer* observer);
109 106
110 // Checks in the cache for a valid access token, and if not found starts 107 // Checks in the cache for a valid access token for a specified |account_id|
111 // a request for an OAuth2 access token using the OAuth2 refresh token 108 // and |scopes|, and if not found starts a request for an OAuth2 access token
112 // maintained by this instance. The caller owns the returned Request. 109 // using the OAuth2 refresh token maintained by this instance for that
110 // |account_id|. The caller owns the returned Request.
113 // |scopes| is the set of scopes to get an access token for, |consumer| is 111 // |scopes| is the set of scopes to get an access token for, |consumer| is
114 // the object that will be called back with results if the returned request 112 // the object that will be called back with results if the returned request
115 // is not deleted. 113 // is not deleted.
116 // TODO(atwilson): Make this non-virtual when we change 114 // TODO(atwilson): Make this non-virtual when we change
117 // ProfileOAuth2TokenServiceRequestTest to use FakeProfileOAuth2TokenService. 115 // ProfileOAuth2TokenServiceRequestTest to use FakeProfileOAuth2TokenService.
118 virtual scoped_ptr<Request> StartRequest(const ScopeSet& scopes, 116 virtual scoped_ptr<Request> StartRequest(const std::string& account_id,
117 const ScopeSet& scopes,
119 Consumer* consumer); 118 Consumer* consumer);
120 119
121 // This method does the same as |StartRequest| except it uses |client_id| and 120 // This method does the same as |StartRequest| except it uses |client_id| and
122 // |client_secret| to identify OAuth client app instead of using 121 // |client_secret| to identify OAuth client app instead of using
123 // Chrome's default values. 122 // Chrome's default values.
124 scoped_ptr<Request> StartRequestForClient( 123 scoped_ptr<Request> StartRequestForClient(
124 const std::string& account_id,
125 const std::string& client_id, 125 const std::string& client_id,
126 const std::string& client_secret, 126 const std::string& client_secret,
127 const ScopeSet& scopes, 127 const ScopeSet& scopes,
128 Consumer* consumer); 128 Consumer* consumer);
129 129
130 // This method does the same as |StartRequest| except it uses the request 130 // This method does the same as |StartRequest| except it uses the request
131 // context given by |getter| instead of using the one returned by 131 // context given by |getter| instead of using the one returned by
132 // |GetRequestContext| implemented by derived classes. 132 // |GetRequestContext| implemented by derived classes.
133 scoped_ptr<Request> StartRequestWithContext( 133 scoped_ptr<Request> StartRequestWithContext(
134 const std::string& account_id,
134 net::URLRequestContextGetter* getter, 135 net::URLRequestContextGetter* getter,
135 const ScopeSet& scopes, 136 const ScopeSet& scopes,
136 Consumer* consumer); 137 Consumer* consumer);
137 138
138 // Returns true if a refresh token exists. If false, calls to 139 // Lists account IDs of all accounts with a refresh token maintained by this
140 // instance.
141 virtual std::vector<std::string> GetAccounts();
142
143 // Returns true if a refresh token exists for |account_id|. If false, calls to
139 // |StartRequest| will result in a Consumer::OnGetTokenFailure callback. 144 // |StartRequest| will result in a Consumer::OnGetTokenFailure callback.
140 virtual bool RefreshTokenIsAvailable(); 145 virtual bool RefreshTokenIsAvailable(const std::string& account_id);
141 146
142 // Mark an OAuth2 access token as invalid. This should be done if the token 147 // Mark an OAuth2 |access_token| issued for |account_id| and |scopes| as
143 // was received from this class, but was not accepted by the server (e.g., 148 // invalid. This should be done if the token was received from this class,
144 // the server returned 401 Unauthorized). The token will be removed from the 149 // but was not accepted by the server (e.g., the server returned
145 // cache for the given scopes. 150 // 401 Unauthorized). The token will be removed from the cache for the given
146 virtual void InvalidateToken(const ScopeSet& scopes, 151 // scopes.
147 const std::string& invalid_token); 152 void InvalidateToken(const std::string& account_id,
153 const ScopeSet& scopes,
154 const std::string& access_token);
155
156 // Like |InvalidateToken| except is uses |client_id| to identity OAuth2 client
157 // app that issued the request instead of Chrome's default values.
158 void InvalidateTokenForClient(const std::string& account_id,
159 const std::string& client_id,
160 const ScopeSet& scopes,
161 const std::string& access_token);
162
148 163
149 // Return the current number of entries in the cache. 164 // Return the current number of entries in the cache.
150 int cache_size_for_testing() const; 165 int cache_size_for_testing() const;
151 void set_max_authorization_token_fetch_retries_for_testing(int max_retries); 166 void set_max_authorization_token_fetch_retries_for_testing(int max_retries);
152 // Returns the current number of pending fetchers matching given params. 167 // Returns the current number of pending fetchers matching given params.
153 size_t GetNumPendingRequestsForTesting( 168 size_t GetNumPendingRequestsForTesting(
154 const std::string& client_id, 169 const std::string& client_id,
155 const std::string& refresh_token, 170 const std::string& account_id,
156 const ScopeSet& scopes) const; 171 const ScopeSet& scopes) const;
157 172
158 protected: 173 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 174 // Implements a cancelable |OAuth2TokenService::Request|, which should be
170 // operated on the UI thread. 175 // operated on the UI thread.
171 // TODO(davidroche): move this out of header file. 176 // TODO(davidroche): move this out of header file.
172 class RequestImpl : public base::SupportsWeakPtr<RequestImpl>, 177 class RequestImpl : public base::SupportsWeakPtr<RequestImpl>,
173 public base::NonThreadSafe, 178 public base::NonThreadSafe,
174 public Request { 179 public Request {
175 public: 180 public:
176 // |consumer| is required to outlive this. 181 // |consumer| is required to outlive this.
177 explicit RequestImpl(Consumer* consumer); 182 explicit RequestImpl(Consumer* consumer);
178 virtual ~RequestImpl(); 183 virtual ~RequestImpl();
179 184
180 // Informs |consumer_| that this request is completed. 185 // Informs |consumer_| that this request is completed.
181 void InformConsumer(const GoogleServiceAuthError& error, 186 void InformConsumer(const GoogleServiceAuthError& error,
182 const std::string& access_token, 187 const std::string& access_token,
183 const base::Time& expiration_date); 188 const base::Time& expiration_date);
184 189
185 private: 190 private:
186 // |consumer_| to call back when this request completes. 191 // |consumer_| to call back when this request completes.
187 Consumer* const consumer_; 192 Consumer* const consumer_;
188 }; 193 };
189 194
190 // Subclasses should return the refresh token maintained. 195 // Subclasses should return the maintained refresh token for |account_id|.
191 // If no token is available, return an empty string. 196 // If no token is available, return an empty string.
192 virtual std::string GetRefreshToken() = 0; 197 virtual std::string GetRefreshToken(const std::string& account_id) = 0;
193 198
194 // Subclasses can override if they want to report errors to the user. 199 // Subclasses can override if they want to report errors to the user.
195 virtual void UpdateAuthError(const GoogleServiceAuthError& error); 200 virtual void UpdateAuthError(
201 const std::string& account_id,
202 const GoogleServiceAuthError& error);
196 203
197 // Add a new entry to the cache. 204 // Add a new entry to the cache.
198 // Subclasses can override if there are implementation-specific reasons 205 // Subclasses can override if there are implementation-specific reasons
199 // that an access token should ever not be cached. 206 // that an access token should ever not be cached.
200 virtual void RegisterCacheEntry(const std::string& client_id, 207 virtual void RegisterCacheEntry(const std::string& client_id,
201 const std::string& refresh_token, 208 const std::string& account_id,
202 const ScopeSet& scopes, 209 const ScopeSet& scopes,
203 const std::string& access_token, 210 const std::string& access_token,
204 const base::Time& expiration_date); 211 const base::Time& expiration_date);
205 212
206 // Returns true if GetCacheEntry would return a valid cache entry for the
207 // given scopes.
208 bool HasCacheEntry(const ClientScopeSet& client_scopes);
209
210 // Posts a task to fire the Consumer callback with the cached token. Must
211 // Must only be called if HasCacheEntry() returns true.
212 void StartCacheLookupRequest(RequestImpl* request,
213 const ClientScopeSet& client_scopes,
214 Consumer* consumer);
215
216 // Clears the internal token cache. 213 // Clears the internal token cache.
217 void ClearCache(); 214 void ClearCache();
218 215
216 // Clears all of the tokens belonging to |account_id| from the internal token
217 // cache. It does not matter what other parameters, like |client_id| were
218 // used to request the tokens.
219 void ClearCacheForAccount(const std::string& account_id);
220
219 // Cancels all requests that are currently in progress. 221 // Cancels all requests that are currently in progress.
220 void CancelAllRequests(); 222 void CancelAllRequests();
221 223
222 // Cancels all requests related to a given refresh token. 224 // Cancels all requests related to a given |account_id|.
223 void CancelRequestsForToken(const std::string& refresh_token); 225 void CancelRequestsForAccount(const std::string& account_id);
224 226
225 // Called by subclasses to notify observers. 227 // Called by subclasses to notify observers.
226 void FireRefreshTokenAvailable(const std::string& account_id); 228 void FireRefreshTokenAvailable(const std::string& account_id);
227 void FireRefreshTokenRevoked(const std::string& account_id); 229 void FireRefreshTokenRevoked(const std::string& account_id);
228 void FireRefreshTokensLoaded(); 230 void FireRefreshTokensLoaded();
229 void FireRefreshTokensCleared();
230 231
231 // Fetches an OAuth token for the specified client/scopes. Virtual so it can 232 // 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. 233 // be overridden for tests and for platform-specific behavior on Android.
233 virtual void FetchOAuth2Token(RequestImpl* request, 234 virtual void FetchOAuth2Token(RequestImpl* request,
235 const std::string& account_id,
234 net::URLRequestContextGetter* getter, 236 net::URLRequestContextGetter* getter,
235 const std::string& client_id, 237 const std::string& client_id,
236 const std::string& client_secret, 238 const std::string& client_secret,
237 const ScopeSet& scopes); 239 const ScopeSet& scopes);
240
241 // Invalidates the |access_token| issued for |account_id|, |client_id| and
242 // |scopes|. Virtual so it can be overriden for tests and for platform-
243 // specifc behavior.
244 virtual void InvalidateOAuth2Token(const std::string& account_id,
245 const std::string& client_id,
246 const ScopeSet& scopes,
247 const std::string& access_token);
248
238 private: 249 private:
239 class Fetcher; 250 class Fetcher;
240 friend class Fetcher; 251 friend class Fetcher;
241 252
242 // The parameters used to fetch an OAuth2 access token. 253 // The parameters used to fetch an OAuth2 access token.
243 struct FetchParameters { 254 struct RequestParameters {
244 FetchParameters(const std::string& client_id, 255 RequestParameters(const std::string& client_id,
245 const std::string& refresh_token, 256 const std::string& account_id,
246 const ScopeSet& scopes); 257 const ScopeSet& scopes);
247 ~FetchParameters(); 258 ~RequestParameters();
248 bool operator<(const FetchParameters& params) const; 259 bool operator<(const RequestParameters& params) const;
249 260
250 // OAuth2 client id. 261 // OAuth2 client id.
251 std::string client_id; 262 std::string client_id;
252 // Refresh token used for minting access tokens within this request. 263 // Account id for which the request is made.
253 std::string refresh_token; 264 std::string account_id;
254 // URL scopes for the requested access token. 265 // URL scopes for the requested access token.
255 ScopeSet scopes; 266 ScopeSet scopes;
256 }; 267 };
257 268
258 typedef std::map<FetchParameters, Fetcher*> PendingFetcherMap; 269 typedef std::map<RequestParameters, Fetcher*> PendingFetcherMap;
259 270
260 // Derived classes must provide a request context used for fetching access 271 // Derived classes must provide a request context used for fetching access
261 // tokens with the |StartRequest| method. 272 // tokens with the |StartRequest| method.
262 virtual net::URLRequestContextGetter* GetRequestContext() = 0; 273 virtual net::URLRequestContextGetter* GetRequestContext() = 0;
263 274
264 // Struct that contains the information of an OAuth2 access token. 275 // Struct that contains the information of an OAuth2 access token.
265 struct CacheEntry { 276 struct CacheEntry {
266 std::string access_token; 277 std::string access_token;
267 base::Time expiration_date; 278 base::Time expiration_date;
268 }; 279 };
269 280
270 // This method does the same as |StartRequestWithContext| except it 281 // This method does the same as |StartRequestWithContext| except it
271 // uses |client_id| and |client_secret| to identify OAuth 282 // uses |client_id| and |client_secret| to identify OAuth
272 // client app instead of using Chrome's default values. 283 // client app instead of using Chrome's default values.
273 scoped_ptr<Request> StartRequestForClientWithContext( 284 scoped_ptr<Request> StartRequestForClientWithContext(
285 const std::string& account_id,
274 net::URLRequestContextGetter* getter, 286 net::URLRequestContextGetter* getter,
275 const std::string& client_id, 287 const std::string& client_id,
276 const std::string& client_secret, 288 const std::string& client_secret,
277 const ScopeSet& scopes, 289 const ScopeSet& scopes,
278 Consumer* consumer); 290 Consumer* consumer);
279 291
292 // Returns true if GetCacheEntry would return a valid cache entry for the
293 // given scopes.
294 bool HasCacheEntry(const RequestParameters& client_scopes);
295
296 // Posts a task to fire the Consumer callback with the cached token. Must
297 // Must only be called if HasCacheEntry() returns true.
298 void StartCacheLookupRequest(RequestImpl* request,
299 const RequestParameters& client_scopes,
300 Consumer* consumer);
301
280 // Returns a currently valid OAuth2 access token for the given set of scopes, 302 // 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 303 // 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 304 // ensure no entry with the same |client_scopes| is added before the usage of
283 // the returned entry is done. 305 // the returned entry is done.
284 const CacheEntry* GetCacheEntry(const ClientScopeSet& client_scopes); 306 const CacheEntry* GetCacheEntry(const RequestParameters& client_scopes);
285
286 307
287 // Removes an access token for the given set of scopes from the cache. 308 // Removes an access token for the given set of scopes from the cache.
288 // Returns true if the entry was removed, otherwise false. 309 // Returns true if the entry was removed, otherwise false.
289 bool RemoveCacheEntry(const ClientScopeSet& client_scopes, 310 bool RemoveCacheEntry(const RequestParameters& client_scopes,
290 const std::string& token_to_remove); 311 const std::string& token_to_remove);
291 312
292
293 // Called when |fetcher| finishes fetching. 313 // Called when |fetcher| finishes fetching.
294 void OnFetchComplete(Fetcher* fetcher); 314 void OnFetchComplete(Fetcher* fetcher);
295 315
296 // Called when a number of fetchers need to be canceled. 316 // Called when a number of fetchers need to be canceled.
297 void CancelFetchers(std::vector<Fetcher*> fetchers_to_cancel); 317 void CancelFetchers(std::vector<Fetcher*> fetchers_to_cancel);
298 318
299 // The cache of currently valid tokens. 319 // The cache of currently valid tokens.
300 typedef std::map<ClientScopeSet, CacheEntry> TokenCache; 320 typedef std::map<RequestParameters, CacheEntry> TokenCache;
301 TokenCache token_cache_; 321 TokenCache token_cache_;
302 322
303 // A map from fetch parameters to a fetcher that is fetching an OAuth2 access 323 // A map from fetch parameters to a fetcher that is fetching an OAuth2 access
304 // token using these parameters. 324 // token using these parameters.
305 PendingFetcherMap pending_fetchers_; 325 PendingFetcherMap pending_fetchers_;
306 326
307 // List of observers to notify when token availability changes. 327 // List of observers to notify when token availability changes.
308 // Makes sure list is empty on destruction. 328 // Makes sure list is empty on destruction.
309 ObserverList<Observer, true> observer_list_; 329 ObserverList<Observer, true> observer_list_;
310 330
311 // Maximum number of retries in fetching an OAuth2 access token. 331 // Maximum number of retries in fetching an OAuth2 access token.
312 static int max_fetch_retry_num_; 332 static int max_fetch_retry_num_;
313 333
314 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, ClientScopeSetOrderTest); 334 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, RequestParametersOrderTest);
315 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, FetchParametersOrderTest);
316 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, 335 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest,
317 SameScopesRequestedForDifferentClients); 336 SameScopesRequestedForDifferentClients);
318 337
319 DISALLOW_COPY_AND_ASSIGN(OAuth2TokenService); 338 DISALLOW_COPY_AND_ASSIGN(OAuth2TokenService);
320 }; 339 };
321 340
322 #endif // GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_ 341 #endif // GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_H_
OLDNEW
« no previous file with comments | « chrome/browser/ui/webui/print_preview/print_preview_handler.cc ('k') | google_apis/gaia/oauth2_token_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698