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

Unified Diff: chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc

Issue 304303005: ChromeOS login webui refactoring : Move GAIA-related code to gaia_screen_handler (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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/chromeos/login/gaia_screen_handler.cc
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
index 7ac9edf8140ab7d15404166d59c4aaa6aea3d7a9..44ef2d582840349d8ffd02d928218abcc0044aa6 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -5,20 +5,31 @@
#include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
#include "base/logging.h"
+#include "base/metrics/histogram.h"
+#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_shutdown.h"
+#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
#include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
#include "chrome/browser/chromeos/login/users/user_manager.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "chrome/browser/io_thread.h"
#include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/settings/cros_settings_names.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_frame_host.h"
+#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/gaia_switches.h"
#include "google_apis/gaia/gaia_urls.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
+using content::BrowserThread;
+
namespace chromeos {
namespace {
@@ -79,6 +90,20 @@ void UpdateAuthParams(base::DictionaryValue* params, bool has_users) {
}
}
+void RecordSAMLScrapingVerificationResultInHistogram(bool success) {
+ UMA_HISTOGRAM_BOOLEAN("ChromeOS.SAML.Scraping.VerificationResult", success);
+}
+
+// The Task posted to PostTaskAndReply in StartClearingDnsCache on the IO
+// thread.
+void ClearDnsCache(IOThread* io_thread) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (browser_shutdown::IsTryingToQuit())
+ return;
+
+ io_thread->ClearHostCache();
+}
+
} // namespace
GaiaContext::GaiaContext()
@@ -95,11 +120,62 @@ GaiaScreenHandler::GaiaScreenHandler(
frame_state_(FRAME_STATE_UNKNOWN),
frame_error_(net::OK),
network_state_informer_(network_state_informer),
- signin_screen_handler_(NULL) {
+ dns_cleared_(false),
+ dns_clear_task_running_(false),
+ cookies_cleared_(false),
+ focus_stolen_(false),
+ gaia_silent_load_(false),
+ using_saml_api_(false),
+ test_expects_complete_login_(false),
+ signin_screen_handler_(NULL),
+ weak_factory_(this) {
DCHECK(network_state_informer_.get());
}
-GaiaScreenHandler::~GaiaScreenHandler() {}
+GaiaScreenHandler::~GaiaScreenHandler() {
+ weak_factory_.InvalidateWeakPtrs();
+}
+
+void GaiaScreenHandler::DeclareLocalizedValues(
+ LocalizedValuesBuilder* builder) {
+ builder->Add("signinScreenTitle", IDS_SIGNIN_SCREEN_TITLE);
+ builder->Add("signinScreenPasswordChanged",
+ IDS_SIGNIN_SCREEN_PASSWORD_CHANGED);
+ builder->Add("createAccount", IDS_CREATE_ACCOUNT_HTML);
+ builder->Add("guestSignin", IDS_BROWSE_WITHOUT_SIGNING_IN_HTML);
+ builder->Add("createLocallyManagedUser",
+ IDS_CREATE_LOCALLY_MANAGED_USER_HTML);
+ builder->Add("createManagedUserFeatureName",
+ IDS_CREATE_LOCALLY_MANAGED_USER_FEATURE_NAME);
+
+ // Strings used by the fatal error dialog.
Nikita (slow) 2014/06/02 14:18:29 nit: by the SAML fatal error dialog
Denis Kuznetsov (DE-MUC) 2014/06/02 16:47:01 Done.
+ builder->Add("fatalErrorMessageNoEmail", IDS_LOGIN_FATAL_ERROR_NO_EMAIL);
+ builder->Add("fatalErrorMessageNoPassword",
+ IDS_LOGIN_FATAL_ERROR_NO_PASSWORD);
+ builder->Add("fatalErrorMessageVerificationFailed",
+ IDS_LOGIN_FATAL_ERROR_PASSWORD_VERIFICATION);
+ builder->Add("fatalErrorMessageInsecureURL",
+ IDS_LOGIN_FATAL_ERROR_TEXT_INSECURE_URL);
+ builder->Add("fatalErrorInstructions", IDS_LOGIN_FATAL_ERROR_INSTRUCTIONS);
+ builder->Add("fatalErrorDismissButton", IDS_OK);
+}
+
+void GaiaScreenHandler::Initialize() {
+}
+
+void GaiaScreenHandler::RegisterMessages() {
+ AddCallback("frameLoadingCompleted",
+ &GaiaScreenHandler::HandleFrameLoadingCompleted);
+ AddCallback("completeLogin", &GaiaScreenHandler::HandleCompleteLogin);
+ AddCallback("completeAuthentication",
+ &GaiaScreenHandler::HandleCompleteAuthentication);
+ AddCallback("usingSAMLAPI", &GaiaScreenHandler::HandleUsingSAMLAPI);
+ AddCallback("scrapedPasswordCount",
+ &GaiaScreenHandler::HandleScrapedPasswordCount);
+ AddCallback("scrapedPasswordVerificationFailed",
+ &GaiaScreenHandler::HandleScrapedPasswordVerificationFailed);
+ AddCallback("loginWebuiReady", &GaiaScreenHandler::HandleGaiaUIReady);
+}
void GaiaScreenHandler::LoadGaia(const GaiaContext& context) {
LOG(WARNING) << "LoadGaia() call.";
@@ -175,37 +251,6 @@ void GaiaScreenHandler::ReloadGaia() {
CallJS("doReload");
}
-void GaiaScreenHandler::DeclareLocalizedValues(
- LocalizedValuesBuilder* builder) {
- builder->Add("signinScreenTitle", IDS_SIGNIN_SCREEN_TITLE);
- builder->Add("signinScreenPasswordChanged",
- IDS_SIGNIN_SCREEN_PASSWORD_CHANGED);
- builder->Add("createAccount", IDS_CREATE_ACCOUNT_HTML);
- builder->Add("guestSignin", IDS_BROWSE_WITHOUT_SIGNING_IN_HTML);
- builder->Add("createLocallyManagedUser",
- IDS_CREATE_LOCALLY_MANAGED_USER_HTML);
- builder->Add("createManagedUserFeatureName",
- IDS_CREATE_LOCALLY_MANAGED_USER_FEATURE_NAME);
-
- // Strings used by the fatal error dialog.
- builder->Add("fatalErrorMessageNoEmail", IDS_LOGIN_FATAL_ERROR_NO_EMAIL);
- builder->Add("fatalErrorMessageNoPassword",
- IDS_LOGIN_FATAL_ERROR_NO_PASSWORD);
- builder->Add("fatalErrorMessageVerificationFailed",
- IDS_LOGIN_FATAL_ERROR_PASSWORD_VERIFICATION);
- builder->Add("fatalErrorMessageInsecureURL",
- IDS_LOGIN_FATAL_ERROR_TEXT_INSECURE_URL);
- builder->Add("fatalErrorInstructions", IDS_LOGIN_FATAL_ERROR_INSTRUCTIONS);
- builder->Add("fatalErrorDismissButton", IDS_OK);
-}
-
-void GaiaScreenHandler::Initialize() {}
-
-void GaiaScreenHandler::RegisterMessages() {
- AddCallback("frameLoadingCompleted",
- &GaiaScreenHandler::HandleFrameLoadingCompleted);
-}
-
void GaiaScreenHandler::HandleFrameLoadingCompleted(int status) {
const net::Error frame_error = static_cast<net::Error>(-status);
if (frame_error == net::ERR_ABORTED) {
@@ -234,8 +279,282 @@ void GaiaScreenHandler::UpdateState(ErrorScreenActor::ErrorReason reason) {
signin_screen_handler_->UpdateState(reason);
}
+void GaiaScreenHandler::HandleCompleteLogin(const std::string& typed_email,
+ const std::string& password,
+ bool using_saml) {
+ if (using_saml && !using_saml_api_)
+ RecordSAMLScrapingVerificationResultInHistogram(true);
+
+ const std::string sanitized_email = gaia::SanitizeEmail(typed_email);
+ Delegate()->SetDisplayEmail(sanitized_email);
+ UserContext user_context(sanitized_email);
+ user_context.SetKey(Key(password));
+ user_context.SetAuthFlow(using_saml
+ ? UserContext::AUTH_FLOW_GAIA_WITH_SAML
+ : UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML);
+ Delegate()->CompleteLogin(user_context);
+
+ if (test_expects_complete_login_) {
+ VLOG(2) << "Complete test login for " << typed_email
+ << ", requested=" << test_user_;
+
+ test_expects_complete_login_ = false;
+ test_user_.clear();
+ test_pass_.clear();
+ }
+}
+
+void GaiaScreenHandler::HandleCompleteAuthentication(
+ const std::string& email,
+ const std::string& password,
+ const std::string& auth_code) {
+ Delegate()->SetDisplayEmail(gaia::SanitizeEmail(email));
Nikita (slow) 2014/06/02 14:18:29 As discussed, let's continue checking for Delegate
Denis Kuznetsov (DE-MUC) 2014/06/02 16:47:01 Done.
+ UserContext user_context(email);
+ user_context.SetKey(Key(password));
+ user_context.SetAuthCode(auth_code);
+ Delegate()->CompleteLogin(user_context);
+}
+
+void GaiaScreenHandler::ShowSigninScreenForCreds(const std::string& username,
+ const std::string& password) {
+ VLOG(2) << "ShowSigninScreenForCreds for user " << username
+ << ", frame_state=" << FrameState();
+
+ test_user_ = username;
+ test_pass_ = password;
+ test_expects_complete_login_ = true;
+
+ // Submit login form for test if gaia is ready. If gaia is loading, login
+ // will be attempted in HandleLoginWebuiReady after gaia is ready. Otherwise,
+ // reload gaia then follow the loading case.
+ if (FrameState() == GaiaScreenHandler::FRAME_STATE_LOADED)
+ SubmitLoginFormForTest();
+ else if (FrameState() != GaiaScreenHandler::FRAME_STATE_LOADING) {
+ DCHECK(signin_screen_handler_);
+ signin_screen_handler_->OnShowAddUser();
Nikita (slow) 2014/06/02 14:18:29 Can you call ShowGaia() directly here or this is d
Denis Kuznetsov (DE-MUC) 2014/06/02 16:47:01 Done.
+ }
+}
+
+void GaiaScreenHandler::SubmitLoginFormForTest() {
+ VLOG(2) << "Submit login form for test, user=" << test_user_;
+
+ std::string code;
+ code += "document.getElementById('Email').value = '" + test_user_ + "';";
+ code += "document.getElementById('Passwd').value = '" + test_pass_ + "';";
+ code += "document.getElementById('signIn').click();";
+
+ content::RenderFrameHost* frame =
+ LoginDisplayHostImpl::GetGaiaAuthIframe(web_ui()->GetWebContents());
+ frame->ExecuteJavaScript(base::ASCIIToUTF16(code));
+
+ // Test properties are cleared in HandleCompleteLogin because the form
+ // submission might fail and login will not be attempted after reloading
+ // if they are cleared here.
+}
+
+void GaiaScreenHandler::SetSAMLPrincipalsAPIUsed(bool api_used) {
+ using_saml_api_ = api_used;
+ UMA_HISTOGRAM_BOOLEAN("ChromeOS.SAML.APIUsed", api_used);
+}
+
+void GaiaScreenHandler::HandleUsingSAMLAPI() {
+ SetSAMLPrincipalsAPIUsed(true);
+}
+
+void GaiaScreenHandler::HandleScrapedPasswordCount(int password_count) {
+ SetSAMLPrincipalsAPIUsed(false);
+ // Use a histogram that has 11 buckets, one for each of the values in [0, 9]
+ // and an overflow bucket at the end.
+ UMA_HISTOGRAM_ENUMERATION(
+ "ChromeOS.SAML.Scraping.PasswordCount", std::min(password_count, 10), 11);
+ if (password_count == 0)
+ HandleScrapedPasswordVerificationFailed();
+}
+
+void GaiaScreenHandler::HandleScrapedPasswordVerificationFailed() {
+ RecordSAMLScrapingVerificationResultInHistogram(false);
+}
+
+void GaiaScreenHandler::ShowGaiaScreenIfReady() {
+ LOG(WARNING) << "ShowSigninScreenIfReady() call.";
Nikita (slow) 2014/06/02 14:18:29 nit: ShowGaiaScreenIfReady
Denis Kuznetsov (DE-MUC) 2014/06/02 16:47:01 Done.
+
+ if (!dns_cleared_ || !cookies_cleared_ || !Delegate())
+ return;
+
+ std::string active_network_path = network_state_informer_->network_path();
+ if (gaia_silent_load_ &&
+ (network_state_informer_->state() != NetworkStateInformer::ONLINE ||
+ gaia_silent_load_network_ != active_network_path)) {
+ // Network has changed. Force Gaia reload.
+ gaia_silent_load_ = false;
+ // Gaia page will be realoded, so focus isn't stolen anymore.
+ focus_stolen_ = false;
+ }
+
+ // Note that LoadAuthExtension clears |populated_email_|.
+ if (populated_email_.empty())
+ Delegate()->LoadSigninWallpaper();
+ else
+ Delegate()->LoadWallpaper(populated_email_);
+
+ // Set Least Recently Used input method for the user.
+ if (!populated_email_.empty())
+ signin_screen_handler_->SetUserInputMethod(populated_email_);
+
+ LoadAuthExtension(!gaia_silent_load_, false, false);
+ signin_screen_handler_->UpdateUIState(
+ SigninScreenHandler::UI_STATE_GAIA_SIGNIN, NULL);
+
+ if (gaia_silent_load_) {
+ // The variable is assigned to false because silently loaded Gaia page was
+ // used.
+ gaia_silent_load_ = false;
+ if (focus_stolen_)
+ HandleGaiaUIReady();
+ }
+
+ signin_screen_handler_->UpdateState(ErrorScreenActor::ERROR_REASON_UPDATE);
+}
+
+void GaiaScreenHandler::HandleGaiaUIReady() {
+ if (focus_stolen_) {
+ // Set focus to the Gaia page.
+ // TODO(altimofeev): temporary solution, until focus parameters are
+ // implemented on the Gaia side.
+ // Do this only once. Any subsequent call would relod GAIA frame.
+ focus_stolen_ = false;
+ const char code[] =
+ "if (typeof gWindowOnLoad != 'undefined') gWindowOnLoad();";
+ content::RenderFrameHost* frame =
+ LoginDisplayHostImpl::GetGaiaAuthIframe(web_ui()->GetWebContents());
+ frame->ExecuteJavaScript(base::ASCIIToUTF16(code));
+ }
+ if (gaia_silent_load_) {
+ focus_stolen_ = true;
+ // Prevent focus stealing by the Gaia page.
+ // TODO(altimofeev): temporary solution, until focus parameters are
+ // implemented on the Gaia side.
+ const char code[] =
+ "var gWindowOnLoad = window.onload; "
+ "window.onload=function() {};";
+ content::RenderFrameHost* frame =
+ LoginDisplayHostImpl::GetGaiaAuthIframe(web_ui()->GetWebContents());
+ frame->ExecuteJavaScript(base::ASCIIToUTF16(code));
+
+ // As we could miss and window.onload could already be called, restore
+ // focus to current pod (see crbug/175243).
+ DCHECK(signin_screen_handler_);
+ signin_screen_handler_->RefocusCurrentPod();
+ }
+ HandleFrameLoadingCompleted(0);
+
+ if (test_expects_complete_login_)
+ SubmitLoginFormForTest();
+}
+
+void GaiaScreenHandler::ShowGaia() {
+ if (gaia_silent_load_ && populated_email_.empty()) {
+ dns_cleared_ = true;
+ cookies_cleared_ = true;
+ ShowGaiaScreenIfReady();
+ } else {
+ StartClearingDnsCache();
+ StartClearingCookies(base::Bind(&GaiaScreenHandler::ShowGaiaScreenIfReady,
+ weak_factory_.GetWeakPtr()));
+ }
+}
+
+void GaiaScreenHandler::MaybePreloadAuthExtension() {
+ LOG(WARNING) << "MaybePreloadAuthExtension() call.";
+
+ // Fetching of the extension is not started before account picker page is
Nikita (slow) 2014/06/02 14:18:29 nit: Move first comment sentence to SigninScreenHa
Denis Kuznetsov (DE-MUC) 2014/06/02 16:47:01 Done.
+ // loaded because it can affect the loading speed. Also if cookies clearing
+ // was initiated or |dns_clear_task_running_| then auth extension showing has
+ // already been initiated and preloading is senseless.
+ // Do not load the extension for the screen locker, see crosbug.com/25018.
Nikita (slow) 2014/06/02 14:18:29 nit: Move screen locker comment to SigninScreenHa
Denis Kuznetsov (DE-MUC) 2014/06/02 16:47:01 Done.
+ if (signin_screen_handler_->ShouldLoadGaia() && !gaia_silent_load_ &&
Nikita (slow) 2014/06/02 14:18:29 nit: Can you please re-format this to have one con
Denis Kuznetsov (DE-MUC) 2014/06/02 16:47:01 Done.
Nikita (slow) 2014/06/02 16:49:34 I don't see changes in this condition. Please chan
+ !cookies_cleared_ && !dns_clear_task_running_ &&
+ network_state_informer_->state() == NetworkStateInformer::ONLINE) {
+ gaia_silent_load_ = true;
+ gaia_silent_load_network_ = network_state_informer_->network_path();
+ LoadAuthExtension(true, true, false);
+ }
+}
+
+void GaiaScreenHandler::LoadAuthExtension(bool force,
+ bool silent_load,
+ bool offline) {
+ GaiaContext context;
+ context.force_reload = force;
+ context.is_local = offline;
+ context.password_changed = !populated_email_.empty() &&
+ password_changed_for_.count(populated_email_);
+ context.use_offline = offline;
+ context.email = populated_email_;
+ if (Delegate()) {
+ context.show_users = Delegate()->IsShowUsers();
+ context.has_users = !Delegate()->GetUsers().empty();
+ }
+
+ populated_email_.clear();
+
+ LoadGaia(context);
+}
+
+void GaiaScreenHandler::StartClearingDnsCache() {
+ if (dns_clear_task_running_ || !g_browser_process->io_thread())
+ return;
+
+ dns_cleared_ = false;
+ BrowserThread::PostTaskAndReply(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&ClearDnsCache, g_browser_process->io_thread()),
+ base::Bind(&GaiaScreenHandler::OnDnsCleared, weak_factory_.GetWeakPtr()));
+ dns_clear_task_running_ = true;
+}
+
+void GaiaScreenHandler::OnDnsCleared() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ dns_clear_task_running_ = false;
+ dns_cleared_ = true;
+ ShowGaiaScreenIfReady();
+}
+
+void GaiaScreenHandler::StartClearingCookies(
+ const base::Closure& on_clear_callback) {
+ cookies_cleared_ = false;
+ ProfileHelper* profile_helper =
+ g_browser_process->platform_part()->profile_helper();
+ LOG_ASSERT(Profile::FromWebUI(web_ui()) ==
+ profile_helper->GetSigninProfile());
+ profile_helper->ClearSigninProfile(
+ base::Bind(&GaiaScreenHandler::OnCookiesCleared,
+ weak_factory_.GetWeakPtr(),
+ on_clear_callback));
+}
+
+void GaiaScreenHandler::OnCookiesCleared(base::Closure on_clear_callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ cookies_cleared_ = true;
+ on_clear_callback.Run();
+}
+
+void GaiaScreenHandler::PopulateEmail(const std::string& user_id) {
+ populated_email_ = user_id;
+}
+
+void GaiaScreenHandler::PasswordChangedFor(const std::string& user_id) {
+ password_changed_for_.insert(user_id);
+}
+
+SigninScreenHandlerDelegate* GaiaScreenHandler::Delegate() {
+ DCHECK(signin_screen_handler_);
+ DCHECK(signin_screen_handler_->delegate_);
+ return signin_screen_handler_->delegate_;
+}
+
void GaiaScreenHandler::SetSigninScreenHandler(SigninScreenHandler* handler) {
signin_screen_handler_ = handler;
}
-
} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698