| Index: chrome/browser/chromeos/login/saml_browsertest.cc
|
| diff --git a/chrome/browser/chromeos/login/saml_browsertest.cc b/chrome/browser/chromeos/login/saml_browsertest.cc
|
| deleted file mode 100644
|
| index ae049bd29ff402192925606bc928a46eb101df6e..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/chromeos/login/saml_browsertest.cc
|
| +++ /dev/null
|
| @@ -1,489 +0,0 @@
|
| -// Copyright 2013 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 "base/command_line.h"
|
| -#include "base/file_util.h"
|
| -#include "base/files/file_path.h"
|
| -#include "base/path_service.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "chrome/browser/chrome_notification_types.h"
|
| -#include "chrome/browser/chromeos/login/existing_user_controller.h"
|
| -#include "chrome/browser/chromeos/login/login_display_host_impl.h"
|
| -#include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
|
| -#include "chrome/browser/chromeos/login/user.h"
|
| -#include "chrome/browser/chromeos/login/user_manager.h"
|
| -#include "chrome/browser/chromeos/login/webui_login_display.h"
|
| -#include "chrome/browser/chromeos/login/wizard_controller.h"
|
| -#include "chrome/browser/lifetime/application_lifetime.h"
|
| -#include "chrome/common/chrome_paths.h"
|
| -#include "chrome/common/chrome_switches.h"
|
| -#include "chrome/test/base/in_process_browser_test.h"
|
| -#include "chromeos/chromeos_switches.h"
|
| -#include "content/public/browser/render_view_host.h"
|
| -#include "content/public/browser/web_contents.h"
|
| -#include "content/public/test/browser_test_utils.h"
|
| -#include "content/public/test/test_utils.h"
|
| -#include "google_apis/gaia/fake_gaia.h"
|
| -#include "google_apis/gaia/gaia_switches.h"
|
| -#include "net/base/url_util.h"
|
| -#include "net/dns/mock_host_resolver.h"
|
| -#include "net/test/embedded_test_server/embedded_test_server.h"
|
| -#include "net/test/embedded_test_server/http_request.h"
|
| -#include "net/test/embedded_test_server/http_response.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -
|
| -using net::test_server::BasicHttpResponse;
|
| -using net::test_server::HttpRequest;
|
| -using net::test_server::HttpResponse;
|
| -
|
| -namespace chromeos {
|
| -
|
| -namespace {
|
| -
|
| -const char kTestAuthSIDCookie[] = "fake-auth-SID-cookie";
|
| -const char kTestAuthLSIDCookie[] = "fake-auth-LSID-cookie";
|
| -const char kTestAuthCode[] = "fake-auth-code";
|
| -const char kTestGaiaUberToken[] = "fake-uber-token";
|
| -const char kTestAuthLoginAccessToken[] = "fake-access-token";
|
| -const char kTestRefreshToken[] = "fake-refresh-token";
|
| -const char kTestSessionSIDCookie[] = "fake-session-SID-cookie";
|
| -const char kTestSessionLSIDCookie[] = "fake-session-LSID-cookie";
|
| -
|
| -const char kAnotherUserEmail[] = "alice@example.com";
|
| -const char kUserEmail[] = "bob@example.com";
|
| -
|
| -const char kRelayState[] = "RelayState";
|
| -
|
| -// FakeSamlIdp serves IdP auth form and the form submission. The form is
|
| -// served with the template's RelayState placeholder expanded to the real
|
| -// RelayState parameter from request. The form submission redirects back to
|
| -// FakeGaia with the same RelayState.
|
| -class FakeSamlIdp {
|
| - public:
|
| - FakeSamlIdp();
|
| - ~FakeSamlIdp();
|
| -
|
| - void SetUp(const std::string& base_path, const GURL& gaia_url);
|
| -
|
| - void SetLoginHTMLTemplate(const std::string& template_file);
|
| - void SetLoginAuthHTMLTemplate(const std::string& template_file);
|
| -
|
| - scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request);
|
| -
|
| - private:
|
| - scoped_ptr<HttpResponse> BuildHTMLResponse(const std::string& html_template,
|
| - const std::string& relay_state,
|
| - const std::string& next_path);
|
| -
|
| - base::FilePath html_template_dir_;
|
| -
|
| - std::string login_path_;
|
| - std::string login_auth_path_;
|
| -
|
| - std::string login_html_template_;
|
| - std::string login_auth_html_template_;
|
| - GURL gaia_assertion_url_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(FakeSamlIdp);
|
| -};
|
| -
|
| -FakeSamlIdp::FakeSamlIdp() {
|
| -}
|
| -
|
| -FakeSamlIdp::~FakeSamlIdp() {
|
| -}
|
| -
|
| -void FakeSamlIdp::SetUp(const std::string& base_path, const GURL& gaia_url) {
|
| - base::FilePath test_data_dir;
|
| - ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
|
| - html_template_dir_ = test_data_dir.Append("login");
|
| -
|
| - login_path_= base_path;
|
| - login_auth_path_ = base_path + "Auth";
|
| - gaia_assertion_url_ = gaia_url.Resolve("/SSO");
|
| -}
|
| -
|
| -void FakeSamlIdp::SetLoginHTMLTemplate(const std::string& template_file) {
|
| - EXPECT_TRUE(base::ReadFileToString(
|
| - html_template_dir_.Append(template_file),
|
| - &login_html_template_));
|
| -}
|
| -
|
| -void FakeSamlIdp::SetLoginAuthHTMLTemplate(const std::string& template_file) {
|
| - EXPECT_TRUE(base::ReadFileToString(
|
| - html_template_dir_.Append(template_file),
|
| - &login_auth_html_template_));
|
| -}
|
| -
|
| -scoped_ptr<HttpResponse> FakeSamlIdp::HandleRequest(
|
| - const HttpRequest& request) {
|
| - // The scheme and host of the URL is actually not important but required to
|
| - // get a valid GURL in order to parse |request.relative_url|.
|
| - GURL request_url = GURL("http://localhost").Resolve(request.relative_url);
|
| - std::string request_path = request_url.path();
|
| -
|
| - if (request_path == login_path_) {
|
| - std::string relay_state;
|
| - net::GetValueForKeyInQuery(request_url, kRelayState, &relay_state);
|
| - return BuildHTMLResponse(login_html_template_,
|
| - relay_state,
|
| - login_auth_path_);
|
| - }
|
| -
|
| - if (request_path != login_auth_path_) {
|
| - // Request not understood.
|
| - return scoped_ptr<HttpResponse>();
|
| - }
|
| -
|
| - std::string relay_state;
|
| - FakeGaia::GetQueryParameter(request.content, kRelayState, &relay_state);
|
| - GURL redirect_url = gaia_assertion_url_;
|
| -
|
| - if (!login_auth_html_template_.empty()) {
|
| - return BuildHTMLResponse(login_auth_html_template_,
|
| - relay_state,
|
| - redirect_url.spec());
|
| - }
|
| -
|
| - redirect_url = net::AppendQueryParameter(
|
| - redirect_url, "SAMLResponse", "fake_response");
|
| - redirect_url = net::AppendQueryParameter(
|
| - redirect_url, kRelayState, relay_state);
|
| -
|
| - scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse());
|
| - http_response->set_code(net::HTTP_TEMPORARY_REDIRECT);
|
| - http_response->AddCustomHeader("Location", redirect_url.spec());
|
| - return http_response.PassAs<HttpResponse>();
|
| -}
|
| -
|
| -scoped_ptr<HttpResponse> FakeSamlIdp::BuildHTMLResponse(
|
| - const std::string& html_template,
|
| - const std::string& relay_state,
|
| - const std::string& next_path) {
|
| - std::string response_html = html_template;
|
| - ReplaceSubstringsAfterOffset(&response_html, 0, "$RelayState", relay_state);
|
| - ReplaceSubstringsAfterOffset(&response_html, 0, "$Post", next_path);
|
| -
|
| - scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse());
|
| - http_response->set_code(net::HTTP_OK);
|
| - http_response->set_content(response_html);
|
| - http_response->set_content_type("text/html");
|
| -
|
| - return http_response.PassAs<HttpResponse>();
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -class SamlTest : public InProcessBrowserTest {
|
| - public:
|
| - SamlTest() : saml_load_injected_(false) {}
|
| - virtual ~SamlTest() {}
|
| -
|
| - virtual void SetUp() OVERRIDE {
|
| - // Start embedded test server here so that we can get server base url
|
| - // and override Gaia urls in SetupCommandLine.
|
| - ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
|
| -
|
| - // Stop IO thread here because no threads are allowed while
|
| - // spawning sandbox host process. See crbug.com/322732.
|
| - embedded_test_server()->StopThread();
|
| -
|
| - InProcessBrowserTest::SetUp();
|
| - }
|
| -
|
| - virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
|
| - host_resolver()->AddRule("*", "127.0.0.1");
|
| - }
|
| -
|
| - virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
|
| - command_line->AppendSwitch(switches::kLoginManager);
|
| - command_line->AppendSwitch(switches::kForceLoginManagerInTests);
|
| - command_line->AppendSwitch(::switches::kDisableBackgroundNetworking);
|
| - command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
|
| -
|
| - const GURL& server_url = embedded_test_server()->base_url();
|
| -
|
| - std::string gaia_host("gaia");
|
| - GURL::Replacements replace_gaia_host;
|
| - replace_gaia_host.SetHostStr(gaia_host);
|
| - gaia_url_ = server_url.ReplaceComponents(replace_gaia_host);
|
| -
|
| - command_line->AppendSwitchASCII(::switches::kGaiaUrl, gaia_url_.spec());
|
| - command_line->AppendSwitchASCII(::switches::kLsoUrl, gaia_url_.spec());
|
| - command_line->AppendSwitchASCII(::switches::kGoogleApisUrl,
|
| - gaia_url_.spec());
|
| - fake_gaia_.Initialize();
|
| -
|
| - std::string saml_idp_host("saml.idp");
|
| - GURL::Replacements replace_saml_idp_host;
|
| - replace_saml_idp_host.SetHostStr(saml_idp_host);
|
| - GURL saml_idp_url = server_url.ReplaceComponents(replace_saml_idp_host);
|
| - saml_idp_url = saml_idp_url.Resolve("/SAML/SSO");
|
| -
|
| - fake_saml_idp_.SetUp(saml_idp_url.path(), gaia_url_);
|
| - fake_gaia_.RegisterSamlUser(kAnotherUserEmail, saml_idp_url);
|
| - fake_gaia_.RegisterSamlUser(kUserEmail, saml_idp_url);
|
| - }
|
| -
|
| - virtual void SetUpOnMainThread() OVERRIDE {
|
| - FakeGaia::MergeSessionParams params;
|
| - params.auth_sid_cookie = kTestAuthSIDCookie;
|
| - params.auth_lsid_cookie = kTestAuthLSIDCookie;
|
| - params.auth_code = kTestAuthCode;
|
| - params.refresh_token = kTestRefreshToken;
|
| - params.access_token = kTestAuthLoginAccessToken;
|
| - params.gaia_uber_token = kTestGaiaUberToken;
|
| - params.session_sid_cookie = kTestSessionSIDCookie;
|
| - params.session_lsid_cookie = kTestSessionLSIDCookie;
|
| - params.email = kUserEmail;
|
| - fake_gaia_.SetMergeSessionParams(params);
|
| -
|
| - embedded_test_server()->RegisterRequestHandler(
|
| - base::Bind(&FakeGaia::HandleRequest, base::Unretained(&fake_gaia_)));
|
| - embedded_test_server()->RegisterRequestHandler(base::Bind(
|
| - &FakeSamlIdp::HandleRequest, base::Unretained(&fake_saml_idp_)));
|
| -
|
| - // Restart the thread as the sandbox host process has already been spawned.
|
| - embedded_test_server()->RestartThreadAndListen();
|
| - }
|
| -
|
| - virtual void CleanUpOnMainThread() OVERRIDE {
|
| - // If the login display is still showing, exit gracefully.
|
| - if (LoginDisplayHostImpl::default_host()) {
|
| - base::MessageLoop::current()->PostTask(FROM_HERE,
|
| - base::Bind(&chrome::AttemptExit));
|
| - content::RunMessageLoop();
|
| - }
|
| - }
|
| -
|
| - WebUILoginDisplay* GetLoginDisplay() {
|
| - ExistingUserController* controller =
|
| - ExistingUserController::current_controller();
|
| - CHECK(controller);
|
| - return static_cast<WebUILoginDisplay*>(controller->login_display());
|
| - }
|
| -
|
| - void WaitForSigninScreen() {
|
| - WizardController::SkipPostLoginScreensForTesting();
|
| - WizardController* wizard_controller =
|
| - chromeos::WizardController::default_controller();
|
| - CHECK(wizard_controller);
|
| - wizard_controller->SkipToLoginForTesting(LoginScreenContext());
|
| -
|
| - content::WindowedNotificationObserver(
|
| - chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
|
| - content::NotificationService::AllSources()).Wait();
|
| - }
|
| -
|
| - void StartSamlAndWaitForIdpPageLoad(const std::string& gaia_email) {
|
| - WaitForSigninScreen();
|
| -
|
| - if (!saml_load_injected_) {
|
| - saml_load_injected_ = true;
|
| -
|
| - ASSERT_TRUE(content::ExecuteScript(
|
| - GetLoginUI()->GetWebContents(),
|
| - "$('gaia-signin').gaiaAuthHost_.addEventListener('authFlowChange',"
|
| - "function() {"
|
| - "window.domAutomationController.setAutomationId(0);"
|
| - "window.domAutomationController.send("
|
| - "$('gaia-signin').isSAML() ? 'SamlLoaded' : 'GaiaLoaded');"
|
| - "});"));
|
| - }
|
| -
|
| - content::DOMMessageQueue message_queue; // Start observe before SAML.
|
| - GetLoginDisplay()->ShowSigninScreenForCreds(gaia_email, "");
|
| -
|
| - std::string message;
|
| - ASSERT_TRUE(message_queue.WaitForMessage(&message));
|
| - EXPECT_EQ("\"SamlLoaded\"", message);
|
| - }
|
| -
|
| - void SetSignFormField(const std::string& field_id,
|
| - const std::string& field_value) {
|
| - std::string js =
|
| - "(function(){"
|
| - "document.getElementById('$FieldId').value = '$FieldValue';"
|
| - "var e = new Event('input');"
|
| - "document.getElementById('$FieldId').dispatchEvent(e);"
|
| - "})();";
|
| - ReplaceSubstringsAfterOffset(&js, 0, "$FieldId", field_id);
|
| - ReplaceSubstringsAfterOffset(&js, 0, "$FieldValue", field_value);
|
| - ExecuteJsInSigninFrame(js);
|
| - }
|
| -
|
| - void SendConfirmPassword(const std::string& password_to_confirm) {
|
| - std::string js =
|
| - "$('confirm-password-input').value='$Password';"
|
| - "$('confirm-password').onConfirmPassword_();";
|
| - ReplaceSubstringsAfterOffset(&js, 0, "$Password", password_to_confirm);
|
| - ASSERT_TRUE(content::ExecuteScript(GetLoginUI()->GetWebContents(), js));
|
| - }
|
| -
|
| - void JsExpect(const std::string& js) {
|
| - bool result;
|
| - EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
|
| - GetLoginUI()->GetWebContents(),
|
| - "window.domAutomationController.send(!!(" + js + "));",
|
| - &result));
|
| - EXPECT_TRUE(result) << js;
|
| - }
|
| -
|
| - content::WebUI* GetLoginUI() {
|
| - return static_cast<chromeos::LoginDisplayHostImpl*>(
|
| - chromeos::LoginDisplayHostImpl::default_host())->GetOobeUI()->web_ui();
|
| - }
|
| -
|
| - // Executes Js code in the auth iframe hosted by gaia_auth extension.
|
| - void ExecuteJsInSigninFrame(const std::string& js) {
|
| - ASSERT_TRUE(content::ExecuteScriptInFrame(
|
| - GetLoginUI()->GetWebContents(),
|
| - "//iframe[@id='signin-frame']\n//iframe",
|
| - js));
|
| - }
|
| -
|
| - FakeSamlIdp* fake_saml_idp() { return &fake_saml_idp_; }
|
| -
|
| - private:
|
| - GURL gaia_url_;
|
| - FakeGaia fake_gaia_;
|
| - FakeSamlIdp fake_saml_idp_;
|
| -
|
| - bool saml_load_injected_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(SamlTest);
|
| -};
|
| -
|
| -// Tests that signin frame should have 'saml' class and 'cancel' button is
|
| -// visible when SAML IdP page is loaded. And 'cancel' button goes back to
|
| -// gaia on clicking.
|
| -IN_PROC_BROWSER_TEST_F(SamlTest, SamlUI) {
|
| - fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
|
| - StartSamlAndWaitForIdpPageLoad(kUserEmail);
|
| -
|
| - // Saml flow UI expectations.
|
| - JsExpect("$('gaia-signin').classList.contains('saml')");
|
| - JsExpect("!$('cancel-add-user-button').hidden");
|
| -
|
| - // Click on 'cancel'.
|
| - content::DOMMessageQueue message_queue; // Observe before 'cancel'.
|
| - ASSERT_TRUE(content::ExecuteScript(
|
| - GetLoginUI()->GetWebContents(),
|
| - "$('cancel-add-user-button').click();"));
|
| -
|
| - // Auth flow should change back to Gaia.
|
| - std::string message;
|
| - do {
|
| - ASSERT_TRUE(message_queue.WaitForMessage(&message));
|
| - } while (message != "\"GaiaLoaded\"");
|
| -
|
| - // Saml flow is gone.
|
| - JsExpect("!$('gaia-signin').classList.contains('saml')");
|
| -}
|
| -
|
| -// Tests the sign-in flow when the credentials passing API is used.
|
| -IN_PROC_BROWSER_TEST_F(SamlTest, CredentialPassingAPI) {
|
| - fake_saml_idp()->SetLoginHTMLTemplate("saml_api_login.html");
|
| - fake_saml_idp()->SetLoginAuthHTMLTemplate("saml_api_login_auth.html");
|
| - StartSamlAndWaitForIdpPageLoad(kUserEmail);
|
| -
|
| - // Fill-in the SAML IdP form and submit.
|
| - SetSignFormField("Email", "fake_user");
|
| - SetSignFormField("Password", "fake_password");
|
| - ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
|
| -
|
| - // Login should finish login and a session should start.
|
| - content::WindowedNotificationObserver(
|
| - chrome::NOTIFICATION_SESSION_STARTED,
|
| - content::NotificationService::AllSources()).Wait();
|
| -}
|
| -
|
| -// Tests the single password scraped flow.
|
| -IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedSingle) {
|
| - fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
|
| - StartSamlAndWaitForIdpPageLoad(kUserEmail);
|
| -
|
| - // Fill-in the SAML IdP form and submit.
|
| - SetSignFormField("Email", "fake_user");
|
| - SetSignFormField("Password", "fake_password");
|
| - ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
|
| -
|
| - // Lands on confirm password screen.
|
| - OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait();
|
| -
|
| - // Enter an unknown password should go back to confirm password screen.
|
| - SendConfirmPassword("wrong_password");
|
| - OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait();
|
| -
|
| - // Enter a known password should finish login and start session.
|
| - SendConfirmPassword("fake_password");
|
| - content::WindowedNotificationObserver(
|
| - chrome::NOTIFICATION_SESSION_STARTED,
|
| - content::NotificationService::AllSources()).Wait();
|
| -}
|
| -
|
| -// Tests the multiple password scraped flow.
|
| -IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedMultiple) {
|
| - fake_saml_idp()->SetLoginHTMLTemplate("saml_login_two_passwords.html");
|
| -
|
| - StartSamlAndWaitForIdpPageLoad(kUserEmail);
|
| -
|
| - SetSignFormField("Email", "fake_user");
|
| - SetSignFormField("Password", "fake_password");
|
| - SetSignFormField("Password1", "password1");
|
| - ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
|
| -
|
| - OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait();
|
| -
|
| - // Either scraped password should be able to sign-in.
|
| - SendConfirmPassword("password1");
|
| - content::WindowedNotificationObserver(
|
| - chrome::NOTIFICATION_SESSION_STARTED,
|
| - content::NotificationService::AllSources()).Wait();
|
| -}
|
| -
|
| -// Tests the no password scraped flow.
|
| -IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedNone) {
|
| - fake_saml_idp()->SetLoginHTMLTemplate("saml_login_no_passwords.html");
|
| -
|
| - StartSamlAndWaitForIdpPageLoad(kUserEmail);
|
| -
|
| - SetSignFormField("Email", "fake_user");
|
| - ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
|
| -
|
| - OobeScreenWaiter(OobeDisplay::SCREEN_MESSAGE_BOX).Wait();
|
| - JsExpect(
|
| - "$('message-box-title').textContent == "
|
| - "loadTimeData.getString('noPasswordWarningTitle')");
|
| -}
|
| -
|
| -// Types |alice@example.com| into the GAIA login form but then authenticates as
|
| -// |bob@example.com| via SAML. Verifies that the logged-in user is correctly
|
| -// identified as Bob.
|
| -IN_PROC_BROWSER_TEST_F(SamlTest, UseAutenticatedUserEmailAddress) {
|
| - fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
|
| - // Type |alice@example.com| into the GAIA login form.
|
| - StartSamlAndWaitForIdpPageLoad(kAnotherUserEmail);
|
| -
|
| - // Authenticate as bob@example.com via SAML (the |Email| provided here is
|
| - // irrelevant - the authenticated user's e-mail address that FakeGAIA
|
| - // reports was set via SetMergeSessionParams()).
|
| - SetSignFormField("Email", "fake_user");
|
| - SetSignFormField("Password", "fake_password");
|
| - ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
|
| -
|
| - OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait();
|
| -
|
| - SendConfirmPassword("fake_password");
|
| - content::WindowedNotificationObserver(
|
| - chrome::NOTIFICATION_SESSION_STARTED,
|
| - content::NotificationService::AllSources()).Wait();
|
| - const User* user = UserManager::Get()->GetActiveUser();
|
| - ASSERT_TRUE(user);
|
| - EXPECT_EQ(kUserEmail, user->email());
|
| -}
|
| -
|
| -
|
| -} // namespace chromeos
|
|
|