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

Side by Side Diff: chrome/browser/signin/oauth2_token_service.cc

Issue 22581003: Handling of multiple concurrent requests from different clients in OAuth2TokenService (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 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 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 #include "chrome/browser/signin/oauth2_token_service.h" 5 #include "chrome/browser/signin/oauth2_token_service.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/memory/weak_ptr.h" 10 #include "base/memory/weak_ptr.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/rand_util.h" 12 #include "base/rand_util.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/time/time.h" 14 #include "base/time/time.h"
15 #include "base/timer/timer.h" 15 #include "base/timer/timer.h"
16 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
17 #include "google_apis/gaia/gaia_urls.h" 17 #include "google_apis/gaia/gaia_urls.h"
18 #include "google_apis/gaia/google_service_auth_error.h" 18 #include "google_apis/gaia/google_service_auth_error.h"
19 #include "google_apis/gaia/oauth2_access_token_consumer.h" 19 #include "google_apis/gaia/oauth2_access_token_consumer.h"
20 #include "google_apis/gaia/oauth2_access_token_fetcher.h" 20 #include "google_apis/gaia/oauth2_access_token_fetcher.h"
21 #include "net/url_request/url_request_context_getter.h" 21 #include "net/url_request/url_request_context_getter.h"
22 22
23 int OAuth2TokenService::max_fetch_retry_num_ = 5; 23 int OAuth2TokenService::max_fetch_retry_num_ = 5;
24 24
25 OAuth2TokenService::ClientScopeSet::ClientScopeSet(
26 const std::string& request_origin,
27 const std::string& client_id,
28 const ScopeSet& scopes)
29 : request_origin(request_origin),
30 client_id(client_id),
31 scopes(scopes) {
32 }
33
34 bool OAuth2TokenService::ClientScopeSet::operator<(
35 const ClientScopeSet& set) const {
fgorski 2013/08/08 17:25:33 Will this produce strict weak ordering required by
zel 2013/08/08 19:15:18 The ordering should be fixed now and covered with
36 if (request_origin < set.request_origin)
37 return true;
38
39 if (client_id < set.client_id)
40 return true;
41
42 if (scopes < set.scopes)
43 return true;
44
45 return false;
46 }
47
48 OAuth2TokenService::FetchParameters::FetchParameters(
49 const std::string& request_origin,
50 const std::string& client_id,
51 const std::string& refresh_token,
52 const ScopeSet& scopes)
53 : request_origin(request_origin),
54 client_id(client_id),
55 refresh_token(refresh_token),
56 scopes(scopes) {
57 }
58
59 bool OAuth2TokenService::FetchParameters::operator<(
60 const FetchParameters& params) const {
fgorski 2013/08/08 17:25:33 Same comment as implementation of the ClientScopeS
zel 2013/08/08 18:31:20 you are absolutely right good catch! fixing that n
zel 2013/08/08 19:15:18 Done.
61 if (request_origin < params.request_origin)
62 return true;
63
64 if (client_id < params.client_id)
65 return true;
66
67 if (refresh_token < params.refresh_token)
68 return true;
69
70 if (scopes < params.scopes)
71 return true;
72
73 return false;
74 }
75
25 OAuth2TokenService::RequestImpl::RequestImpl( 76 OAuth2TokenService::RequestImpl::RequestImpl(
26 OAuth2TokenService::Consumer* consumer) 77 OAuth2TokenService::Consumer* consumer)
27 : consumer_(consumer) { 78 : consumer_(consumer) {
28 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 79 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
29 } 80 }
30 81
31 OAuth2TokenService::RequestImpl::~RequestImpl() { 82 OAuth2TokenService::RequestImpl::~RequestImpl() {
32 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 83 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
33 } 84 }
34 85
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 // - when the Fetcher is destructed if the Fetcher is destructed before it 121 // - when the Fetcher is destructed if the Fetcher is destructed before it
71 // completes fetching (in this case, the waiting requests will be called back 122 // completes fetching (in this case, the waiting requests will be called back
72 // with error). 123 // with error).
73 class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer { 124 class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer {
74 public: 125 public:
75 // Creates a Fetcher and starts fetching an OAuth2 access token for 126 // Creates a Fetcher and starts fetching an OAuth2 access token for
76 // |refresh_token| and |scopes| in the request context obtained by |getter|. 127 // |refresh_token| and |scopes| in the request context obtained by |getter|.
77 // The given |oauth2_token_service| will be informed when fetching is done. 128 // The given |oauth2_token_service| will be informed when fetching is done.
78 static Fetcher* CreateAndStart(OAuth2TokenService* oauth2_token_service, 129 static Fetcher* CreateAndStart(OAuth2TokenService* oauth2_token_service,
79 net::URLRequestContextGetter* getter, 130 net::URLRequestContextGetter* getter,
80 const std::string& chrome_client_id, 131 const std::string& request_origin,
81 const std::string& chrome_client_secret, 132 const std::string& client_id,
133 const std::string& client_secret,
82 const std::string& refresh_token, 134 const std::string& refresh_token,
83 const OAuth2TokenService::ScopeSet& scopes, 135 const OAuth2TokenService::ScopeSet& scopes,
84 base::WeakPtr<RequestImpl> waiting_request); 136 base::WeakPtr<RequestImpl> waiting_request);
85 virtual ~Fetcher(); 137 virtual ~Fetcher();
86 138
87 // Add a request that is waiting for the result of this Fetcher. 139 // Add a request that is waiting for the result of this Fetcher.
88 void AddWaitingRequest(base::WeakPtr<RequestImpl> waiting_request); 140 void AddWaitingRequest(base::WeakPtr<RequestImpl> waiting_request);
89 141
90 void Cancel(); 142 void Cancel();
91 143
92 const OAuth2TokenService::ScopeSet& GetScopeSet() const; 144 const OAuth2TokenService::ScopeSet& GetScopeSet() const;
93 const std::string& GetRefreshToken() const; 145 const std::string& GetRefreshToken() const;
146 const std::string& GetClientId() const;
147 const std::string& GetRequestOrigin() const;
94 148
95 // The error result from this fetcher. 149 // The error result from this fetcher.
96 const GoogleServiceAuthError& error() const { return error_; } 150 const GoogleServiceAuthError& error() const { return error_; }
97 151
98 protected: 152 protected:
99 // OAuth2AccessTokenConsumer 153 // OAuth2AccessTokenConsumer
100 virtual void OnGetTokenSuccess(const std::string& access_token, 154 virtual void OnGetTokenSuccess(const std::string& access_token,
101 const base::Time& expiration_date) OVERRIDE; 155 const base::Time& expiration_date) OVERRIDE;
102 virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) OVERRIDE; 156 virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) OVERRIDE;
103 157
104 private: 158 private:
105 Fetcher(OAuth2TokenService* oauth2_token_service, 159 Fetcher(OAuth2TokenService* oauth2_token_service,
106 net::URLRequestContextGetter* getter, 160 net::URLRequestContextGetter* getter,
107 const std::string& chrome_client_id, 161 const std::string& request_origin,
108 const std::string& chrome_client_secret, 162 const std::string& client_id,
163 const std::string& client_secret,
109 const std::string& refresh_token, 164 const std::string& refresh_token,
110 const OAuth2TokenService::ScopeSet& scopes, 165 const OAuth2TokenService::ScopeSet& scopes,
111 base::WeakPtr<RequestImpl> waiting_request); 166 base::WeakPtr<RequestImpl> waiting_request);
112 void Start(); 167 void Start();
113 void InformWaitingRequests(); 168 void InformWaitingRequests();
114 void InformWaitingRequestsAndDelete(); 169 void InformWaitingRequestsAndDelete();
115 static bool ShouldRetry(const GoogleServiceAuthError& error); 170 static bool ShouldRetry(const GoogleServiceAuthError& error);
116 int64 ComputeExponentialBackOffMilliseconds(int retry_num); 171 int64 ComputeExponentialBackOffMilliseconds(int retry_num);
117 172
118 // |oauth2_token_service_| remains valid for the life of this Fetcher, since 173 // |oauth2_token_service_| remains valid for the life of this Fetcher, since
119 // this Fetcher is destructed in the dtor of the OAuth2TokenService or is 174 // this Fetcher is destructed in the dtor of the OAuth2TokenService or is
120 // scheduled for deletion at the end of OnGetTokenFailure/OnGetTokenSuccess 175 // scheduled for deletion at the end of OnGetTokenFailure/OnGetTokenSuccess
121 // (whichever comes first). 176 // (whichever comes first).
122 OAuth2TokenService* const oauth2_token_service_; 177 OAuth2TokenService* const oauth2_token_service_;
123 scoped_refptr<net::URLRequestContextGetter> getter_; 178 scoped_refptr<net::URLRequestContextGetter> getter_;
124 const std::string refresh_token_; 179 const std::string refresh_token_;
125 const OAuth2TokenService::ScopeSet scopes_; 180 const OAuth2TokenService::ScopeSet scopes_;
126 std::vector<base::WeakPtr<RequestImpl> > waiting_requests_; 181 std::vector<base::WeakPtr<RequestImpl> > waiting_requests_;
127 182
128 int retry_number_; 183 int retry_number_;
129 base::OneShotTimer<OAuth2TokenService::Fetcher> retry_timer_; 184 base::OneShotTimer<OAuth2TokenService::Fetcher> retry_timer_;
130 scoped_ptr<OAuth2AccessTokenFetcher> fetcher_; 185 scoped_ptr<OAuth2AccessTokenFetcher> fetcher_;
131 186
132 // Variables that store fetch results. 187 // Variables that store fetch results.
133 // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle 188 // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle
134 // destruction. 189 // destruction.
135 GoogleServiceAuthError error_; 190 GoogleServiceAuthError error_;
136 std::string access_token_; 191 std::string access_token_;
137 base::Time expiration_date_; 192 base::Time expiration_date_;
193
194 // Token fetch request origin identifier.
195 std::string request_origin_;
196
138 // OAuth2 client id and secret. 197 // OAuth2 client id and secret.
139 std::string chrome_client_id_; 198 std::string client_id_;
140 std::string chrome_client_secret_; 199 std::string client_secret_;
141 200
142 DISALLOW_COPY_AND_ASSIGN(Fetcher); 201 DISALLOW_COPY_AND_ASSIGN(Fetcher);
143 }; 202 };
144 203
145 // static 204 // static
146 OAuth2TokenService::Fetcher* OAuth2TokenService::Fetcher::CreateAndStart( 205 OAuth2TokenService::Fetcher* OAuth2TokenService::Fetcher::CreateAndStart(
147 OAuth2TokenService* oauth2_token_service, 206 OAuth2TokenService* oauth2_token_service,
148 net::URLRequestContextGetter* getter, 207 net::URLRequestContextGetter* getter,
149 const std::string& chrome_client_id, 208 const std::string& request_origin,
150 const std::string& chrome_client_secret, 209 const std::string& client_id,
210 const std::string& client_secret,
151 const std::string& refresh_token, 211 const std::string& refresh_token,
152 const OAuth2TokenService::ScopeSet& scopes, 212 const OAuth2TokenService::ScopeSet& scopes,
153 base::WeakPtr<RequestImpl> waiting_request) { 213 base::WeakPtr<RequestImpl> waiting_request) {
154 OAuth2TokenService::Fetcher* fetcher = new Fetcher( 214 OAuth2TokenService::Fetcher* fetcher = new Fetcher(
155 oauth2_token_service, 215 oauth2_token_service,
156 getter, 216 getter,
157 chrome_client_id, 217 request_origin,
158 chrome_client_secret, 218 client_id,
219 client_secret,
159 refresh_token, 220 refresh_token,
160 scopes, 221 scopes,
161 waiting_request); 222 waiting_request);
162 fetcher->Start(); 223 fetcher->Start();
163 return fetcher; 224 return fetcher;
164 } 225 }
165 226
166 OAuth2TokenService::Fetcher::Fetcher( 227 OAuth2TokenService::Fetcher::Fetcher(
167 OAuth2TokenService* oauth2_token_service, 228 OAuth2TokenService* oauth2_token_service,
168 net::URLRequestContextGetter* getter, 229 net::URLRequestContextGetter* getter,
169 const std::string& chrome_client_id, 230 const std::string& request_origin,
170 const std::string& chrome_client_secret, 231 const std::string& client_id,
232 const std::string& client_secret,
171 const std::string& refresh_token, 233 const std::string& refresh_token,
172 const OAuth2TokenService::ScopeSet& scopes, 234 const OAuth2TokenService::ScopeSet& scopes,
173 base::WeakPtr<RequestImpl> waiting_request) 235 base::WeakPtr<RequestImpl> waiting_request)
174 : oauth2_token_service_(oauth2_token_service), 236 : oauth2_token_service_(oauth2_token_service),
175 getter_(getter), 237 getter_(getter),
176 refresh_token_(refresh_token), 238 refresh_token_(refresh_token),
177 scopes_(scopes), 239 scopes_(scopes),
178 retry_number_(0), 240 retry_number_(0),
179 error_(GoogleServiceAuthError::SERVICE_UNAVAILABLE), 241 error_(GoogleServiceAuthError::SERVICE_UNAVAILABLE),
180 chrome_client_id_(chrome_client_id), 242 request_origin_(request_origin),
181 chrome_client_secret_(chrome_client_secret) { 243 client_id_(client_id),
244 client_secret_(client_secret) {
182 DCHECK(oauth2_token_service_); 245 DCHECK(oauth2_token_service_);
183 DCHECK(getter_.get()); 246 DCHECK(getter_.get());
184 DCHECK(refresh_token_.length()); 247 DCHECK(refresh_token_.length());
185 waiting_requests_.push_back(waiting_request); 248 waiting_requests_.push_back(waiting_request);
186 } 249 }
187 250
188 OAuth2TokenService::Fetcher::~Fetcher() { 251 OAuth2TokenService::Fetcher::~Fetcher() {
189 // Inform the waiting requests if it has not done so. 252 // Inform the waiting requests if it has not done so.
190 if (waiting_requests_.size()) 253 if (waiting_requests_.size())
191 InformWaitingRequests(); 254 InformWaitingRequests();
192 } 255 }
193 256
194 void OAuth2TokenService::Fetcher::Start() { 257 void OAuth2TokenService::Fetcher::Start() {
195 fetcher_.reset(new OAuth2AccessTokenFetcher(this, getter_.get())); 258 fetcher_.reset(new OAuth2AccessTokenFetcher(this, getter_.get()));
196 fetcher_->Start(chrome_client_id_, 259 fetcher_->Start(client_id_,
197 chrome_client_secret_, 260 client_secret_,
198 refresh_token_, 261 refresh_token_,
199 std::vector<std::string>(scopes_.begin(), scopes_.end())); 262 std::vector<std::string>(scopes_.begin(), scopes_.end()));
200 retry_timer_.Stop(); 263 retry_timer_.Stop();
201 } 264 }
202 265
203 void OAuth2TokenService::Fetcher::OnGetTokenSuccess( 266 void OAuth2TokenService::Fetcher::OnGetTokenSuccess(
204 const std::string& access_token, 267 const std::string& access_token,
205 const base::Time& expiration_date) { 268 const base::Time& expiration_date) {
206 fetcher_.reset(); 269 fetcher_.reset();
207 270
208 // Fetch completes. 271 // Fetch completes.
209 error_ = GoogleServiceAuthError::AuthErrorNone(); 272 error_ = GoogleServiceAuthError::AuthErrorNone();
210 access_token_ = access_token; 273 access_token_ = access_token;
211 expiration_date_ = expiration_date; 274 expiration_date_ = expiration_date;
212 275
213 // Subclasses may override this method to skip caching in some cases, but 276 // Subclasses may override this method to skip caching in some cases, but
214 // we still inform all waiting Consumers of a successful token fetch below. 277 // we still inform all waiting Consumers of a successful token fetch below.
215 // This is intentional -- some consumers may need the token for cleanup 278 // This is intentional -- some consumers may need the token for cleanup
216 // tasks. https://chromiumcodereview.appspot.com/11312124/ 279 // tasks. https://chromiumcodereview.appspot.com/11312124/
217 oauth2_token_service_->RegisterCacheEntry(refresh_token_, 280 oauth2_token_service_->RegisterCacheEntry(request_origin_,
281 client_id_,
282 refresh_token_,
218 scopes_, 283 scopes_,
219 access_token_, 284 access_token_,
220 expiration_date_); 285 expiration_date_);
221 InformWaitingRequestsAndDelete(); 286 InformWaitingRequestsAndDelete();
222 } 287 }
223 288
224 void OAuth2TokenService::Fetcher::OnGetTokenFailure( 289 void OAuth2TokenService::Fetcher::OnGetTokenFailure(
225 const GoogleServiceAuthError& error) { 290 const GoogleServiceAuthError& error) {
226 fetcher_.reset(); 291 fetcher_.reset();
227 292
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 357
293 const OAuth2TokenService::ScopeSet& OAuth2TokenService::Fetcher::GetScopeSet() 358 const OAuth2TokenService::ScopeSet& OAuth2TokenService::Fetcher::GetScopeSet()
294 const { 359 const {
295 return scopes_; 360 return scopes_;
296 } 361 }
297 362
298 const std::string& OAuth2TokenService::Fetcher::GetRefreshToken() const { 363 const std::string& OAuth2TokenService::Fetcher::GetRefreshToken() const {
299 return refresh_token_; 364 return refresh_token_;
300 } 365 }
301 366
367 const std::string& OAuth2TokenService::Fetcher::GetClientId() const {
368 return client_id_;
369 }
370
371 const std::string& OAuth2TokenService::Fetcher::GetRequestOrigin() const {
372 return request_origin_;
373 }
374
302 OAuth2TokenService::Request::Request() { 375 OAuth2TokenService::Request::Request() {
303 } 376 }
304 377
305 OAuth2TokenService::Request::~Request() { 378 OAuth2TokenService::Request::~Request() {
306 } 379 }
307 380
308 OAuth2TokenService::Consumer::Consumer() { 381 OAuth2TokenService::Consumer::Consumer() {
309 } 382 }
310 383
311 OAuth2TokenService::Consumer::~Consumer() { 384 OAuth2TokenService::Consumer::~Consumer() {
(...skipping 20 matching lines...) Expand all
332 bool OAuth2TokenService::RefreshTokenIsAvailable() { 405 bool OAuth2TokenService::RefreshTokenIsAvailable() {
333 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 406 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
334 return !GetRefreshToken().empty(); 407 return !GetRefreshToken().empty();
335 } 408 }
336 409
337 scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( 410 scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest(
338 const OAuth2TokenService::ScopeSet& scopes, 411 const OAuth2TokenService::ScopeSet& scopes,
339 OAuth2TokenService::Consumer* consumer) { 412 OAuth2TokenService::Consumer* consumer) {
340 return StartRequestForClientWithContext( 413 return StartRequestForClientWithContext(
341 GetRequestContext(), 414 GetRequestContext(),
415 std::string(),
342 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), 416 GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
343 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), 417 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
344 scopes, 418 scopes,
345 consumer); 419 consumer);
346 } 420 }
347 421
348 scoped_ptr<OAuth2TokenService::Request> 422 scoped_ptr<OAuth2TokenService::Request>
349 OAuth2TokenService::StartRequestForClient( 423 OAuth2TokenService::StartRequestForClient(
424 const std::string& request_origin,
350 const std::string& client_id, 425 const std::string& client_id,
351 const std::string& client_secret, 426 const std::string& client_secret,
352 const OAuth2TokenService::ScopeSet& scopes, 427 const OAuth2TokenService::ScopeSet& scopes,
353 OAuth2TokenService::Consumer* consumer) { 428 OAuth2TokenService::Consumer* consumer) {
354 return StartRequestForClientWithContext( 429 return StartRequestForClientWithContext(
355 GetRequestContext(), 430 GetRequestContext(),
431 request_origin,
356 client_id, 432 client_id,
357 client_secret, 433 client_secret,
358 scopes, 434 scopes,
359 consumer); 435 consumer);
360 } 436 }
361 437
362 scoped_ptr<OAuth2TokenService::Request> 438 scoped_ptr<OAuth2TokenService::Request>
363 OAuth2TokenService::StartRequestWithContext( 439 OAuth2TokenService::StartRequestWithContext(
364 net::URLRequestContextGetter* getter, 440 net::URLRequestContextGetter* getter,
365 const ScopeSet& scopes, 441 const ScopeSet& scopes,
366 Consumer* consumer) { 442 Consumer* consumer) {
367 return StartRequestForClientWithContext( 443 return StartRequestForClientWithContext(
368 getter, 444 getter,
445 std::string(),
369 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), 446 GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
370 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), 447 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
371 scopes, 448 scopes,
372 consumer); 449 consumer);
373 } 450 }
374 451
375 scoped_ptr<OAuth2TokenService::Request> 452 scoped_ptr<OAuth2TokenService::Request>
376 OAuth2TokenService::StartRequestForClientWithContext( 453 OAuth2TokenService::StartRequestForClientWithContext(
377 net::URLRequestContextGetter* getter, 454 net::URLRequestContextGetter* getter,
455 const std::string& request_origin,
378 const std::string& client_id, 456 const std::string& client_id,
379 const std::string& client_secret, 457 const std::string& client_secret,
380 const ScopeSet& scopes, 458 const ScopeSet& scopes,
381 Consumer* consumer) { 459 Consumer* consumer) {
382 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 460 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
383 461
384 scoped_ptr<RequestImpl> request(new RequestImpl(consumer)); 462 scoped_ptr<RequestImpl> request(new RequestImpl(consumer));
385 463
386 std::string refresh_token = GetRefreshToken(); 464 std::string refresh_token = GetRefreshToken();
387 if (refresh_token.empty()) { 465 if (refresh_token.empty()) {
388 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 466 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
389 &RequestImpl::InformConsumer, 467 &RequestImpl::InformConsumer,
390 request->AsWeakPtr(), 468 request->AsWeakPtr(),
391 GoogleServiceAuthError( 469 GoogleServiceAuthError(
392 GoogleServiceAuthError::USER_NOT_SIGNED_UP), 470 GoogleServiceAuthError::USER_NOT_SIGNED_UP),
393 std::string(), 471 std::string(),
394 base::Time())); 472 base::Time()));
395 return request.PassAs<Request>(); 473 return request.PassAs<Request>();
396 } 474 }
397 475
398 if (HasCacheEntry(scopes)) 476 ClientScopeSet client_scopes(request_origin,
399 return StartCacheLookupRequest(scopes, consumer); 477 client_id,
478 scopes);
479 if (HasCacheEntry(client_scopes))
480 return StartCacheLookupRequest(client_scopes, consumer);
400 481
401 // If there is already a pending fetcher for |scopes| and |refresh_token|, 482 // If there is already a pending fetcher for |scopes| and |refresh_token|,
402 // simply register this |request| for those results rather than starting 483 // simply register this |request| for those results rather than starting
403 // a new fetcher. 484 // a new fetcher.
404 FetchParameters fetch_parameters = std::make_pair(refresh_token, scopes); 485 FetchParameters fetch_parameters = FetchParameters(request_origin,
486 client_id,
487 refresh_token,
488 scopes);
405 std::map<FetchParameters, Fetcher*>::iterator iter = 489 std::map<FetchParameters, Fetcher*>::iterator iter =
406 pending_fetchers_.find(fetch_parameters); 490 pending_fetchers_.find(fetch_parameters);
407 if (iter != pending_fetchers_.end()) { 491 if (iter != pending_fetchers_.end()) {
408 iter->second->AddWaitingRequest(request->AsWeakPtr()); 492 iter->second->AddWaitingRequest(request->AsWeakPtr());
409 return request.PassAs<Request>(); 493 return request.PassAs<Request>();
410 } 494 }
411 495
412 pending_fetchers_[fetch_parameters] = 496 pending_fetchers_[fetch_parameters] =
413 Fetcher::CreateAndStart(this, 497 Fetcher::CreateAndStart(this,
414 getter, 498 getter,
499 request_origin,
415 client_id, 500 client_id,
416 client_secret, 501 client_secret,
417 refresh_token, 502 refresh_token,
418 scopes, 503 scopes,
419 request->AsWeakPtr()); 504 request->AsWeakPtr());
420 return request.PassAs<Request>(); 505 return request.PassAs<Request>();
421 } 506 }
422 507
423 scoped_ptr<OAuth2TokenService::Request> 508 scoped_ptr<OAuth2TokenService::Request>
424 OAuth2TokenService::StartCacheLookupRequest( 509 OAuth2TokenService::StartCacheLookupRequest(
425 const OAuth2TokenService::ScopeSet& scopes, 510 const OAuth2TokenService::ClientScopeSet& client_scopes,
426 OAuth2TokenService::Consumer* consumer) { 511 OAuth2TokenService::Consumer* consumer) {
427 CHECK(HasCacheEntry(scopes)); 512 CHECK(HasCacheEntry(client_scopes));
428 const CacheEntry* cache_entry = GetCacheEntry(scopes); 513 const CacheEntry* cache_entry = GetCacheEntry(client_scopes);
429 scoped_ptr<RequestImpl> request(new RequestImpl(consumer)); 514 scoped_ptr<RequestImpl> request(new RequestImpl(consumer));
430 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 515 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
431 &RequestImpl::InformConsumer, 516 &RequestImpl::InformConsumer,
432 request->AsWeakPtr(), 517 request->AsWeakPtr(),
433 GoogleServiceAuthError(GoogleServiceAuthError::NONE), 518 GoogleServiceAuthError(GoogleServiceAuthError::NONE),
434 cache_entry->access_token, 519 cache_entry->access_token,
435 cache_entry->expiration_date)); 520 cache_entry->expiration_date));
436 return request.PassAs<Request>(); 521 return request.PassAs<Request>();
437 } 522 }
438 523
439 void OAuth2TokenService::InvalidateToken(const ScopeSet& scopes, 524 void OAuth2TokenService::InvalidateToken(const ScopeSet& scopes,
440 const std::string& invalid_token) { 525 const std::string& invalid_token) {
441 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 526 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
442 RemoveCacheEntry(scopes, invalid_token); 527 RemoveCacheEntry(
528 ClientScopeSet(std::string(),
529 GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
530 scopes),
531 invalid_token);
443 } 532 }
444 533
445 void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) { 534 void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) {
446 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 535 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
447 536
448 // Update the auth error state so auth errors are appropriately communicated 537 // Update the auth error state so auth errors are appropriately communicated
449 // to the user. 538 // to the user.
450 UpdateAuthError(fetcher->error()); 539 UpdateAuthError(fetcher->error());
451 540
452 // Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh 541 // Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh
(...skipping 16 matching lines...) Expand all
469 // 558 //
470 // (3) Each of the Fetchers recorded in |pending_fetchers_| is mapped to its 559 // (3) Each of the Fetchers recorded in |pending_fetchers_| is mapped to its
471 // refresh token and ScopeSet. This is guaranteed by Fetcher creation in 560 // refresh token and ScopeSet. This is guaranteed by Fetcher creation in
472 // method StartRequest(). 561 // method StartRequest().
473 // 562 //
474 // When this method is called, |fetcher| is alive and uncompleted. 563 // When this method is called, |fetcher| is alive and uncompleted.
475 // By (1), |fetcher| is created by this service. 564 // By (1), |fetcher| is created by this service.
476 // Then by (2), |fetcher| is recorded in |pending_fetchers_|. 565 // Then by (2), |fetcher| is recorded in |pending_fetchers_|.
477 // Then by (3), |fetcher_| is mapped to its refresh token and ScopeSet. 566 // Then by (3), |fetcher_| is mapped to its refresh token and ScopeSet.
478 std::map<FetchParameters, Fetcher*>::iterator iter = 567 std::map<FetchParameters, Fetcher*>::iterator iter =
479 pending_fetchers_.find(std::make_pair( 568 pending_fetchers_.find(FetchParameters(
480 fetcher->GetRefreshToken(), fetcher->GetScopeSet())); 569 fetcher->GetRequestOrigin(),
570 fetcher->GetClientId(),
571 fetcher->GetRefreshToken(),
572 fetcher->GetScopeSet()));
481 DCHECK(iter != pending_fetchers_.end()); 573 DCHECK(iter != pending_fetchers_.end());
482 DCHECK_EQ(fetcher, iter->second); 574 DCHECK_EQ(fetcher, iter->second);
483 pending_fetchers_.erase(iter); 575 pending_fetchers_.erase(iter);
484 } 576 }
485 577
486 bool OAuth2TokenService::HasCacheEntry( 578 bool OAuth2TokenService::HasCacheEntry(
487 const OAuth2TokenService::ScopeSet& scopes) { 579 const ClientScopeSet& client_scopes) {
488 const CacheEntry* cache_entry = GetCacheEntry(scopes); 580 const CacheEntry* cache_entry = GetCacheEntry(client_scopes);
489 return cache_entry && cache_entry->access_token.length(); 581 return cache_entry && cache_entry->access_token.length();
490 } 582 }
491 583
492 const OAuth2TokenService::CacheEntry* OAuth2TokenService::GetCacheEntry( 584 const OAuth2TokenService::CacheEntry* OAuth2TokenService::GetCacheEntry(
493 const OAuth2TokenService::ScopeSet& scopes) { 585 const ClientScopeSet& client_scopes) {
494 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 586 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
495 TokenCache::iterator token_iterator = token_cache_.find(scopes); 587 TokenCache::iterator token_iterator = token_cache_.find(client_scopes);
496 if (token_iterator == token_cache_.end()) 588 if (token_iterator == token_cache_.end())
497 return NULL; 589 return NULL;
498 if (token_iterator->second.expiration_date <= base::Time::Now()) { 590 if (token_iterator->second.expiration_date <= base::Time::Now()) {
499 token_cache_.erase(token_iterator); 591 token_cache_.erase(token_iterator);
500 return NULL; 592 return NULL;
501 } 593 }
502 return &token_iterator->second; 594 return &token_iterator->second;
503 } 595 }
504 596
505 bool OAuth2TokenService::RemoveCacheEntry( 597 bool OAuth2TokenService::RemoveCacheEntry(
506 const OAuth2TokenService::ScopeSet& scopes, 598 const ClientScopeSet& client_scopes,
507 const std::string& token_to_remove) { 599 const std::string& token_to_remove) {
508 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 600 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
509 TokenCache::iterator token_iterator = token_cache_.find(scopes); 601 TokenCache::iterator token_iterator = token_cache_.find(client_scopes);
510 if (token_iterator != token_cache_.end() && 602 if (token_iterator != token_cache_.end() &&
511 token_iterator->second.access_token == token_to_remove) { 603 token_iterator->second.access_token == token_to_remove) {
512 token_cache_.erase(token_iterator); 604 token_cache_.erase(token_iterator);
513 return true; 605 return true;
514 } 606 }
515 return false; 607 return false;
516 } 608 }
517 609
518 void OAuth2TokenService::RegisterCacheEntry( 610 void OAuth2TokenService::RegisterCacheEntry(
611 const std::string& request_origin,
612 const std::string& client_id,
519 const std::string& refresh_token, 613 const std::string& refresh_token,
520 const OAuth2TokenService::ScopeSet& scopes, 614 const OAuth2TokenService::ScopeSet& scopes,
521 const std::string& access_token, 615 const std::string& access_token,
522 const base::Time& expiration_date) { 616 const base::Time& expiration_date) {
523 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 617 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
524 618
525 CacheEntry& token = token_cache_[scopes]; 619 CacheEntry& token = token_cache_[ClientScopeSet(request_origin,
620 client_id,
621 scopes)];
526 token.access_token = access_token; 622 token.access_token = access_token;
527 token.expiration_date = expiration_date; 623 token.expiration_date = expiration_date;
528 } 624 }
529 625
530 void OAuth2TokenService::UpdateAuthError(const GoogleServiceAuthError& error) { 626 void OAuth2TokenService::UpdateAuthError(const GoogleServiceAuthError& error) {
531 // Default implementation does nothing. 627 // Default implementation does nothing.
532 } 628 }
533 629
534 void OAuth2TokenService::ClearCache() { 630 void OAuth2TokenService::ClearCache() {
535 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 631 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
(...skipping 11 matching lines...) Expand all
547 CancelFetchers(fetchers_to_cancel); 643 CancelFetchers(fetchers_to_cancel);
548 } 644 }
549 645
550 void OAuth2TokenService::CancelRequestsForToken( 646 void OAuth2TokenService::CancelRequestsForToken(
551 const std::string& refresh_token) { 647 const std::string& refresh_token) {
552 std::vector<Fetcher*> fetchers_to_cancel; 648 std::vector<Fetcher*> fetchers_to_cancel;
553 for (std::map<FetchParameters, Fetcher*>::iterator iter = 649 for (std::map<FetchParameters, Fetcher*>::iterator iter =
554 pending_fetchers_.begin(); 650 pending_fetchers_.begin();
555 iter != pending_fetchers_.end(); 651 iter != pending_fetchers_.end();
556 ++iter) { 652 ++iter) {
557 if (iter->first.first == refresh_token) 653 if (iter->first.refresh_token == refresh_token)
558 fetchers_to_cancel.push_back(iter->second); 654 fetchers_to_cancel.push_back(iter->second);
559 } 655 }
560 CancelFetchers(fetchers_to_cancel); 656 CancelFetchers(fetchers_to_cancel);
561 } 657 }
562 658
563 void OAuth2TokenService::CancelFetchers( 659 void OAuth2TokenService::CancelFetchers(
564 std::vector<Fetcher*> fetchers_to_cancel) { 660 std::vector<Fetcher*> fetchers_to_cancel) {
565 for (std::vector<OAuth2TokenService::Fetcher*>::iterator iter = 661 for (std::vector<OAuth2TokenService::Fetcher*>::iterator iter =
566 fetchers_to_cancel.begin(); 662 fetchers_to_cancel.begin();
567 iter != fetchers_to_cancel.end(); 663 iter != fetchers_to_cancel.end();
(...skipping 25 matching lines...) Expand all
593 689
594 int OAuth2TokenService::cache_size_for_testing() const { 690 int OAuth2TokenService::cache_size_for_testing() const {
595 return token_cache_.size(); 691 return token_cache_.size();
596 } 692 }
597 693
598 void OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing( 694 void OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing(
599 int max_retries) { 695 int max_retries) {
600 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 696 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
601 max_fetch_retry_num_ = max_retries; 697 max_fetch_retry_num_ = max_retries;
602 } 698 }
OLDNEW
« no previous file with comments | « chrome/browser/signin/oauth2_token_service.h ('k') | chrome/browser/signin/oauth2_token_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698