Home | History | Annotate | Download | only in browser
      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.
     14 class 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 
     50 SigninAccountIdHelper::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 
     63 SigninAccountIdHelper::GaiaIdFetcher::~GaiaIdFetcher() {}
     64 
     65 void 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 
     72 void 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 
     85 void 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 
     93 void SigninAccountIdHelper::GaiaIdFetcher::OnGetUserIdResponse(
     94     const std::string& gaia_id) {
     95   signin_account_id_helper_->OnPrimaryAccountIdFetched(gaia_id);
     96 }
     97 
     98 void SigninAccountIdHelper::GaiaIdFetcher::OnOAuthError() {
     99   VLOG(1) << "OnOAuthError";
    100 }
    101 
    102 void SigninAccountIdHelper::GaiaIdFetcher::OnNetworkError(int response_code) {
    103   VLOG(1) << "OnNetworkError " << response_code;
    104 }
    105 
    106 SigninAccountIdHelper::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 
    127 SigninAccountIdHelper::~SigninAccountIdHelper() {
    128   signin_manager_->RemoveObserver(this);
    129   token_service_->RemoveObserver(this);
    130 }
    131 
    132 void SigninAccountIdHelper::GoogleSignedOut(const std::string& username) {
    133   client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUserAccountId);
    134 }
    135 
    136 void SigninAccountIdHelper::OnRefreshTokenAvailable(
    137     const std::string& account_id) {
    138   if (account_id == signin_manager_->GetAuthenticatedAccountId()) {
    139     std::string current_gaia_id =
    140         client_->GetPrefs()->GetString(prefs::kGoogleServicesUserAccountId);
    141     if (current_gaia_id.empty() && !disable_for_test_) {
    142       id_fetcher_.reset(
    143           new GaiaIdFetcher(client_, token_service_, signin_manager_, this));
    144     }
    145   }
    146 }
    147 
    148 void SigninAccountIdHelper::OnPrimaryAccountIdFetched(
    149     const std::string& gaia_id) {
    150   if (!gaia_id.empty()) {
    151     client_->GetPrefs()->SetString(prefs::kGoogleServicesUserAccountId,
    152                                    gaia_id);
    153   }
    154 }
    155 
    156 // static
    157 bool SigninAccountIdHelper::disable_for_test_ = false;
    158 
    159 // static
    160 void SigninAccountIdHelper::SetDisableForTest(bool disable_for_test) {
    161   disable_for_test_ = disable_for_test;
    162 }
    163