signin_manager.cc revision bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293
1// Copyright (c) 2010 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 "chrome/browser/sync/signin_manager.h"
6
7#include "base/string_util.h"
8#include "chrome/browser/net/gaia/token_service.h"
9#include "chrome/browser/prefs/pref_service.h"
10#include "chrome/browser/profile.h"
11#include "chrome/common/net/gaia/gaia_constants.h"
12#include "chrome/common/notification_service.h"
13#include "chrome/common/pref_names.h"
14
15const char kGetInfoEmailKey[] = "email";
16
17// static
18void SigninManager::RegisterUserPrefs(PrefService* user_prefs) {
19  user_prefs->RegisterStringPref(prefs::kGoogleServicesUsername, "");
20}
21
22void SigninManager::Initialize(Profile* profile) {
23  profile_ = profile;
24  username_ = profile_->GetPrefs()->GetString(prefs::kGoogleServicesUsername);
25  profile_->GetTokenService()->Initialize(
26      GaiaConstants::kChromeSource, profile_);
27  if (!username_.empty()) {
28    profile_->GetTokenService()->LoadTokensFromDB();
29  }
30}
31
32// If a username already exists, the user is logged in.
33const std::string& SigninManager::GetUsername() {
34  return username_;
35}
36
37void SigninManager::SetUsername(const std::string& username) {
38  username_ = username;
39}
40
41// Users must always sign out before they sign in again.
42void SigninManager::StartSignIn(const std::string& username,
43                                const std::string& password,
44                                const std::string& login_token,
45                                const std::string& login_captcha) {
46  DCHECK(username_.empty());
47  // The Sign out should clear the token service credentials.
48  DCHECK(!profile_->GetTokenService()->AreCredentialsValid());
49
50  username_.assign(username);
51  password_.assign(password);
52
53  client_login_.reset(new GaiaAuthenticator2(this,
54                                             GaiaConstants::kChromeSource,
55                                             profile_->GetRequestContext()));
56  client_login_->StartClientLogin(username,
57                                  password,
58                                  "",
59                                  login_token,
60                                  login_captcha);
61}
62
63void SigninManager::SignOut() {
64  client_login_.reset();
65  last_result_ = ClientLoginResult();
66  username_.clear();
67  password_.clear();
68  profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername, username_);
69  profile_->GetPrefs()->ScheduleSavePersistentPrefs();
70  profile_->GetTokenService()->ResetCredentialsInMemory();
71  profile_->GetTokenService()->EraseTokensFromDB();
72}
73
74void SigninManager::OnClientLoginSuccess(const ClientLoginResult& result) {
75  last_result_ = result;
76  // Make a request for the canonical email address.
77  client_login_->StartGetUserInfo(result.lsid, kGetInfoEmailKey);
78}
79
80void SigninManager::OnGetUserInfoSuccess(const std::string& key,
81                                         const std::string& value) {
82  DCHECK(key == kGetInfoEmailKey);
83
84  username_ = value;
85  profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername, username_);
86  profile_->GetPrefs()->ScheduleSavePersistentPrefs();
87
88  GoogleServiceSigninSuccessDetails details(username_, password_);
89  NotificationService::current()->Notify(
90      NotificationType::GOOGLE_SIGNIN_SUCCESSFUL,
91      Source<SigninManager>(this),
92      Details<const GoogleServiceSigninSuccessDetails>(&details));
93
94  password_.clear();  // Don't need it anymore.
95
96  profile_->GetTokenService()->UpdateCredentials(last_result_);
97  DCHECK(profile_->GetTokenService()->AreCredentialsValid());
98  profile_->GetTokenService()->StartFetchingTokens();
99}
100
101void SigninManager::OnGetUserInfoKeyNotFound(const std::string& key) {
102  DCHECK(key == kGetInfoEmailKey);
103  LOG(ERROR) << "Account is not associated with a valid email address. "
104             << "Login failed.";
105  OnClientLoginFailure(GoogleServiceAuthError(
106      GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
107}
108
109void SigninManager::OnGetUserInfoFailure(const GoogleServiceAuthError& error) {
110  LOG(ERROR) << "Unable to retreive the canonical email address. Login failed.";
111  OnClientLoginFailure(error);
112}
113
114void SigninManager::OnClientLoginFailure(const GoogleServiceAuthError& error) {
115  GoogleServiceAuthError details(error);
116  NotificationService::current()->Notify(
117      NotificationType::GOOGLE_SIGNIN_FAILED,
118      Source<SigninManager>(this),
119      Details<const GoogleServiceAuthError>(&details));
120  SignOut();
121}
122