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 |