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