1e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file. 4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 5e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/signin_account_id_helper.h" 6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/prefs/pref_service.h" 8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/profile_oauth2_token_service.h" 9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/signin_client.h" 10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/common/signin_pref_names.h" 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/gaia/gaia_oauth_client.h" 12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// TODO(guohui): this class should be moved to a more generic place for reuse. 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class SigninAccountIdHelper::GaiaIdFetcher 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : public OAuth2TokenService::Consumer, 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public gaia::GaiaOAuthClient::Delegate { 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch GaiaIdFetcher(SigninClient* client, 19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ProfileOAuth2TokenService* token_service, 20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SigninManagerBase* signin_manager, 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SigninAccountIdHelper* signin_account_id_helper); 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~GaiaIdFetcher(); 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // OAuth2TokenService::Consumer implementation. 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request, 26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& access_token, 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::Time& expiration_time) OVERRIDE; 28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request, 29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const GoogleServiceAuthError& error) OVERRIDE; 30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // gaia::GaiaOAuthClient::Delegate implementation. 32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void OnGetUserIdResponse(const std::string& gaia_id) OVERRIDE; 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void OnOAuthError() OVERRIDE; 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void OnNetworkError(int response_code) OVERRIDE; 35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private: 37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void Start(); 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SigninClient* client_; 40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ProfileOAuth2TokenService* token_service_; 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SigninManagerBase* signin_manager_; 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SigninAccountIdHelper* signin_account_id_helper_; 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<OAuth2TokenService::Request> login_token_request_; 45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<gaia::GaiaOAuthClient> gaia_oauth_client_; 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(GaiaIdFetcher); 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SigninAccountIdHelper::GaiaIdFetcher::GaiaIdFetcher( 51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SigninClient* client, 52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ProfileOAuth2TokenService* token_service, 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SigninManagerBase* signin_manager, 54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SigninAccountIdHelper* signin_account_id_helper) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : OAuth2TokenService::Consumer("gaia_id_fetcher"), 56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch client_(client), 57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch token_service_(token_service), 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) signin_manager_(signin_manager), 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) signin_account_id_helper_(signin_account_id_helper) { 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Start(); 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SigninAccountIdHelper::GaiaIdFetcher::~GaiaIdFetcher() {} 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SigninAccountIdHelper::GaiaIdFetcher::Start() { 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OAuth2TokenService::ScopeSet scopes; 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scopes.insert("https://www.googleapis.com/auth/userinfo.profile"); 68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch login_token_request_ = token_service_->StartRequest( 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) signin_manager_->GetAuthenticatedAccountId(), scopes, this); 70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SigninAccountIdHelper::GaiaIdFetcher::OnGetTokenSuccess( 73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const OAuth2TokenService::Request* request, 74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& access_token, 75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::Time& expiration_time) { 76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_EQ(request, login_token_request_.get()); 77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gaia_oauth_client_.reset( 79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new gaia::GaiaOAuthClient(client_->GetURLRequestContext())); 80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const int kMaxGetUserIdRetries = 3; 82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gaia_oauth_client_->GetUserId(access_token, kMaxGetUserIdRetries, this); 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SigninAccountIdHelper::GaiaIdFetcher::OnGetTokenFailure( 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const OAuth2TokenService::Request* request, 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const GoogleServiceAuthError& error) { 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) VLOG(1) << "OnGetTokenFailure: " << error.error_message(); 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_EQ(request, login_token_request_.get()); 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) signin_account_id_helper_->OnPrimaryAccountIdFetched(""); 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SigninAccountIdHelper::GaiaIdFetcher::OnGetUserIdResponse( 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& gaia_id) { 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) signin_account_id_helper_->OnPrimaryAccountIdFetched(gaia_id); 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SigninAccountIdHelper::GaiaIdFetcher::OnOAuthError() { 99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) VLOG(1) << "OnOAuthError"; 100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 102e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid SigninAccountIdHelper::GaiaIdFetcher::OnNetworkError(int response_code) { 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) VLOG(1) << "OnNetworkError " << response_code; 104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 106effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochSigninAccountIdHelper::SigninAccountIdHelper( 107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SigninClient* client, 108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ProfileOAuth2TokenService* token_service, 109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SigninManagerBase* signin_manager) 110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : client_(client), 111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch token_service_(token_service), 112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch signin_manager_(signin_manager) { 113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(client_); 114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(token_service_); 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(signin_manager_); 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) signin_manager_->AddObserver(this); 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string primary_email = signin_manager_->GetAuthenticatedAccountId(); 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!primary_email.empty() && 119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch token_service_->RefreshTokenIsAvailable(primary_email) && 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !disable_for_test_) { 121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch id_fetcher_.reset( 122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new GaiaIdFetcher(client_, token_service_, signin_manager_, this)); 123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch token_service_->AddObserver(this); 125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)SigninAccountIdHelper::~SigninAccountIdHelper() { 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) signin_manager_->RemoveObserver(this); 129effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch token_service_->RemoveObserver(this); 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid SigninAccountIdHelper::GoogleSignedOut(const std::string& account_id, 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& username) { 134effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUserAccountId); 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SigninAccountIdHelper::OnRefreshTokenAvailable( 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& account_id) { 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (account_id == signin_manager_->GetAuthenticatedAccountId()) { 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string current_gaia_id = 141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch client_->GetPrefs()->GetString(prefs::kGoogleServicesUserAccountId); 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (current_gaia_id.empty() && !disable_for_test_) { 143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch id_fetcher_.reset( 144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new GaiaIdFetcher(client_, token_service_, signin_manager_, this)); 145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SigninAccountIdHelper::OnPrimaryAccountIdFetched( 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& gaia_id) { 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!gaia_id.empty()) { 152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch client_->GetPrefs()->SetString(prefs::kGoogleServicesUserAccountId, 153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch gaia_id); 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SigninAccountIdHelper::disable_for_test_ = false; 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SigninAccountIdHelper::SetDisableForTest(bool disable_for_test) { 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) disable_for_test_ = disable_for_test; 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 164