Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(393)

Unified Diff: chrome/browser/ui/webui/sync_setup_handler.cc

Issue 9295044: Start moving signin code out of browser/sync. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed unit test Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/webui/sync_setup_handler.cc
diff --git a/chrome/browser/ui/webui/sync_setup_handler.cc b/chrome/browser/ui/webui/sync_setup_handler.cc
index 3dfebf94cda9c03dc4d4ce77ec1419ae7d36872c..748b2a372ad9ce51fa67adfdf5d371718e25d964 100644
--- a/chrome/browser/ui/webui/sync_setup_handler.cc
+++ b/chrome/browser/ui/webui/sync_setup_handler.cc
@@ -16,12 +16,15 @@
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_metrics.h"
#include "chrome/browser/signin/signin_manager.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/sync/protocol/service_constants.h"
#include "chrome/browser/sync/sync_setup_flow.h"
#include "chrome/browser/sync/util/oauth.h"
#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/webui/signin/login_ui_service.h"
+#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
#include "chrome/browser/ui/webui/sync_promo/sync_promo_ui.h"
#include "chrome/common/net/gaia/gaia_constants.h"
#include "chrome/common/url_constants.h"
@@ -182,9 +185,12 @@ SyncSetupHandler::SyncSetupHandler(ProfileManager* profile_manager)
}
SyncSetupHandler::~SyncSetupHandler() {
+ // Just exit if running unit tests (no actual WebUI is attached).
+ if (!web_ui())
+ return;
+
// This case is hit when the user performs a back navigation.
- if (flow_)
- flow_->OnDialogClosed("");
+ CloseSyncSetup();
}
void SyncSetupHandler::GetLocalizedValues(DictionaryValue* localized_strings) {
@@ -350,15 +356,44 @@ void SyncSetupHandler::GetStaticLocalizedValues(
}
void SyncSetupHandler::Initialize() {
+ OptionsPageUIHandler::Initialize();
James Hawkins 2012/02/10 23:08:01 What is this part of the change about?
Andrew T Wilson (Slow) 2012/02/11 01:50:45 Ah, I was originally registering for some notifica
+}
+
+void SyncSetupHandler::StartConfigureSync() {
+ DCHECK(!flow_);
+ // We only get here if we're signed in, so no longer need our SigninTracker.
+ signin_tracker_.reset();
+ ProfileSyncService* service = GetSyncService();
+ service->get_wizard().Step(
+ service->HasSyncSetupCompleted() ?
+ SyncSetupWizard::CONFIGURE : SyncSetupWizard::SYNC_EVERYTHING);
+
+ // Attach this as the sync setup handler.
+ if (!service->get_wizard().AttachSyncSetupHandler(this)) {
+ LOG(ERROR) << "SyncSetupHandler attach failed!";
+ CloseOverlay();
+ }
+}
+
+bool SyncSetupHandler::IsActiveLogin() const {
+ LoginUIService* service = GetLoginUIService();
+ return service->current_login_ui() == web_ui();
}
void SyncSetupHandler::OnGetOAuthTokenSuccess(const std::string& oauth_token) {
- flow_->OnUserSubmittedOAuth(oauth_token);
+ Profile* profile = Profile::FromWebUI(web_ui());
+ SigninManager* signin = GetSignin();
+ GaiaOAuthFetcher* fetcher = new GaiaOAuthFetcher(
+ signin,
+ profile->GetRequestContext(),
+ profile,
+ GaiaConstants::kSyncServiceOAuth);
+ signin->StartOAuthSignIn(oauth_token, fetcher);
}
void SyncSetupHandler::OnGetOAuthTokenFailure(
const GoogleServiceAuthError& error) {
- CloseSyncSetup();
+ CloseOverlay();
}
void SyncSetupHandler::RegisterMessages() {
@@ -388,37 +423,80 @@ void SyncSetupHandler::RegisterMessages() {
base::Unretained(this)));
}
-// Ideal(?) solution here would be to mimic the ClientLogin overlay. Since
-// this UI must render an external URL, that overlay cannot be used directly.
-// The current implementation is functional, but fails asthetically.
-// TODO(rickcam): Bug 90711: Update UI for OAuth sign-in flow
-void SyncSetupHandler::ShowOAuthLogin() {
- DCHECK(browser_sync::IsUsingOAuth());
-
+SigninManager* SyncSetupHandler::GetSignin() const {
Profile* profile = Profile::FromWebUI(web_ui());
- oauth_login_.reset(new GaiaOAuthFetcher(this,
- profile->GetRequestContext(),
- profile,
- GaiaConstants::kSyncServiceOAuth));
- oauth_login_->SetAutoFetchLimit(GaiaOAuthFetcher::OAUTH1_REQUEST_TOKEN);
- oauth_login_->StartGetOAuthToken();
+ return SigninManagerFactory::GetForProfile(profile);
}
-void SyncSetupHandler::ShowGaiaLogin(const DictionaryValue& args) {
+void SyncSetupHandler::DisplayGaiaLogin(bool fatal_error) {
+ DisplayGaiaLoginWithErrorMessage(string16(), fatal_error);
+}
+
+void SyncSetupHandler::DisplayGaiaLoginWithErrorMessage(
+ const string16& error_message, bool fatal_error) {
DCHECK(!browser_sync::IsUsingOAuth());
+ // If we're exiting from sync config (due to some kind of error), notify
+ // SyncSetupFlow.
+ if (flow_) {
+ flow_->OnDialogClosed(std::string());
+ flow_ = NULL;
+ }
+
+ // Setup args for the GAIA login screen:
+ // error_message: custom error message to display
+ // error: GoogleServiceAuthError from previous login attempt (0 if none)
+ // user: The email the user most recently entered.
+ // editable_user: Whether the username field should be editable.
+ SigninManager* signin = GetSignin();
+ std::string user;
+ int error;
+ bool editable_user;
+ if (!last_attempted_user_email_.empty()) {
+ // This is a repeat of a login attempt.
+ user = last_attempted_user_email_;
+ error = signin->GetLoginAuthError().state();
+ editable_user = true;
+ } else {
+ // Fresh login attempt - lock in the authenticated username if there is
+ // one (don't let the user change it).
+ user = signin->GetAuthenticatedUsername();
+ error = 0;
+ editable_user = user.empty();
+ }
+ DictionaryValue args;
+ args.SetString("user", user);
+ args.SetInteger("error", error);
+ args.SetBoolean("editable_user", editable_user);
+ if (!error_message.empty())
+ args.SetString("error_message", error_message);
+ if (fatal_error)
+ args.SetBoolean("fatalError", true);
StringValue page("login");
web_ui()->CallJavascriptFunction(
"SyncSetupOverlay.showSyncSetupPage", page, args);
}
-void SyncSetupHandler::ShowGaiaSuccessAndClose() {
+void SyncSetupHandler::RecordSignin() {
+ // By default, do nothing - subclasses can override.
+}
+
+void SyncSetupHandler::DisplayGaiaSuccessAndClose() {
+ // TODO(atwilson): Can we remove this now that we've changed the signin flow?
+ RecordSignin();
web_ui()->CallJavascriptFunction("SyncSetupOverlay.showSuccessAndClose");
}
-void SyncSetupHandler::ShowGaiaSuccessAndSettingUp() {
+void SyncSetupHandler::DisplayGaiaSuccessAndSettingUp() {
+ RecordSignin();
web_ui()->CallJavascriptFunction("SyncSetupOverlay.showSuccessAndSettingUp");
}
+void SyncSetupHandler::ShowFatalError() {
+ // For now, just send the user back to the login page. Ultimately we may want
+ // to give different feedback (especially for chromeos).
+ DisplayGaiaLogin(true);
+}
+
void SyncSetupHandler::ShowConfigure(const DictionaryValue& args) {
StringValue page("configure");
web_ui()->CallJavascriptFunction(
@@ -447,9 +525,7 @@ void SyncSetupHandler::ShowSetupDone(const string16& user) {
SyncPromoUI::SetUserSkippedSyncPromo(Profile::FromWebUI(web_ui()));
Profile* profile = Profile::FromWebUI(web_ui());
- ProfileSyncService* service =
- ProfileSyncServiceFactory::GetInstance()->GetForProfile(
- profile);
+ ProfileSyncService* service = GetSyncService();
if (!service->HasSyncSetupCompleted()) {
FilePath profile_file_path = profile->GetPath();
ProfileMetrics::LogProfileSyncSignIn(profile_file_path);
@@ -488,12 +564,58 @@ void SyncSetupHandler::HandleSubmitAuth(const ListValue* args) {
string16 error_message;
if (!IsLoginAuthDataValid(username, &error_message)) {
- ShowLoginErrorMessage(error_message);
+ DisplayGaiaLoginWithErrorMessage(error_message, false);
return;
}
- if (flow_)
- flow_->OnUserSubmittedAuth(username, password, captcha, access_code);
+ TryLogin(username, password, captcha, access_code);
+}
+
+void SyncSetupHandler::TryLogin(const std::string& username,
+ const std::string& password,
+ const std::string& captcha,
+ const std::string& access_code) {
+ DCHECK(IsActiveLogin());
+ // Make sure we are listening for signin traffic.
+ if (!signin_tracker_.get())
+ signin_tracker_.reset(new SigninTracker(Profile::FromWebUI(web_ui()),
+ this));
+
+ last_attempted_user_email_ = username;
+ // If we're just being called to provide an ASP, then pass it to the
+ // SigninManager and wait for the next step.
+ SigninManager* signin = GetSignin();
+ if (!access_code.empty()) {
+ signin->ProvideSecondFactorAccessCode(access_code);
+ return;
+ }
+
+ // Kick off a sign-in through the signin manager.
+ signin->StartSignIn(username,
+ password,
+ signin->GetLoginAuthError().captcha().token,
+ captcha);
+}
+
+void SyncSetupHandler::GaiaCredentialsValid() {
+ DCHECK(IsActiveLogin());
+ // Gaia credentials are valid - update the UI.
+ DisplayGaiaSuccessAndSettingUp();
+}
+
+void SyncSetupHandler::SigninFailed() {
+ // Got a failed signin - this is either just a typical auth error, or a
+ // sync error (treat sync errors as "fatal errors" - i.e. non-auth errors).
+ DisplayGaiaLogin(GetSyncService()->unrecoverable_error_detected());
+}
+
+ProfileSyncService* SyncSetupHandler::GetSyncService() const {
+ return ProfileSyncServiceFactory::GetForProfile(Profile::FromWebUI(web_ui()));
+}
+
+void SyncSetupHandler::SigninSuccess() {
+ DCHECK(GetSyncService()->sync_initialized());
+ StartConfigureSync();
}
void SyncSetupHandler::HandleConfigure(const ListValue* args) {
@@ -563,9 +685,7 @@ void SyncSetupHandler::HandleAttachHandler(const ListValue* args) {
void SyncSetupHandler::HandleShowErrorUI(const ListValue* args) {
DCHECK(!flow_);
- Profile* profile = Profile::FromWebUI(web_ui());
- ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()->
- GetForProfile(profile);
+ ProfileSyncService* service = GetSyncService();
DCHECK(service);
service->ShowErrorUI();
@@ -573,52 +693,54 @@ void SyncSetupHandler::HandleShowErrorUI(const ListValue* args) {
void SyncSetupHandler::HandleShowSetupUI(const ListValue* args) {
DCHECK(!flow_);
- if (FocusExistingWizard()) {
- CloseOverlay();
- return;
- }
-
- StepWizardForShowSetupUI();
- ShowSetupUI();
+ OpenSyncSetup();
}
void SyncSetupHandler::CloseSyncSetup() {
+ // TODO(atwilson): Move UMA tracking of signin events out of sync module.
+ if (IsActiveLogin()) {
+ if (signin_tracker_.get()) {
+ ProfileSyncService::SyncEvent(
+ ProfileSyncService::CANCEL_DURING_SIGNON);
+ } else if (!flow_) {
+ ProfileSyncService::SyncEvent(
+ ProfileSyncService::CANCEL_FROM_SIGNON_WITHOUT_AUTH);
+ }
+ }
+
if (flow_) {
flow_->OnDialogClosed(std::string());
flow_ = NULL;
}
+ signin_tracker_.reset();
+ GetLoginUIService()->ClearLoginUI(web_ui());
}
void SyncSetupHandler::OpenSyncSetup() {
- DCHECK(!flow_);
-
- Profile* profile = Profile::FromWebUI(web_ui());
- ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()->
- GetForProfile(profile);
+ ProfileSyncService* service = GetSyncService();
if (!service) {
// If there's no sync service, the user tried to manually invoke a syncSetup
// URL, but sync features are disabled. We need to close the overlay for
// this (rare) case.
+ DLOG(WARNING) << "Closing sync UI because sync is disabled";
CloseOverlay();
return;
}
- // If the wizard is already visible, it must be attached to another flow
- // handler.
+ // If the wizard is already visible, just focus that one.
if (FocusExistingWizard()) {
- CloseOverlay();
+ if (!IsActiveLogin())
+ CloseOverlay();
return;
}
- // The wizard must be stepped before attaching. Allow subclasses to step the
- // wizard to appropriate state.
- StepWizardForShowSetupUI();
+ GetLoginUIService()->SetLoginUI(web_ui());
- // Attach this as the sync setup handler, before calling ShowSetupUI().
- if (!service->get_wizard().AttachSyncSetupHandler(this)) {
- LOG(ERROR) << "SyncSetupHandler attach failed!";
- CloseOverlay();
- return;
+ if (!SigninTracker::AreServicesSignedIn(Profile::FromWebUI(web_ui()))) {
+ // User is not logged in - need to display login UI.
+ DisplayGaiaLogin(false);
+ } else {
+ StartConfigureSync();
}
ShowSetupUI();
@@ -626,22 +748,40 @@ void SyncSetupHandler::OpenSyncSetup() {
// Private member functions.
-bool SyncSetupHandler::FocusExistingWizard() {
+bool SyncSetupHandler::IsUserLoggedIn() const {
Profile* profile = Profile::FromWebUI(web_ui());
- ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()->
- GetForProfile(profile);
- if (!service)
+ std::string user = GetSignin()->GetAuthenticatedUsername();
+ if (user.empty())
return false;
- // If the wizard is already visible, focus it.
- if (service->get_wizard().IsVisible()) {
- service->get_wizard().Focus();
- return true;
- }
- return false;
+ // Now, make sure the services all have proper auth tokens.
+ // TODO(atwilson): Remove this dependency on the ProfileSyncService here.
+ // Ultimately, we'd like individual services like sync to report their auth
+ // errors via the TokenService, so we can query the TokenService to check for
+ // invalid credentials instead of asking the services themselves.
+ ProfileSyncService* service =
+ ProfileSyncServiceFactory::GetForProfile(profile);
+ // We're signed in if we have a token and our last attempt to access the
+ // server succeeded.
+ return !service->waiting_for_auth() &&
+ service->AreCredentialsAvailable() &&
+ service->GetAuthError().state() == GoogleServiceAuthError::NONE;
+}
+
+bool SyncSetupHandler::FocusExistingWizard() {
+ LoginUIService* service = GetLoginUIService();
+ if (!service->current_login_ui())
+ return false;
+ service->FocusLoginUI();
+ return true;
+}
+
+LoginUIService* SyncSetupHandler::GetLoginUIService() const {
+ return LoginUIServiceFactory::GetForProfile(Profile::FromWebUI(web_ui()));
}
void SyncSetupHandler::CloseOverlay() {
+ CloseSyncSetup();
web_ui()->CallJavascriptFunction("OptionsPage.closeOverlay");
}
@@ -671,11 +811,3 @@ bool SyncSetupHandler::IsLoginAuthDataValid(const std::string& username,
return true;
}
-
-void SyncSetupHandler::ShowLoginErrorMessage(const string16& error_message) {
- DCHECK(flow_);
- DictionaryValue args;
- flow_->GetArgsForGaiaLogin(&args);
- args.SetString("error_message", error_message);
- ShowGaiaLogin(args);
-}

Powered by Google App Engine
This is Rietveld 408576698