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

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

Issue 12880014: Get OAuth2TokenService working on Android. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add token invalidation. Created 7 years, 9 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 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"
(...skipping 11 matching lines...) Expand all
22 #include "chrome/common/chrome_notification_types.h" 22 #include "chrome/common/chrome_notification_types.h"
23 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/notification_details.h" 24 #include "content/public/browser/notification_details.h"
25 #include "content/public/browser/notification_source.h" 25 #include "content/public/browser/notification_source.h"
26 #include "google_apis/gaia/gaia_constants.h" 26 #include "google_apis/gaia/gaia_constants.h"
27 #include "google_apis/gaia/gaia_urls.h" 27 #include "google_apis/gaia/gaia_urls.h"
28 #include "google_apis/gaia/google_service_auth_error.h" 28 #include "google_apis/gaia/google_service_auth_error.h"
29 #include "google_apis/gaia/oauth2_access_token_consumer.h" 29 #include "google_apis/gaia/oauth2_access_token_consumer.h"
30 #include "google_apis/gaia/oauth2_access_token_fetcher.h" 30 #include "google_apis/gaia/oauth2_access_token_fetcher.h"
31 31
32 #if defined(OS_ANDROID)
33 #include "chrome/browser/sync/profile_sync_service_android.h"
34 #endif
35
32 namespace { 36 namespace {
33 37
34 // Maximum number of retries in fetching an OAuth2 access token. 38 // Maximum number of retries in fetching an OAuth2 access token.
35 const int kMaxFetchRetryNum = 5; 39 const int kMaxFetchRetryNum = 5;
36 40
37 // Returns an exponential backoff in milliseconds including randomness less than 41 // Returns an exponential backoff in milliseconds including randomness less than
38 // 1000 ms when retrying fetching an OAuth2 access token. 42 // 1000 ms when retrying fetching an OAuth2 access token.
39 int64 ComputeExponentialBackOffMilliseconds(int retry_num) { 43 int64 ComputeExponentialBackOffMilliseconds(int retry_num) {
40 DCHECK(retry_num < kMaxFetchRetryNum); 44 DCHECK(retry_num < kMaxFetchRetryNum);
41 int64 exponential_backoff_in_seconds = 1 << retry_num; 45 int64 exponential_backoff_in_seconds = 1 << retry_num;
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 base::Time expiration_date) { 371 base::Time expiration_date) {
368 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 372 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
369 373
370 if (request) 374 if (request)
371 request->InformConsumer(error, access_token, expiration_date); 375 request->InformConsumer(error, access_token, expiration_date);
372 } 376 }
373 377
374 scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( 378 scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest(
375 const OAuth2TokenService::ScopeSet& scopes, 379 const OAuth2TokenService::ScopeSet& scopes,
376 OAuth2TokenService::Consumer* consumer) { 380 OAuth2TokenService::Consumer* consumer) {
381 return InvalidateTokenAndStartRequest(scopes, consumer, std::string());
382 }
383
384 scoped_ptr<OAuth2TokenService::Request>
385 OAuth2TokenService::InvalidateTokenAndStartRequest(
386 const OAuth2TokenService::ScopeSet& scopes,
387 OAuth2TokenService::Consumer* consumer,
388 const std::string& invalid_token) {
377 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 389 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
378 390
379 scoped_ptr<RequestImpl> request(new RequestImpl(consumer)); 391 scoped_ptr<RequestImpl> request(new RequestImpl(consumer));
380 392
393 #if !defined(OS_ANDROID)
381 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); 394 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
382 if (!token_service || !token_service->HasOAuthLoginToken()) { 395 if (!token_service || !token_service->HasOAuthLoginToken()) {
383 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 396 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
384 &OAuth2TokenService::InformConsumer, 397 &OAuth2TokenService::InformConsumer,
385 request->AsWeakPtr(), 398 request->AsWeakPtr(),
386 GoogleServiceAuthError(GoogleServiceAuthError::USER_NOT_SIGNED_UP), 399 GoogleServiceAuthError(GoogleServiceAuthError::USER_NOT_SIGNED_UP),
387 std::string(), 400 std::string(),
388 base::Time())); 401 base::Time()));
389 return request.PassAs<Request>(); 402 return request.PassAs<Request>();
390 } 403 }
404 #endif
405
406 if (!invalid_token.empty())
407 RemoveCacheEntry(scopes, invalid_token);
391 408
392 const CacheEntry* cache_entry = GetCacheEntry(scopes); 409 const CacheEntry* cache_entry = GetCacheEntry(scopes);
393 if (cache_entry && cache_entry->access_token.length()) { 410 if (cache_entry && cache_entry->access_token.length()) {
394 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 411 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
395 &OAuth2TokenService::InformConsumer, 412 &OAuth2TokenService::InformConsumer,
396 request->AsWeakPtr(), 413 request->AsWeakPtr(),
397 GoogleServiceAuthError(GoogleServiceAuthError::NONE), 414 GoogleServiceAuthError(GoogleServiceAuthError::NONE),
398 cache_entry->access_token, 415 cache_entry->access_token,
399 cache_entry->expiration_date)); 416 cache_entry->expiration_date));
400 return request.PassAs<Request>(); 417 return request.PassAs<Request>();
401 } 418 }
402 419
420 #if defined(OS_ANDROID)
421 DCHECK_EQ(scopes.size(), 1U);
422 std::vector<std::string> scope_list(scopes.begin(), scopes.end());
423 ProfileSyncServiceAndroid* sync_service =
424 ProfileSyncServiceAndroid::GetProfileSyncServiceAndroid();
425 sync_service->FetchOAuth2Token(
426 scope_list.front(),
427 invalid_token,
428 base::Bind(&OAuth2TokenService::InformConsumer,
429 request->AsWeakPtr()));
430 return request.PassAs<Request>();
431 #else
403 std::string refresh_token = token_service->GetOAuth2LoginRefreshToken(); 432 std::string refresh_token = token_service->GetOAuth2LoginRefreshToken();
404 if (!refresh_token.length()) { 433 if (!refresh_token.length()) {
405 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 434 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
406 &OAuth2TokenService::InformConsumer, 435 &OAuth2TokenService::InformConsumer,
407 request->AsWeakPtr(), 436 request->AsWeakPtr(),
408 GoogleServiceAuthError( 437 GoogleServiceAuthError(
409 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS), 438 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS),
410 std::string(), 439 std::string(),
411 base::Time())); 440 base::Time()));
412 return request.PassAs<Request>(); 441 return request.PassAs<Request>();
413 } 442 }
414 443
415 // Makes sure there is a pending fetcher for |scopes| and |refresh_token|. 444 // Makes sure there is a pending fetcher for |scopes| and |refresh_token|.
416 // Adds |request| to the waiting request list of this fetcher so |request| 445 // Adds |request| to the waiting request list of this fetcher so |request|
417 // will be called back when this fetcher finishes fetching. 446 // will be called back when this fetcher finishes fetching.
418 FetchParameters fetch_parameters = std::make_pair(refresh_token, scopes); 447 FetchParameters fetch_parameters = std::make_pair(refresh_token, scopes);
419 std::map<FetchParameters, Fetcher*>::iterator iter = 448 std::map<FetchParameters, Fetcher*>::iterator iter =
420 pending_fetchers_.find(fetch_parameters); 449 pending_fetchers_.find(fetch_parameters);
421 if (iter != pending_fetchers_.end()) { 450 if (iter != pending_fetchers_.end()) {
422 iter->second->AddWaitingRequest(request->AsWeakPtr()); 451 iter->second->AddWaitingRequest(request->AsWeakPtr());
423 return request.PassAs<Request>(); 452 return request.PassAs<Request>();
424 } 453 }
425 pending_fetchers_[fetch_parameters] = Fetcher::CreateAndStart( 454 pending_fetchers_[fetch_parameters] = Fetcher::CreateAndStart(
426 profile_, getter_, refresh_token, scopes, request->AsWeakPtr()); 455 profile_, getter_, refresh_token, scopes, request->AsWeakPtr());
427 return request.PassAs<Request>(); 456 return request.PassAs<Request>();
457 #endif // defined(OS_ANDROID)
428 } 458 }
429 459
430 void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) { 460 void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) {
431 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 461 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
432 462
433 // Update the auth error state so auth errors are appropriately communicated 463 // Update the auth error state so auth errors are appropriately communicated
434 // to the user. 464 // to the user.
435 UpdateAuthError(fetcher->error()); 465 UpdateAuthError(fetcher->error());
436 466
437 // Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh 467 // Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 TokenCache::iterator token_iterator = token_cache_.find(scopes); 505 TokenCache::iterator token_iterator = token_cache_.find(scopes);
476 if (token_iterator == token_cache_.end()) 506 if (token_iterator == token_cache_.end())
477 return NULL; 507 return NULL;
478 if (token_iterator->second.expiration_date <= base::Time::Now()) { 508 if (token_iterator->second.expiration_date <= base::Time::Now()) {
479 token_cache_.erase(token_iterator); 509 token_cache_.erase(token_iterator);
480 return NULL; 510 return NULL;
481 } 511 }
482 return &token_iterator->second; 512 return &token_iterator->second;
483 } 513 }
484 514
515 bool OAuth2TokenService::RemoveCacheEntry(
516 const OAuth2TokenService::ScopeSet& scopes,
517 const std::string& token_to_remove) {
518 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
519 TokenCache::iterator token_iterator = token_cache_.find(scopes);
520 if (token_iterator == token_cache_.end() &&
521 token_iterator->second.access_token == token_to_remove) {
522 token_cache_.erase(token_iterator);
523 return true;
524 }
525 return false;
526 }
527
485 void OAuth2TokenService::RegisterCacheEntry( 528 void OAuth2TokenService::RegisterCacheEntry(
486 const std::string& refresh_token, 529 const std::string& refresh_token,
487 const OAuth2TokenService::ScopeSet& scopes, 530 const OAuth2TokenService::ScopeSet& scopes,
488 const std::string& access_token, 531 const std::string& access_token,
489 const base::Time& expiration_date) { 532 const base::Time& expiration_date) {
490 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 533 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
491 534
535 #if !defined(OS_ANDROID)
492 // Only register OAuth2 access tokens for the refresh token held by 536 // Only register OAuth2 access tokens for the refresh token held by
493 // TokenService. 537 // TokenService.
494 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); 538 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
495 if (!token_service || 539 if (!token_service ||
496 !token_service->HasOAuthLoginToken() || 540 !token_service->HasOAuthLoginToken() ||
497 token_service->GetOAuth2LoginRefreshToken().compare(refresh_token) != 0) { 541 token_service->GetOAuth2LoginRefreshToken().compare(refresh_token) != 0) {
498 DLOG(INFO) << 542 DLOG(INFO) <<
499 "Received a token with a refresh token not maintained by TokenService."; 543 "Received a token with a refresh token not maintained by TokenService.";
500 return; 544 return;
501 } 545 }
546 #endif
502 547
503 CacheEntry& token = token_cache_[scopes]; 548 CacheEntry& token = token_cache_[scopes];
504 token.access_token = access_token; 549 token.access_token = access_token;
505 token.expiration_date = expiration_date; 550 token.expiration_date = expiration_date;
506 } 551 }
507 552
508 void OAuth2TokenService::Observe(int type, 553 void OAuth2TokenService::Observe(int type,
509 const content::NotificationSource& source, 554 const content::NotificationSource& source,
510 const content::NotificationDetails& details) { 555 const content::NotificationDetails& details) {
511 DCHECK(type == chrome::NOTIFICATION_TOKENS_CLEARED || 556 DCHECK(type == chrome::NOTIFICATION_TOKENS_CLEARED ||
(...skipping 21 matching lines...) Expand all
533 if (error.state() != last_auth_error_.state()) { 578 if (error.state() != last_auth_error_.state()) {
534 last_auth_error_ = error; 579 last_auth_error_ = error;
535 SigninManagerFactory::GetForProfile(profile_)->signin_global_error()-> 580 SigninManagerFactory::GetForProfile(profile_)->signin_global_error()->
536 AuthStatusChanged(); 581 AuthStatusChanged();
537 } 582 }
538 } 583 }
539 584
540 GoogleServiceAuthError OAuth2TokenService::GetAuthStatus() const { 585 GoogleServiceAuthError OAuth2TokenService::GetAuthStatus() const {
541 return last_auth_error_; 586 return last_auth_error_;
542 } 587 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698