signin_manager.cc revision 4a5e2dc747d50c653511c68ccb2cfbfb740bd5a7
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 17SigninManager::SigninManager() 18 : profile_(NULL), had_two_factor_error_(false) {} 19 20SigninManager::~SigninManager() {} 21 22// static 23void SigninManager::RegisterUserPrefs(PrefService* user_prefs) { 24 user_prefs->RegisterStringPref(prefs::kGoogleServicesUsername, ""); 25} 26 27void SigninManager::Initialize(Profile* profile) { 28 profile_ = profile; 29 username_ = profile_->GetPrefs()->GetString(prefs::kGoogleServicesUsername); 30 profile_->GetTokenService()->Initialize( 31 GaiaConstants::kChromeSource, profile_); 32 if (!username_.empty()) { 33 profile_->GetTokenService()->LoadTokensFromDB(); 34 } 35} 36 37// If a username already exists, the user is logged in. 38const std::string& SigninManager::GetUsername() { 39 return username_; 40} 41 42void SigninManager::SetUsername(const std::string& username) { 43 username_ = username; 44} 45 46// Users must always sign out before they sign in again. 47void SigninManager::StartSignIn(const std::string& username, 48 const std::string& password, 49 const std::string& login_token, 50 const std::string& login_captcha) { 51 DCHECK(username_.empty()); 52 // The Sign out should clear the token service credentials. 53 DCHECK(!profile_->GetTokenService()->AreCredentialsValid()); 54 55 username_.assign(username); 56 password_.assign(password); 57 58 client_login_.reset(new GaiaAuthFetcher(this, 59 GaiaConstants::kChromeSource, 60 profile_->GetRequestContext())); 61 client_login_->StartClientLogin(username, 62 password, 63 "", 64 login_token, 65 login_captcha, 66 GaiaAuthFetcher::HostedAccountsNotAllowed); 67} 68 69void SigninManager::ProvideSecondFactorAccessCode( 70 const std::string& access_code) { 71 DCHECK(!username_.empty() && !password_.empty() && 72 last_result_.data.empty()); 73 74 client_login_.reset(new GaiaAuthFetcher(this, 75 GaiaConstants::kChromeSource, 76 profile_->GetRequestContext())); 77 client_login_->StartClientLogin(username_, 78 access_code, 79 "", 80 std::string(), 81 std::string(), 82 GaiaAuthFetcher::HostedAccountsNotAllowed); 83} 84 85void SigninManager::SignOut() { 86 if (!profile_) 87 return; 88 89 client_login_.reset(); 90 last_result_ = ClientLoginResult(); 91 username_.clear(); 92 password_.clear(); 93 had_two_factor_error_ = false; 94 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername, username_); 95 profile_->GetPrefs()->ScheduleSavePersistentPrefs(); 96 profile_->GetTokenService()->ResetCredentialsInMemory(); 97 profile_->GetTokenService()->EraseTokensFromDB(); 98} 99 100void SigninManager::OnClientLoginSuccess(const ClientLoginResult& result) { 101 last_result_ = result; 102 // Make a request for the canonical email address. 103 client_login_->StartGetUserInfo(result.lsid, kGetInfoEmailKey); 104} 105 106void SigninManager::OnGetUserInfoSuccess(const std::string& key, 107 const std::string& value) { 108 DCHECK(key == kGetInfoEmailKey); 109 110 username_ = value; 111 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername, username_); 112 profile_->GetPrefs()->ScheduleSavePersistentPrefs(); 113 114 GoogleServiceSigninSuccessDetails details(username_, password_); 115 NotificationService::current()->Notify( 116 NotificationType::GOOGLE_SIGNIN_SUCCESSFUL, 117 Source<Profile>(profile_), 118 Details<const GoogleServiceSigninSuccessDetails>(&details)); 119 120 password_.clear(); // Don't need it anymore. 121 122 profile_->GetTokenService()->UpdateCredentials(last_result_); 123 DCHECK(profile_->GetTokenService()->AreCredentialsValid()); 124 profile_->GetTokenService()->StartFetchingTokens(); 125} 126 127void SigninManager::OnGetUserInfoKeyNotFound(const std::string& key) { 128 DCHECK(key == kGetInfoEmailKey); 129 LOG(ERROR) << "Account is not associated with a valid email address. " 130 << "Login failed."; 131 OnClientLoginFailure(GoogleServiceAuthError( 132 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); 133} 134 135void SigninManager::OnGetUserInfoFailure(const GoogleServiceAuthError& error) { 136 LOG(ERROR) << "Unable to retreive the canonical email address. Login failed."; 137 OnClientLoginFailure(error); 138} 139 140void SigninManager::OnClientLoginFailure(const GoogleServiceAuthError& error) { 141 NotificationService::current()->Notify( 142 NotificationType::GOOGLE_SIGNIN_FAILED, 143 Source<Profile>(profile_), 144 Details<const GoogleServiceAuthError>(&error)); 145 146 // We don't sign-out if the password was valid and we're just dealing with 147 // a second factor error, and we don't sign out if we're dealing with 148 // an invalid access code (again, because the password was valid). 149 bool invalid_gaia = error.state() == 150 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS; 151 if (error.state() == GoogleServiceAuthError::TWO_FACTOR || 152 (had_two_factor_error_ && invalid_gaia)) { 153 had_two_factor_error_ = true; 154 return; 155 } 156 157 SignOut(); 158} 159