1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "components/signin/core/browser/signin_account_id_helper.h" 6 7#include "base/prefs/pref_service.h" 8#include "components/signin/core/browser/profile_oauth2_token_service.h" 9#include "components/signin/core/browser/signin_client.h" 10#include "components/signin/core/common/signin_pref_names.h" 11#include "google_apis/gaia/gaia_oauth_client.h" 12 13// TODO(guohui): this class should be moved to a more generic place for reuse. 14class SigninAccountIdHelper::GaiaIdFetcher 15 : public OAuth2TokenService::Consumer, 16 public gaia::GaiaOAuthClient::Delegate { 17 public: 18 GaiaIdFetcher(SigninClient* client, 19 ProfileOAuth2TokenService* token_service, 20 SigninManagerBase* signin_manager, 21 SigninAccountIdHelper* signin_account_id_helper); 22 virtual ~GaiaIdFetcher(); 23 24 // OAuth2TokenService::Consumer implementation. 25 virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request, 26 const std::string& access_token, 27 const base::Time& expiration_time) OVERRIDE; 28 virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request, 29 const GoogleServiceAuthError& error) OVERRIDE; 30 31 // gaia::GaiaOAuthClient::Delegate implementation. 32 virtual void OnGetUserIdResponse(const std::string& gaia_id) OVERRIDE; 33 virtual void OnOAuthError() OVERRIDE; 34 virtual void OnNetworkError(int response_code) OVERRIDE; 35 36 private: 37 void Start(); 38 39 SigninClient* client_; 40 ProfileOAuth2TokenService* token_service_; 41 SigninManagerBase* signin_manager_; 42 SigninAccountIdHelper* signin_account_id_helper_; 43 44 scoped_ptr<OAuth2TokenService::Request> login_token_request_; 45 scoped_ptr<gaia::GaiaOAuthClient> gaia_oauth_client_; 46 47 DISALLOW_COPY_AND_ASSIGN(GaiaIdFetcher); 48}; 49 50SigninAccountIdHelper::GaiaIdFetcher::GaiaIdFetcher( 51 SigninClient* client, 52 ProfileOAuth2TokenService* token_service, 53 SigninManagerBase* signin_manager, 54 SigninAccountIdHelper* signin_account_id_helper) 55 : OAuth2TokenService::Consumer("gaia_id_fetcher"), 56 client_(client), 57 token_service_(token_service), 58 signin_manager_(signin_manager), 59 signin_account_id_helper_(signin_account_id_helper) { 60 Start(); 61} 62 63SigninAccountIdHelper::GaiaIdFetcher::~GaiaIdFetcher() {} 64 65void SigninAccountIdHelper::GaiaIdFetcher::Start() { 66 OAuth2TokenService::ScopeSet scopes; 67 scopes.insert("https://www.googleapis.com/auth/userinfo.profile"); 68 login_token_request_ = token_service_->StartRequest( 69 signin_manager_->GetAuthenticatedAccountId(), scopes, this); 70} 71 72void SigninAccountIdHelper::GaiaIdFetcher::OnGetTokenSuccess( 73 const OAuth2TokenService::Request* request, 74 const std::string& access_token, 75 const base::Time& expiration_time) { 76 DCHECK_EQ(request, login_token_request_.get()); 77 78 gaia_oauth_client_.reset( 79 new gaia::GaiaOAuthClient(client_->GetURLRequestContext())); 80 81 const int kMaxGetUserIdRetries = 3; 82 gaia_oauth_client_->GetUserId(access_token, kMaxGetUserIdRetries, this); 83} 84 85void SigninAccountIdHelper::GaiaIdFetcher::OnGetTokenFailure( 86 const OAuth2TokenService::Request* request, 87 const GoogleServiceAuthError& error) { 88 VLOG(1) << "OnGetTokenFailure: " << error.error_message(); 89 DCHECK_EQ(request, login_token_request_.get()); 90 signin_account_id_helper_->OnPrimaryAccountIdFetched(""); 91} 92 93void SigninAccountIdHelper::GaiaIdFetcher::OnGetUserIdResponse( 94 const std::string& gaia_id) { 95 signin_account_id_helper_->OnPrimaryAccountIdFetched(gaia_id); 96} 97 98void SigninAccountIdHelper::GaiaIdFetcher::OnOAuthError() { 99 VLOG(1) << "OnOAuthError"; 100} 101 102void SigninAccountIdHelper::GaiaIdFetcher::OnNetworkError(int response_code) { 103 VLOG(1) << "OnNetworkError " << response_code; 104} 105 106SigninAccountIdHelper::SigninAccountIdHelper( 107 SigninClient* client, 108 ProfileOAuth2TokenService* token_service, 109 SigninManagerBase* signin_manager) 110 : client_(client), 111 token_service_(token_service), 112 signin_manager_(signin_manager) { 113 DCHECK(client_); 114 DCHECK(token_service_); 115 DCHECK(signin_manager_); 116 signin_manager_->AddObserver(this); 117 std::string primary_email = signin_manager_->GetAuthenticatedAccountId(); 118 if (!primary_email.empty() && 119 token_service_->RefreshTokenIsAvailable(primary_email) && 120 !disable_for_test_) { 121 id_fetcher_.reset( 122 new GaiaIdFetcher(client_, token_service_, signin_manager_, this)); 123 } 124 token_service_->AddObserver(this); 125} 126 127SigninAccountIdHelper::~SigninAccountIdHelper() { 128 signin_manager_->RemoveObserver(this); 129 token_service_->RemoveObserver(this); 130} 131 132void SigninAccountIdHelper::GoogleSignedOut(const std::string& account_id, 133 const std::string& username) { 134 client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUserAccountId); 135} 136 137void SigninAccountIdHelper::OnRefreshTokenAvailable( 138 const std::string& account_id) { 139 if (account_id == signin_manager_->GetAuthenticatedAccountId()) { 140 std::string current_gaia_id = 141 client_->GetPrefs()->GetString(prefs::kGoogleServicesUserAccountId); 142 if (current_gaia_id.empty() && !disable_for_test_) { 143 id_fetcher_.reset( 144 new GaiaIdFetcher(client_, token_service_, signin_manager_, this)); 145 } 146 } 147} 148 149void SigninAccountIdHelper::OnPrimaryAccountIdFetched( 150 const std::string& gaia_id) { 151 if (!gaia_id.empty()) { 152 client_->GetPrefs()->SetString(prefs::kGoogleServicesUserAccountId, 153 gaia_id); 154 } 155} 156 157// static 158bool SigninAccountIdHelper::disable_for_test_ = false; 159 160// static 161void SigninAccountIdHelper::SetDisableForTest(bool disable_for_test) { 162 disable_for_test_ = disable_for_test; 163} 164