signin_account_id_helper.cc revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
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& username) {
133  client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUserAccountId);
134}
135
136void 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
148void 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
157bool SigninAccountIdHelper::disable_for_test_ = false;
158
159// static
160void SigninAccountIdHelper::SetDisableForTest(bool disable_for_test) {
161  disable_for_test_ = disable_for_test;
162}
163