OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 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_client_login.h" |
| 6 |
| 7 #include "base/command_line.h" |
| 8 #include "base/string_util.h" |
| 9 #include "chrome/browser/net/gaia/token_service.h" |
| 10 #include "chrome/browser/prefs/pref_service.h" |
| 11 #include "chrome/browser/profiles/profile.h" |
| 12 #include "chrome/common/chrome_switches.h" |
| 13 #include "chrome/common/net/gaia/gaia_auth_fetcher.h" |
| 14 #include "chrome/common/net/gaia/gaia_constants.h" |
| 15 #include "chrome/common/net/gaia/authentication_fetcher_oauth.h" |
| 16 #include "chrome/common/pref_names.h" |
| 17 #include "content/common/notification_service.h" |
| 18 |
| 19 const char kGetInfoEmailKey[] = "email"; |
| 20 |
| 21 // static |
| 22 const char SigninManagerClientLogin::kSigninManagerVariantName[] = |
| 23 "Google Client Login"; |
| 24 |
| 25 SigninManagerClientLogin::SigninManagerClientLogin() |
| 26 : profile_(NULL), had_two_factor_error_(false) {} |
| 27 |
| 28 SigninManagerClientLogin::~SigninManagerClientLogin() {} |
| 29 |
| 30 // static |
| 31 void SigninManagerClientLogin::RegisterUserPrefs(PrefService* user_prefs) { |
| 32 user_prefs->RegisterStringPref(prefs::kGoogleServicesUsername, ""); |
| 33 } |
| 34 |
| 35 // virtual |
| 36 void SigninManagerClientLogin::Initialize(Profile* profile) { |
| 37 profile_ = profile; |
| 38 username_ = profile_->GetPrefs()->GetString(prefs::kGoogleServicesUsername); |
| 39 profile_->GetTokenService()->Initialize( |
| 40 GaiaConstants::kChromeSource, profile_); |
| 41 if (!username_.empty()) { |
| 42 profile_->GetTokenService()->LoadTokensFromDB(); |
| 43 } |
| 44 } |
| 45 |
| 46 // If a username already exists, the user is logged in. |
| 47 const std::string& SigninManagerClientLogin::GetUsername() { |
| 48 return username_; |
| 49 } |
| 50 |
| 51 void SigninManagerClientLogin::SetUsername(const std::string& username) { |
| 52 username_ = username; |
| 53 } |
| 54 |
| 55 void SigninManagerClientLogin::StartSignIn( |
| 56 const std::string& username, |
| 57 const std::string& password, |
| 58 const std::string& login_token, |
| 59 const std::string& login_captcha) { |
| 60 DCHECK(username_.empty()); |
| 61 #if !defined(OS_CHROMEOS) |
| 62 // The Sign out should clear the token service credentials. |
| 63 // Note: In CHROMEOS we might have valid credentials but still need to |
| 64 // set up 2-factor authentication. |
| 65 DCHECK(!profile_->GetTokenService()->AreCredentialsValid()); |
| 66 #endif |
| 67 username_.assign(username); |
| 68 password_.assign(password); |
| 69 |
| 70 fetcher_.reset(new GaiaAuthFetcher(this, |
| 71 GaiaConstants::kChromeSource, |
| 72 profile_->GetRequestContext())); |
| 73 fetcher_->StartAuthentication(username, |
| 74 password, |
| 75 "", |
| 76 login_token, |
| 77 login_captcha, |
| 78 GaiaAuthFetcher::HostedAccountsNotAllowed); |
| 79 } |
| 80 |
| 81 void SigninManagerClientLogin::ProvideSecondFactorAccessCode( |
| 82 const std::string& access_code) { |
| 83 DCHECK(!username_.empty() && !password_.empty() && |
| 84 static_cast<GaiaAuthConsumer::ClientLoginResult*>( |
| 85 last_result_.get())->data.empty()); |
| 86 |
| 87 fetcher_.reset(new GaiaAuthFetcher(this, |
| 88 GaiaConstants::kChromeSource, |
| 89 profile_->GetRequestContext())); |
| 90 fetcher_->StartAuthentication(username_, |
| 91 access_code, |
| 92 "", |
| 93 std::string(), |
| 94 std::string(), |
| 95 GaiaAuthFetcher::HostedAccountsNotAllowed); |
| 96 } |
| 97 |
| 98 void SigninManagerClientLogin::SignOut() { |
| 99 if (!profile_) |
| 100 return; |
| 101 |
| 102 fetcher_.reset(); |
| 103 last_result_.reset(new ClientLoginResult()); |
| 104 username_.clear(); |
| 105 password_.clear(); |
| 106 had_two_factor_error_ = false; |
| 107 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername, username_); |
| 108 profile_->GetPrefs()->ScheduleSavePersistentPrefs(); |
| 109 profile_->GetTokenService()->ResetCredentialsInMemory(); |
| 110 profile_->GetTokenService()->EraseTokensFromDB(); |
| 111 } |
| 112 |
| 113 void SigninManagerClientLogin::OnClientLoginSuccess(ClientLoginResult* result) { |
| 114 last_result_.reset(result); |
| 115 // Make a request for the canonical email address. |
| 116 fetcher_->StartGetUserInfo( |
| 117 static_cast<GaiaAuthConsumer::ClientLoginResult*>(result)->lsid, |
| 118 kGetInfoEmailKey); |
| 119 } |
| 120 |
| 121 void SigninManagerClientLogin::OnGetUserInfoSuccess(const std::string& key, |
| 122 const std::string& value) { |
| 123 DCHECK(key == kGetInfoEmailKey); |
| 124 |
| 125 username_ = value; |
| 126 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername, username_); |
| 127 profile_->GetPrefs()->ScheduleSavePersistentPrefs(); |
| 128 |
| 129 GoogleServiceSigninSuccessDetails details(username_, password_); |
| 130 NotificationService::current()->Notify( |
| 131 NotificationType::GOOGLE_SIGNIN_SUCCESSFUL, |
| 132 Source<Profile>(profile_), |
| 133 Details<const GoogleServiceSigninSuccessDetails>(&details)); |
| 134 |
| 135 password_.clear(); // Don't need it anymore. |
| 136 |
| 137 profile_->GetTokenService()->UpdateCredentials( |
| 138 *static_cast<GaiaAuthConsumer::ClientLoginResult*>(last_result_.get())); |
| 139 DCHECK(profile_->GetTokenService()->AreCredentialsValid()); |
| 140 profile_->GetTokenService()->StartFetchingTokens(); |
| 141 } |
| 142 |
| 143 void SigninManagerClientLogin::OnGetUserInfoKeyNotFound( |
| 144 const std::string& key) { |
| 145 DCHECK(key == kGetInfoEmailKey); |
| 146 LOG(ERROR) << "Account is not associated with a valid email address. " |
| 147 << "Login failed."; |
| 148 OnClientLoginFailure(GoogleServiceAuthError( |
| 149 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); |
| 150 } |
| 151 |
| 152 void SigninManagerClientLogin::OnGetUserInfoFailure( |
| 153 const GoogleServiceAuthError& error) { |
| 154 LOG(ERROR) << "Unable to retreive the canonical email address. Login failed."; |
| 155 OnClientLoginFailure(error); |
| 156 } |
| 157 |
| 158 void SigninManagerClientLogin::OnClientLoginFailure( |
| 159 const GoogleServiceAuthError& error) { |
| 160 NotificationService::current()->Notify( |
| 161 NotificationType::GOOGLE_SIGNIN_FAILED, |
| 162 Source<Profile>(profile_), |
| 163 Details<const GoogleServiceAuthError>(&error)); |
| 164 |
| 165 // We don't sign-out if the password was valid and we're just dealing with |
| 166 // a second factor error, and we don't sign out if we're dealing with |
| 167 // an invalid access code (again, because the password was valid). |
| 168 bool invalid_gaia = error.state() == |
| 169 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS; |
| 170 if (error.state() == GoogleServiceAuthError::TWO_FACTOR || |
| 171 (had_two_factor_error_ && invalid_gaia)) { |
| 172 had_two_factor_error_ = true; |
| 173 return; |
| 174 } |
| 175 |
| 176 SignOut(); |
| 177 } |
OLD | NEW |