Index: chrome/browser/sync/signin_manager_client_login.cc |
diff --git a/chrome/browser/sync/signin_manager_client_login.cc b/chrome/browser/sync/signin_manager_client_login.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..00fe7012306b0e511a7fcefc5368ed845ac71630 |
--- /dev/null |
+++ b/chrome/browser/sync/signin_manager_client_login.cc |
@@ -0,0 +1,177 @@ |
+// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/sync/signin_manager_client_login.h" |
+ |
+#include "base/command_line.h" |
+#include "base/string_util.h" |
+#include "chrome/browser/net/gaia/token_service.h" |
+#include "chrome/browser/prefs/pref_service.h" |
+#include "chrome/browser/profiles/profile.h" |
+#include "chrome/common/chrome_switches.h" |
+#include "chrome/common/net/gaia/gaia_auth_fetcher.h" |
+#include "chrome/common/net/gaia/gaia_constants.h" |
+#include "chrome/common/net/gaia/authentication_fetcher_oauth.h" |
+#include "chrome/common/pref_names.h" |
+#include "content/common/notification_service.h" |
+ |
+const char kGetInfoEmailKey[] = "email"; |
+ |
+// static |
+const char SigninManagerClientLogin::kSigninManagerVariantName[] = |
+ "Google Client Login"; |
+ |
+SigninManagerClientLogin::SigninManagerClientLogin() |
+ : profile_(NULL), had_two_factor_error_(false) {} |
+ |
+SigninManagerClientLogin::~SigninManagerClientLogin() {} |
+ |
+// static |
+void SigninManagerClientLogin::RegisterUserPrefs(PrefService* user_prefs) { |
+ user_prefs->RegisterStringPref(prefs::kGoogleServicesUsername, ""); |
+} |
+ |
+// virtual |
+void SigninManagerClientLogin::Initialize(Profile* profile) { |
+ profile_ = profile; |
+ username_ = profile_->GetPrefs()->GetString(prefs::kGoogleServicesUsername); |
+ profile_->GetTokenService()->Initialize( |
+ GaiaConstants::kChromeSource, profile_); |
+ if (!username_.empty()) { |
+ profile_->GetTokenService()->LoadTokensFromDB(); |
+ } |
+} |
+ |
+// If a username already exists, the user is logged in. |
+const std::string& SigninManagerClientLogin::GetUsername() { |
+ return username_; |
+} |
+ |
+void SigninManagerClientLogin::SetUsername(const std::string& username) { |
+ username_ = username; |
+} |
+ |
+void SigninManagerClientLogin::StartSignIn( |
+ const std::string& username, |
+ const std::string& password, |
+ const std::string& login_token, |
+ const std::string& login_captcha) { |
+ DCHECK(username_.empty()); |
+#if !defined(OS_CHROMEOS) |
+ // The Sign out should clear the token service credentials. |
+ // Note: In CHROMEOS we might have valid credentials but still need to |
+ // set up 2-factor authentication. |
+ DCHECK(!profile_->GetTokenService()->AreCredentialsValid()); |
+#endif |
+ username_.assign(username); |
+ password_.assign(password); |
+ |
+ fetcher_.reset(new GaiaAuthFetcher(this, |
+ GaiaConstants::kChromeSource, |
+ profile_->GetRequestContext())); |
+ fetcher_->StartAuthentication(username, |
+ password, |
+ "", |
+ login_token, |
+ login_captcha, |
+ GaiaAuthFetcher::HostedAccountsNotAllowed); |
+} |
+ |
+void SigninManagerClientLogin::ProvideSecondFactorAccessCode( |
+ const std::string& access_code) { |
+ DCHECK(!username_.empty() && !password_.empty() && |
+ static_cast<GaiaAuthConsumer::ClientLoginResult*>( |
+ last_result_.get())->data.empty()); |
+ |
+ fetcher_.reset(new GaiaAuthFetcher(this, |
+ GaiaConstants::kChromeSource, |
+ profile_->GetRequestContext())); |
+ fetcher_->StartAuthentication(username_, |
+ access_code, |
+ "", |
+ std::string(), |
+ std::string(), |
+ GaiaAuthFetcher::HostedAccountsNotAllowed); |
+} |
+ |
+void SigninManagerClientLogin::SignOut() { |
+ if (!profile_) |
+ return; |
+ |
+ fetcher_.reset(); |
+ last_result_.reset(new ClientLoginResult()); |
+ username_.clear(); |
+ password_.clear(); |
+ had_two_factor_error_ = false; |
+ profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername, username_); |
+ profile_->GetPrefs()->ScheduleSavePersistentPrefs(); |
+ profile_->GetTokenService()->ResetCredentialsInMemory(); |
+ profile_->GetTokenService()->EraseTokensFromDB(); |
+} |
+ |
+void SigninManagerClientLogin::OnClientLoginSuccess(ClientLoginResult* result) { |
+ last_result_.reset(result); |
+ // Make a request for the canonical email address. |
+ fetcher_->StartGetUserInfo( |
+ static_cast<GaiaAuthConsumer::ClientLoginResult*>(result)->lsid, |
+ kGetInfoEmailKey); |
+} |
+ |
+void SigninManagerClientLogin::OnGetUserInfoSuccess(const std::string& key, |
+ const std::string& value) { |
+ DCHECK(key == kGetInfoEmailKey); |
+ |
+ username_ = value; |
+ profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername, username_); |
+ profile_->GetPrefs()->ScheduleSavePersistentPrefs(); |
+ |
+ GoogleServiceSigninSuccessDetails details(username_, password_); |
+ NotificationService::current()->Notify( |
+ NotificationType::GOOGLE_SIGNIN_SUCCESSFUL, |
+ Source<Profile>(profile_), |
+ Details<const GoogleServiceSigninSuccessDetails>(&details)); |
+ |
+ password_.clear(); // Don't need it anymore. |
+ |
+ profile_->GetTokenService()->UpdateCredentials( |
+ *static_cast<GaiaAuthConsumer::ClientLoginResult*>(last_result_.get())); |
+ DCHECK(profile_->GetTokenService()->AreCredentialsValid()); |
+ profile_->GetTokenService()->StartFetchingTokens(); |
+} |
+ |
+void SigninManagerClientLogin::OnGetUserInfoKeyNotFound( |
+ const std::string& key) { |
+ DCHECK(key == kGetInfoEmailKey); |
+ LOG(ERROR) << "Account is not associated with a valid email address. " |
+ << "Login failed."; |
+ OnClientLoginFailure(GoogleServiceAuthError( |
+ GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); |
+} |
+ |
+void SigninManagerClientLogin::OnGetUserInfoFailure( |
+ const GoogleServiceAuthError& error) { |
+ LOG(ERROR) << "Unable to retreive the canonical email address. Login failed."; |
+ OnClientLoginFailure(error); |
+} |
+ |
+void SigninManagerClientLogin::OnClientLoginFailure( |
+ const GoogleServiceAuthError& error) { |
+ NotificationService::current()->Notify( |
+ NotificationType::GOOGLE_SIGNIN_FAILED, |
+ Source<Profile>(profile_), |
+ Details<const GoogleServiceAuthError>(&error)); |
+ |
+ // We don't sign-out if the password was valid and we're just dealing with |
+ // a second factor error, and we don't sign out if we're dealing with |
+ // an invalid access code (again, because the password was valid). |
+ bool invalid_gaia = error.state() == |
+ GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS; |
+ if (error.state() == GoogleServiceAuthError::TWO_FACTOR || |
+ (had_two_factor_error_ && invalid_gaia)) { |
+ had_two_factor_error_ = true; |
+ return; |
+ } |
+ |
+ SignOut(); |
+} |