| 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 #include "google_apis/gaia/oauth2_token_service.h" | 5 #include "google_apis/gaia/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/profiler/scoped_tracker.h" | 12 #include "base/profiler/scoped_tracker.h" |
| 13 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
| 14 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 15 #include "base/time/time.h" | 15 #include "base/time/time.h" |
| 16 #include "base/timer/timer.h" | 16 #include "base/timer/timer.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_fetcher_impl.h" | 19 #include "google_apis/gaia/oauth2_access_token_fetcher_impl.h" |
| 20 #include "google_apis/gaia/oauth2_token_service_delegate.h" |
| 20 #include "net/url_request/url_request_context_getter.h" | 21 #include "net/url_request/url_request_context_getter.h" |
| 21 | 22 |
| 22 int OAuth2TokenService::max_fetch_retry_num_ = 5; | 23 int OAuth2TokenService::max_fetch_retry_num_ = 5; |
| 23 | 24 |
| 24 OAuth2TokenService::RequestParameters::RequestParameters( | 25 OAuth2TokenService::RequestParameters::RequestParameters( |
| 25 const std::string& client_id, | 26 const std::string& client_id, |
| 26 const std::string& account_id, | 27 const std::string& account_id, |
| 27 const ScopeSet& scopes) | 28 const ScopeSet& scopes) |
| 28 : client_id(client_id), | 29 : client_id(client_id), |
| 29 account_id(account_id), | 30 account_id(account_id), |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 const GoogleServiceAuthError& error, | 72 const GoogleServiceAuthError& error, |
| 72 const std::string& access_token, | 73 const std::string& access_token, |
| 73 const base::Time& expiration_date) { | 74 const base::Time& expiration_date) { |
| 74 DCHECK(CalledOnValidThread()); | 75 DCHECK(CalledOnValidThread()); |
| 75 if (error.state() == GoogleServiceAuthError::NONE) | 76 if (error.state() == GoogleServiceAuthError::NONE) |
| 76 consumer_->OnGetTokenSuccess(this, access_token, expiration_date); | 77 consumer_->OnGetTokenSuccess(this, access_token, expiration_date); |
| 77 else | 78 else |
| 78 consumer_->OnGetTokenFailure(this, error); | 79 consumer_->OnGetTokenFailure(this, error); |
| 79 } | 80 } |
| 80 | 81 |
| 81 OAuth2TokenService::ScopedBatchChange::ScopedBatchChange( | |
| 82 OAuth2TokenService* token_service) : token_service_(token_service) { | |
| 83 DCHECK(token_service_); | |
| 84 token_service_->StartBatchChanges(); | |
| 85 } | |
| 86 | |
| 87 OAuth2TokenService::ScopedBatchChange::~ScopedBatchChange() { | |
| 88 token_service_->EndBatchChanges(); | |
| 89 } | |
| 90 | |
| 91 // Class that fetches an OAuth2 access token for a given account id and set of | 82 // Class that fetches an OAuth2 access token for a given account id and set of |
| 92 // scopes. | 83 // scopes. |
| 93 // | 84 // |
| 94 // It aims to meet OAuth2TokenService's requirements on token fetching. Retry | 85 // It aims to meet OAuth2TokenService's requirements on token fetching. Retry |
| 95 // mechanism is used to handle failures. | 86 // mechanism is used to handle failures. |
| 96 // | 87 // |
| 97 // To use this class, call CreateAndStart() to create and start a Fetcher. | 88 // To use this class, call CreateAndStart() to create and start a Fetcher. |
| 98 // | 89 // |
| 99 // The Fetcher will call back the service by calling | 90 // The Fetcher will call back the service by calling |
| 100 // OAuth2TokenService::OnFetchComplete() when it completes fetching, if it is | 91 // OAuth2TokenService::OnFetchComplete() when it completes fetching, if it is |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 | 368 |
| 378 OAuth2TokenService::Request::~Request() { | 369 OAuth2TokenService::Request::~Request() { |
| 379 } | 370 } |
| 380 | 371 |
| 381 OAuth2TokenService::Consumer::Consumer(const std::string& id) | 372 OAuth2TokenService::Consumer::Consumer(const std::string& id) |
| 382 : id_(id) {} | 373 : id_(id) {} |
| 383 | 374 |
| 384 OAuth2TokenService::Consumer::~Consumer() { | 375 OAuth2TokenService::Consumer::~Consumer() { |
| 385 } | 376 } |
| 386 | 377 |
| 387 OAuth2TokenService::OAuth2TokenService() : batch_change_depth_(0) { | 378 OAuth2TokenService::OAuth2TokenService(OAuth2TokenServiceDelegate* delegate) |
| 379 : delegate_(delegate) { |
| 380 DCHECK(delegate_); |
| 388 } | 381 } |
| 389 | 382 |
| 390 OAuth2TokenService::~OAuth2TokenService() { | 383 OAuth2TokenService::~OAuth2TokenService() { |
| 391 // Release all the pending fetchers. | 384 // Release all the pending fetchers. |
| 392 STLDeleteContainerPairSecondPointers( | 385 STLDeleteContainerPairSecondPointers( |
| 393 pending_fetchers_.begin(), pending_fetchers_.end()); | 386 pending_fetchers_.begin(), pending_fetchers_.end()); |
| 394 } | 387 } |
| 395 | 388 |
| 389 OAuth2TokenServiceDelegate* OAuth2TokenService::GetDelegate() { |
| 390 return delegate_.get(); |
| 391 } |
| 392 |
| 396 void OAuth2TokenService::AddObserver(Observer* observer) { | 393 void OAuth2TokenService::AddObserver(Observer* observer) { |
| 397 observer_list_.AddObserver(observer); | 394 delegate_->AddObserver(observer); |
| 398 } | 395 } |
| 399 | 396 |
| 400 void OAuth2TokenService::RemoveObserver(Observer* observer) { | 397 void OAuth2TokenService::RemoveObserver(Observer* observer) { |
| 401 observer_list_.RemoveObserver(observer); | 398 delegate_->RemoveObserver(observer); |
| 402 } | 399 } |
| 403 | 400 |
| 404 void OAuth2TokenService::AddDiagnosticsObserver(DiagnosticsObserver* observer) { | 401 void OAuth2TokenService::AddDiagnosticsObserver(DiagnosticsObserver* observer) { |
| 405 diagnostics_observer_list_.AddObserver(observer); | 402 diagnostics_observer_list_.AddObserver(observer); |
| 406 } | 403 } |
| 407 | 404 |
| 408 void OAuth2TokenService::RemoveDiagnosticsObserver( | 405 void OAuth2TokenService::RemoveDiagnosticsObserver( |
| 409 DiagnosticsObserver* observer) { | 406 DiagnosticsObserver* observer) { |
| 410 diagnostics_observer_list_.RemoveObserver(observer); | 407 diagnostics_observer_list_.RemoveObserver(observer); |
| 411 } | 408 } |
| 412 | 409 |
| 413 std::vector<std::string> OAuth2TokenService::GetAccounts() { | |
| 414 return std::vector<std::string>(); | |
| 415 } | |
| 416 | |
| 417 scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( | 410 scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( |
| 418 const std::string& account_id, | 411 const std::string& account_id, |
| 419 const OAuth2TokenService::ScopeSet& scopes, | 412 const OAuth2TokenService::ScopeSet& scopes, |
| 420 OAuth2TokenService::Consumer* consumer) { | 413 OAuth2TokenService::Consumer* consumer) { |
| 421 return StartRequestForClientWithContext( | 414 return StartRequestForClientWithContext( |
| 422 account_id, | 415 account_id, |
| 423 GetRequestContext(), | 416 GetRequestContext(), |
| 424 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), | 417 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), |
| 425 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), | 418 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), |
| 426 scopes, | 419 scopes, |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 pending_fetchers_[request_parameters] = | 546 pending_fetchers_[request_parameters] = |
| 554 Fetcher::CreateAndStart(this, | 547 Fetcher::CreateAndStart(this, |
| 555 account_id, | 548 account_id, |
| 556 getter, | 549 getter, |
| 557 client_id, | 550 client_id, |
| 558 client_secret, | 551 client_secret, |
| 559 scopes, | 552 scopes, |
| 560 request->AsWeakPtr()); | 553 request->AsWeakPtr()); |
| 561 } | 554 } |
| 562 | 555 |
| 556 OAuth2AccessTokenFetcher* OAuth2TokenService::CreateAccessTokenFetcher( |
| 557 const std::string& account_id, |
| 558 net::URLRequestContextGetter* getter, |
| 559 OAuth2AccessTokenConsumer* consumer) { |
| 560 return delegate_->CreateAccessTokenFetcher(account_id, getter, consumer); |
| 561 } |
| 562 |
| 563 void OAuth2TokenService::StartCacheLookupRequest( | 563 void OAuth2TokenService::StartCacheLookupRequest( |
| 564 RequestImpl* request, | 564 RequestImpl* request, |
| 565 const OAuth2TokenService::RequestParameters& request_parameters, | 565 const OAuth2TokenService::RequestParameters& request_parameters, |
| 566 OAuth2TokenService::Consumer* consumer) { | 566 OAuth2TokenService::Consumer* consumer) { |
| 567 CHECK(HasCacheEntry(request_parameters)); | 567 CHECK(HasCacheEntry(request_parameters)); |
| 568 const CacheEntry* cache_entry = GetCacheEntry(request_parameters); | 568 const CacheEntry* cache_entry = GetCacheEntry(request_parameters); |
| 569 FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, | 569 FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, |
| 570 OnFetchAccessTokenComplete( | 570 OnFetchAccessTokenComplete( |
| 571 request_parameters.account_id, | 571 request_parameters.account_id, |
| 572 consumer->id(), | 572 consumer->id(), |
| 573 request_parameters.scopes, | 573 request_parameters.scopes, |
| 574 GoogleServiceAuthError::AuthErrorNone(), | 574 GoogleServiceAuthError::AuthErrorNone(), |
| 575 cache_entry->expiration_date)); | 575 cache_entry->expiration_date)); |
| 576 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 576 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
| 577 &RequestImpl::InformConsumer, | 577 &RequestImpl::InformConsumer, |
| 578 request->AsWeakPtr(), | 578 request->AsWeakPtr(), |
| 579 GoogleServiceAuthError(GoogleServiceAuthError::NONE), | 579 GoogleServiceAuthError(GoogleServiceAuthError::NONE), |
| 580 cache_entry->access_token, | 580 cache_entry->access_token, |
| 581 cache_entry->expiration_date)); | 581 cache_entry->expiration_date)); |
| 582 } | 582 } |
| 583 | 583 |
| 584 std::vector<std::string> OAuth2TokenService::GetAccounts() { |
| 585 return delegate_->GetAccounts(); |
| 586 } |
| 587 |
| 588 bool OAuth2TokenService::RefreshTokenIsAvailable( |
| 589 const std::string& account_id) const { |
| 590 return delegate_->RefreshTokenIsAvailable(account_id); |
| 591 } |
| 592 |
| 593 void OAuth2TokenService::RevokeAllCredentials() { |
| 594 CancelAllRequests(); |
| 595 ClearCache(); |
| 596 delegate_->RevokeAllCredentials(); |
| 597 } |
| 598 |
| 584 void OAuth2TokenService::InvalidateToken(const std::string& account_id, | 599 void OAuth2TokenService::InvalidateToken(const std::string& account_id, |
| 585 const ScopeSet& scopes, | 600 const ScopeSet& scopes, |
| 586 const std::string& access_token) { | 601 const std::string& access_token) { |
| 587 InvalidateOAuth2Token(account_id, | 602 InvalidateOAuth2Token(account_id, |
| 588 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), | 603 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), |
| 589 scopes, | 604 scopes, |
| 590 access_token); | 605 access_token); |
| 591 } | 606 } |
| 592 | 607 |
| 593 void OAuth2TokenService::InvalidateTokenForClient( | 608 void OAuth2TokenService::InvalidateTokenForClient( |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 696 if (token_iterator != token_cache_.end() && | 711 if (token_iterator != token_cache_.end() && |
| 697 token_iterator->second.access_token == token_to_remove) { | 712 token_iterator->second.access_token == token_to_remove) { |
| 698 FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, | 713 FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, |
| 699 OnTokenRemoved(request_parameters.account_id, | 714 OnTokenRemoved(request_parameters.account_id, |
| 700 request_parameters.scopes)); | 715 request_parameters.scopes)); |
| 701 token_cache_.erase(token_iterator); | 716 token_cache_.erase(token_iterator); |
| 702 return true; | 717 return true; |
| 703 } | 718 } |
| 704 return false; | 719 return false; |
| 705 } | 720 } |
| 721 void OAuth2TokenService::UpdateAuthError(const std::string& account_id, |
| 722 const GoogleServiceAuthError& error) { |
| 723 delegate_->UpdateAuthError(account_id, error); |
| 724 } |
| 706 | 725 |
| 707 void OAuth2TokenService::RegisterCacheEntry( | 726 void OAuth2TokenService::RegisterCacheEntry( |
| 708 const std::string& client_id, | 727 const std::string& client_id, |
| 709 const std::string& account_id, | 728 const std::string& account_id, |
| 710 const OAuth2TokenService::ScopeSet& scopes, | 729 const OAuth2TokenService::ScopeSet& scopes, |
| 711 const std::string& access_token, | 730 const std::string& access_token, |
| 712 const base::Time& expiration_date) { | 731 const base::Time& expiration_date) { |
| 713 DCHECK(CalledOnValidThread()); | 732 DCHECK(CalledOnValidThread()); |
| 714 | 733 |
| 715 CacheEntry& token = token_cache_[RequestParameters(client_id, | 734 CacheEntry& token = token_cache_[RequestParameters(client_id, |
| 716 account_id, | 735 account_id, |
| 717 scopes)]; | 736 scopes)]; |
| 718 token.access_token = access_token; | 737 token.access_token = access_token; |
| 719 token.expiration_date = expiration_date; | 738 token.expiration_date = expiration_date; |
| 720 } | 739 } |
| 721 | 740 |
| 722 void OAuth2TokenService::UpdateAuthError( | |
| 723 const std::string& account_id, | |
| 724 const GoogleServiceAuthError& error) { | |
| 725 // Default implementation does nothing. | |
| 726 } | |
| 727 | |
| 728 void OAuth2TokenService::ClearCache() { | 741 void OAuth2TokenService::ClearCache() { |
| 729 DCHECK(CalledOnValidThread()); | 742 DCHECK(CalledOnValidThread()); |
| 730 for (TokenCache::iterator iter = token_cache_.begin(); | 743 for (TokenCache::iterator iter = token_cache_.begin(); |
| 731 iter != token_cache_.end(); ++iter) { | 744 iter != token_cache_.end(); ++iter) { |
| 732 FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, | 745 FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, |
| 733 OnTokenRemoved(iter->first.account_id, | 746 OnTokenRemoved(iter->first.account_id, |
| 734 iter->first.scopes)); | 747 iter->first.scopes)); |
| 735 } | 748 } |
| 736 | 749 |
| 737 token_cache_.clear(); | 750 token_cache_.clear(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 void OAuth2TokenService::CancelFetchers( | 792 void OAuth2TokenService::CancelFetchers( |
| 780 std::vector<Fetcher*> fetchers_to_cancel) { | 793 std::vector<Fetcher*> fetchers_to_cancel) { |
| 781 for (std::vector<OAuth2TokenService::Fetcher*>::iterator iter = | 794 for (std::vector<OAuth2TokenService::Fetcher*>::iterator iter = |
| 782 fetchers_to_cancel.begin(); | 795 fetchers_to_cancel.begin(); |
| 783 iter != fetchers_to_cancel.end(); | 796 iter != fetchers_to_cancel.end(); |
| 784 ++iter) { | 797 ++iter) { |
| 785 (*iter)->Cancel(); | 798 (*iter)->Cancel(); |
| 786 } | 799 } |
| 787 } | 800 } |
| 788 | 801 |
| 789 void OAuth2TokenService::FireRefreshTokenAvailable( | |
| 790 const std::string& account_id) { | |
| 791 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/422460 is | |
| 792 // fixed. | |
| 793 tracked_objects::ScopedTracker tracking_profile( | |
| 794 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 795 "422460 OAuth2TokenService::FireRefreshTokenAvailable")); | |
| 796 | |
| 797 FOR_EACH_OBSERVER(Observer, observer_list_, | |
| 798 OnRefreshTokenAvailable(account_id)); | |
| 799 } | |
| 800 | |
| 801 void OAuth2TokenService::FireRefreshTokenRevoked( | |
| 802 const std::string& account_id) { | |
| 803 FOR_EACH_OBSERVER(Observer, observer_list_, | |
| 804 OnRefreshTokenRevoked(account_id)); | |
| 805 } | |
| 806 | |
| 807 void OAuth2TokenService::FireRefreshTokensLoaded() { | |
| 808 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/422460 is | |
| 809 // fixed. | |
| 810 tracked_objects::ScopedTracker tracking_profile( | |
| 811 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 812 "422460 OAuth2TokenService::FireRefreshTokensLoaded")); | |
| 813 | |
| 814 FOR_EACH_OBSERVER(Observer, observer_list_, OnRefreshTokensLoaded()); | |
| 815 } | |
| 816 | |
| 817 void OAuth2TokenService::StartBatchChanges() { | |
| 818 ++batch_change_depth_; | |
| 819 if (batch_change_depth_ == 1) | |
| 820 FOR_EACH_OBSERVER(Observer, observer_list_, OnStartBatchChanges()); | |
| 821 } | |
| 822 | |
| 823 void OAuth2TokenService::EndBatchChanges() { | |
| 824 --batch_change_depth_; | |
| 825 DCHECK_LE(0, batch_change_depth_); | |
| 826 if (batch_change_depth_ == 0) | |
| 827 FOR_EACH_OBSERVER(Observer, observer_list_, OnEndBatchChanges()); | |
| 828 } | |
| 829 | |
| 830 int OAuth2TokenService::cache_size_for_testing() const { | 802 int OAuth2TokenService::cache_size_for_testing() const { |
| 831 return token_cache_.size(); | 803 return token_cache_.size(); |
| 832 } | 804 } |
| 833 | 805 |
| 834 void OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing( | 806 void OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing( |
| 835 int max_retries) { | 807 int max_retries) { |
| 836 DCHECK(CalledOnValidThread()); | 808 DCHECK(CalledOnValidThread()); |
| 837 max_fetch_retry_num_ = max_retries; | 809 max_fetch_retry_num_ = max_retries; |
| 838 } | 810 } |
| 839 | 811 |
| 840 size_t OAuth2TokenService::GetNumPendingRequestsForTesting( | 812 size_t OAuth2TokenService::GetNumPendingRequestsForTesting( |
| 841 const std::string& client_id, | 813 const std::string& client_id, |
| 842 const std::string& account_id, | 814 const std::string& account_id, |
| 843 const ScopeSet& scopes) const { | 815 const ScopeSet& scopes) const { |
| 844 PendingFetcherMap::const_iterator iter = pending_fetchers_.find( | 816 PendingFetcherMap::const_iterator iter = pending_fetchers_.find( |
| 845 OAuth2TokenService::RequestParameters( | 817 OAuth2TokenService::RequestParameters( |
| 846 client_id, | 818 client_id, |
| 847 account_id, | 819 account_id, |
| 848 scopes)); | 820 scopes)); |
| 849 return iter == pending_fetchers_.end() ? | 821 return iter == pending_fetchers_.end() ? |
| 850 0 : iter->second->GetWaitingRequestCount(); | 822 0 : iter->second->GetWaitingRequestCount(); |
| 851 } | 823 } |
| OLD | NEW |