| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 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 "base/command_line.h" | |
| 6 #include "base/file_util.h" | |
| 7 #include "base/files/file_path.h" | |
| 8 #include "base/path_service.h" | |
| 9 #include "base/strings/string_util.h" | |
| 10 #include "base/strings/utf_string_conversions.h" | |
| 11 #include "chrome/browser/chrome_notification_types.h" | |
| 12 #include "chrome/browser/chromeos/login/existing_user_controller.h" | |
| 13 #include "chrome/browser/chromeos/login/login_display_host_impl.h" | |
| 14 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" | |
| 15 #include "chrome/browser/chromeos/login/user.h" | |
| 16 #include "chrome/browser/chromeos/login/user_manager.h" | |
| 17 #include "chrome/browser/chromeos/login/webui_login_display.h" | |
| 18 #include "chrome/browser/chromeos/login/wizard_controller.h" | |
| 19 #include "chrome/browser/lifetime/application_lifetime.h" | |
| 20 #include "chrome/common/chrome_paths.h" | |
| 21 #include "chrome/common/chrome_switches.h" | |
| 22 #include "chrome/test/base/in_process_browser_test.h" | |
| 23 #include "chromeos/chromeos_switches.h" | |
| 24 #include "content/public/browser/render_view_host.h" | |
| 25 #include "content/public/browser/web_contents.h" | |
| 26 #include "content/public/test/browser_test_utils.h" | |
| 27 #include "content/public/test/test_utils.h" | |
| 28 #include "google_apis/gaia/fake_gaia.h" | |
| 29 #include "google_apis/gaia/gaia_switches.h" | |
| 30 #include "net/base/url_util.h" | |
| 31 #include "net/dns/mock_host_resolver.h" | |
| 32 #include "net/test/embedded_test_server/embedded_test_server.h" | |
| 33 #include "net/test/embedded_test_server/http_request.h" | |
| 34 #include "net/test/embedded_test_server/http_response.h" | |
| 35 #include "testing/gtest/include/gtest/gtest.h" | |
| 36 | |
| 37 using net::test_server::BasicHttpResponse; | |
| 38 using net::test_server::HttpRequest; | |
| 39 using net::test_server::HttpResponse; | |
| 40 | |
| 41 namespace chromeos { | |
| 42 | |
| 43 namespace { | |
| 44 | |
| 45 const char kTestAuthSIDCookie[] = "fake-auth-SID-cookie"; | |
| 46 const char kTestAuthLSIDCookie[] = "fake-auth-LSID-cookie"; | |
| 47 const char kTestAuthCode[] = "fake-auth-code"; | |
| 48 const char kTestGaiaUberToken[] = "fake-uber-token"; | |
| 49 const char kTestAuthLoginAccessToken[] = "fake-access-token"; | |
| 50 const char kTestRefreshToken[] = "fake-refresh-token"; | |
| 51 const char kTestSessionSIDCookie[] = "fake-session-SID-cookie"; | |
| 52 const char kTestSessionLSIDCookie[] = "fake-session-LSID-cookie"; | |
| 53 | |
| 54 const char kAnotherUserEmail[] = "alice@example.com"; | |
| 55 const char kUserEmail[] = "bob@example.com"; | |
| 56 | |
| 57 const char kRelayState[] = "RelayState"; | |
| 58 | |
| 59 // FakeSamlIdp serves IdP auth form and the form submission. The form is | |
| 60 // served with the template's RelayState placeholder expanded to the real | |
| 61 // RelayState parameter from request. The form submission redirects back to | |
| 62 // FakeGaia with the same RelayState. | |
| 63 class FakeSamlIdp { | |
| 64 public: | |
| 65 FakeSamlIdp(); | |
| 66 ~FakeSamlIdp(); | |
| 67 | |
| 68 void SetUp(const std::string& base_path, const GURL& gaia_url); | |
| 69 | |
| 70 void SetLoginHTMLTemplate(const std::string& template_file); | |
| 71 void SetLoginAuthHTMLTemplate(const std::string& template_file); | |
| 72 | |
| 73 scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request); | |
| 74 | |
| 75 private: | |
| 76 scoped_ptr<HttpResponse> BuildHTMLResponse(const std::string& html_template, | |
| 77 const std::string& relay_state, | |
| 78 const std::string& next_path); | |
| 79 | |
| 80 base::FilePath html_template_dir_; | |
| 81 | |
| 82 std::string login_path_; | |
| 83 std::string login_auth_path_; | |
| 84 | |
| 85 std::string login_html_template_; | |
| 86 std::string login_auth_html_template_; | |
| 87 GURL gaia_assertion_url_; | |
| 88 | |
| 89 DISALLOW_COPY_AND_ASSIGN(FakeSamlIdp); | |
| 90 }; | |
| 91 | |
| 92 FakeSamlIdp::FakeSamlIdp() { | |
| 93 } | |
| 94 | |
| 95 FakeSamlIdp::~FakeSamlIdp() { | |
| 96 } | |
| 97 | |
| 98 void FakeSamlIdp::SetUp(const std::string& base_path, const GURL& gaia_url) { | |
| 99 base::FilePath test_data_dir; | |
| 100 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)); | |
| 101 html_template_dir_ = test_data_dir.Append("login"); | |
| 102 | |
| 103 login_path_= base_path; | |
| 104 login_auth_path_ = base_path + "Auth"; | |
| 105 gaia_assertion_url_ = gaia_url.Resolve("/SSO"); | |
| 106 } | |
| 107 | |
| 108 void FakeSamlIdp::SetLoginHTMLTemplate(const std::string& template_file) { | |
| 109 EXPECT_TRUE(base::ReadFileToString( | |
| 110 html_template_dir_.Append(template_file), | |
| 111 &login_html_template_)); | |
| 112 } | |
| 113 | |
| 114 void FakeSamlIdp::SetLoginAuthHTMLTemplate(const std::string& template_file) { | |
| 115 EXPECT_TRUE(base::ReadFileToString( | |
| 116 html_template_dir_.Append(template_file), | |
| 117 &login_auth_html_template_)); | |
| 118 } | |
| 119 | |
| 120 scoped_ptr<HttpResponse> FakeSamlIdp::HandleRequest( | |
| 121 const HttpRequest& request) { | |
| 122 // The scheme and host of the URL is actually not important but required to | |
| 123 // get a valid GURL in order to parse |request.relative_url|. | |
| 124 GURL request_url = GURL("http://localhost").Resolve(request.relative_url); | |
| 125 std::string request_path = request_url.path(); | |
| 126 | |
| 127 if (request_path == login_path_) { | |
| 128 std::string relay_state; | |
| 129 net::GetValueForKeyInQuery(request_url, kRelayState, &relay_state); | |
| 130 return BuildHTMLResponse(login_html_template_, | |
| 131 relay_state, | |
| 132 login_auth_path_); | |
| 133 } | |
| 134 | |
| 135 if (request_path != login_auth_path_) { | |
| 136 // Request not understood. | |
| 137 return scoped_ptr<HttpResponse>(); | |
| 138 } | |
| 139 | |
| 140 std::string relay_state; | |
| 141 FakeGaia::GetQueryParameter(request.content, kRelayState, &relay_state); | |
| 142 GURL redirect_url = gaia_assertion_url_; | |
| 143 | |
| 144 if (!login_auth_html_template_.empty()) { | |
| 145 return BuildHTMLResponse(login_auth_html_template_, | |
| 146 relay_state, | |
| 147 redirect_url.spec()); | |
| 148 } | |
| 149 | |
| 150 redirect_url = net::AppendQueryParameter( | |
| 151 redirect_url, "SAMLResponse", "fake_response"); | |
| 152 redirect_url = net::AppendQueryParameter( | |
| 153 redirect_url, kRelayState, relay_state); | |
| 154 | |
| 155 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse()); | |
| 156 http_response->set_code(net::HTTP_TEMPORARY_REDIRECT); | |
| 157 http_response->AddCustomHeader("Location", redirect_url.spec()); | |
| 158 return http_response.PassAs<HttpResponse>(); | |
| 159 } | |
| 160 | |
| 161 scoped_ptr<HttpResponse> FakeSamlIdp::BuildHTMLResponse( | |
| 162 const std::string& html_template, | |
| 163 const std::string& relay_state, | |
| 164 const std::string& next_path) { | |
| 165 std::string response_html = html_template; | |
| 166 ReplaceSubstringsAfterOffset(&response_html, 0, "$RelayState", relay_state); | |
| 167 ReplaceSubstringsAfterOffset(&response_html, 0, "$Post", next_path); | |
| 168 | |
| 169 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse()); | |
| 170 http_response->set_code(net::HTTP_OK); | |
| 171 http_response->set_content(response_html); | |
| 172 http_response->set_content_type("text/html"); | |
| 173 | |
| 174 return http_response.PassAs<HttpResponse>(); | |
| 175 } | |
| 176 | |
| 177 } // namespace | |
| 178 | |
| 179 class SamlTest : public InProcessBrowserTest { | |
| 180 public: | |
| 181 SamlTest() : saml_load_injected_(false) {} | |
| 182 virtual ~SamlTest() {} | |
| 183 | |
| 184 virtual void SetUp() OVERRIDE { | |
| 185 // Start embedded test server here so that we can get server base url | |
| 186 // and override Gaia urls in SetupCommandLine. | |
| 187 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | |
| 188 | |
| 189 // Stop IO thread here because no threads are allowed while | |
| 190 // spawning sandbox host process. See crbug.com/322732. | |
| 191 embedded_test_server()->StopThread(); | |
| 192 | |
| 193 InProcessBrowserTest::SetUp(); | |
| 194 } | |
| 195 | |
| 196 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { | |
| 197 host_resolver()->AddRule("*", "127.0.0.1"); | |
| 198 } | |
| 199 | |
| 200 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { | |
| 201 command_line->AppendSwitch(switches::kLoginManager); | |
| 202 command_line->AppendSwitch(switches::kForceLoginManagerInTests); | |
| 203 command_line->AppendSwitch(::switches::kDisableBackgroundNetworking); | |
| 204 command_line->AppendSwitchASCII(switches::kLoginProfile, "user"); | |
| 205 | |
| 206 const GURL& server_url = embedded_test_server()->base_url(); | |
| 207 | |
| 208 std::string gaia_host("gaia"); | |
| 209 GURL::Replacements replace_gaia_host; | |
| 210 replace_gaia_host.SetHostStr(gaia_host); | |
| 211 gaia_url_ = server_url.ReplaceComponents(replace_gaia_host); | |
| 212 | |
| 213 command_line->AppendSwitchASCII(::switches::kGaiaUrl, gaia_url_.spec()); | |
| 214 command_line->AppendSwitchASCII(::switches::kLsoUrl, gaia_url_.spec()); | |
| 215 command_line->AppendSwitchASCII(::switches::kGoogleApisUrl, | |
| 216 gaia_url_.spec()); | |
| 217 fake_gaia_.Initialize(); | |
| 218 | |
| 219 std::string saml_idp_host("saml.idp"); | |
| 220 GURL::Replacements replace_saml_idp_host; | |
| 221 replace_saml_idp_host.SetHostStr(saml_idp_host); | |
| 222 GURL saml_idp_url = server_url.ReplaceComponents(replace_saml_idp_host); | |
| 223 saml_idp_url = saml_idp_url.Resolve("/SAML/SSO"); | |
| 224 | |
| 225 fake_saml_idp_.SetUp(saml_idp_url.path(), gaia_url_); | |
| 226 fake_gaia_.RegisterSamlUser(kAnotherUserEmail, saml_idp_url); | |
| 227 fake_gaia_.RegisterSamlUser(kUserEmail, saml_idp_url); | |
| 228 } | |
| 229 | |
| 230 virtual void SetUpOnMainThread() OVERRIDE { | |
| 231 FakeGaia::MergeSessionParams params; | |
| 232 params.auth_sid_cookie = kTestAuthSIDCookie; | |
| 233 params.auth_lsid_cookie = kTestAuthLSIDCookie; | |
| 234 params.auth_code = kTestAuthCode; | |
| 235 params.refresh_token = kTestRefreshToken; | |
| 236 params.access_token = kTestAuthLoginAccessToken; | |
| 237 params.gaia_uber_token = kTestGaiaUberToken; | |
| 238 params.session_sid_cookie = kTestSessionSIDCookie; | |
| 239 params.session_lsid_cookie = kTestSessionLSIDCookie; | |
| 240 params.email = kUserEmail; | |
| 241 fake_gaia_.SetMergeSessionParams(params); | |
| 242 | |
| 243 embedded_test_server()->RegisterRequestHandler( | |
| 244 base::Bind(&FakeGaia::HandleRequest, base::Unretained(&fake_gaia_))); | |
| 245 embedded_test_server()->RegisterRequestHandler(base::Bind( | |
| 246 &FakeSamlIdp::HandleRequest, base::Unretained(&fake_saml_idp_))); | |
| 247 | |
| 248 // Restart the thread as the sandbox host process has already been spawned. | |
| 249 embedded_test_server()->RestartThreadAndListen(); | |
| 250 } | |
| 251 | |
| 252 virtual void CleanUpOnMainThread() OVERRIDE { | |
| 253 // If the login display is still showing, exit gracefully. | |
| 254 if (LoginDisplayHostImpl::default_host()) { | |
| 255 base::MessageLoop::current()->PostTask(FROM_HERE, | |
| 256 base::Bind(&chrome::AttemptExit)); | |
| 257 content::RunMessageLoop(); | |
| 258 } | |
| 259 } | |
| 260 | |
| 261 WebUILoginDisplay* GetLoginDisplay() { | |
| 262 ExistingUserController* controller = | |
| 263 ExistingUserController::current_controller(); | |
| 264 CHECK(controller); | |
| 265 return static_cast<WebUILoginDisplay*>(controller->login_display()); | |
| 266 } | |
| 267 | |
| 268 void WaitForSigninScreen() { | |
| 269 WizardController::SkipPostLoginScreensForTesting(); | |
| 270 WizardController* wizard_controller = | |
| 271 chromeos::WizardController::default_controller(); | |
| 272 CHECK(wizard_controller); | |
| 273 wizard_controller->SkipToLoginForTesting(LoginScreenContext()); | |
| 274 | |
| 275 content::WindowedNotificationObserver( | |
| 276 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, | |
| 277 content::NotificationService::AllSources()).Wait(); | |
| 278 } | |
| 279 | |
| 280 void StartSamlAndWaitForIdpPageLoad(const std::string& gaia_email) { | |
| 281 WaitForSigninScreen(); | |
| 282 | |
| 283 if (!saml_load_injected_) { | |
| 284 saml_load_injected_ = true; | |
| 285 | |
| 286 ASSERT_TRUE(content::ExecuteScript( | |
| 287 GetLoginUI()->GetWebContents(), | |
| 288 "$('gaia-signin').gaiaAuthHost_.addEventListener('authFlowChange'," | |
| 289 "function() {" | |
| 290 "window.domAutomationController.setAutomationId(0);" | |
| 291 "window.domAutomationController.send(" | |
| 292 "$('gaia-signin').isSAML() ? 'SamlLoaded' : 'GaiaLoaded');" | |
| 293 "});")); | |
| 294 } | |
| 295 | |
| 296 content::DOMMessageQueue message_queue; // Start observe before SAML. | |
| 297 GetLoginDisplay()->ShowSigninScreenForCreds(gaia_email, ""); | |
| 298 | |
| 299 std::string message; | |
| 300 ASSERT_TRUE(message_queue.WaitForMessage(&message)); | |
| 301 EXPECT_EQ("\"SamlLoaded\"", message); | |
| 302 } | |
| 303 | |
| 304 void SetSignFormField(const std::string& field_id, | |
| 305 const std::string& field_value) { | |
| 306 std::string js = | |
| 307 "(function(){" | |
| 308 "document.getElementById('$FieldId').value = '$FieldValue';" | |
| 309 "var e = new Event('input');" | |
| 310 "document.getElementById('$FieldId').dispatchEvent(e);" | |
| 311 "})();"; | |
| 312 ReplaceSubstringsAfterOffset(&js, 0, "$FieldId", field_id); | |
| 313 ReplaceSubstringsAfterOffset(&js, 0, "$FieldValue", field_value); | |
| 314 ExecuteJsInSigninFrame(js); | |
| 315 } | |
| 316 | |
| 317 void SendConfirmPassword(const std::string& password_to_confirm) { | |
| 318 std::string js = | |
| 319 "$('confirm-password-input').value='$Password';" | |
| 320 "$('confirm-password').onConfirmPassword_();"; | |
| 321 ReplaceSubstringsAfterOffset(&js, 0, "$Password", password_to_confirm); | |
| 322 ASSERT_TRUE(content::ExecuteScript(GetLoginUI()->GetWebContents(), js)); | |
| 323 } | |
| 324 | |
| 325 void JsExpect(const std::string& js) { | |
| 326 bool result; | |
| 327 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( | |
| 328 GetLoginUI()->GetWebContents(), | |
| 329 "window.domAutomationController.send(!!(" + js + "));", | |
| 330 &result)); | |
| 331 EXPECT_TRUE(result) << js; | |
| 332 } | |
| 333 | |
| 334 content::WebUI* GetLoginUI() { | |
| 335 return static_cast<chromeos::LoginDisplayHostImpl*>( | |
| 336 chromeos::LoginDisplayHostImpl::default_host())->GetOobeUI()->web_ui(); | |
| 337 } | |
| 338 | |
| 339 // Executes Js code in the auth iframe hosted by gaia_auth extension. | |
| 340 void ExecuteJsInSigninFrame(const std::string& js) { | |
| 341 ASSERT_TRUE(content::ExecuteScriptInFrame( | |
| 342 GetLoginUI()->GetWebContents(), | |
| 343 "//iframe[@id='signin-frame']\n//iframe", | |
| 344 js)); | |
| 345 } | |
| 346 | |
| 347 FakeSamlIdp* fake_saml_idp() { return &fake_saml_idp_; } | |
| 348 | |
| 349 private: | |
| 350 GURL gaia_url_; | |
| 351 FakeGaia fake_gaia_; | |
| 352 FakeSamlIdp fake_saml_idp_; | |
| 353 | |
| 354 bool saml_load_injected_; | |
| 355 | |
| 356 DISALLOW_COPY_AND_ASSIGN(SamlTest); | |
| 357 }; | |
| 358 | |
| 359 // Tests that signin frame should have 'saml' class and 'cancel' button is | |
| 360 // visible when SAML IdP page is loaded. And 'cancel' button goes back to | |
| 361 // gaia on clicking. | |
| 362 IN_PROC_BROWSER_TEST_F(SamlTest, SamlUI) { | |
| 363 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html"); | |
| 364 StartSamlAndWaitForIdpPageLoad(kUserEmail); | |
| 365 | |
| 366 // Saml flow UI expectations. | |
| 367 JsExpect("$('gaia-signin').classList.contains('saml')"); | |
| 368 JsExpect("!$('cancel-add-user-button').hidden"); | |
| 369 | |
| 370 // Click on 'cancel'. | |
| 371 content::DOMMessageQueue message_queue; // Observe before 'cancel'. | |
| 372 ASSERT_TRUE(content::ExecuteScript( | |
| 373 GetLoginUI()->GetWebContents(), | |
| 374 "$('cancel-add-user-button').click();")); | |
| 375 | |
| 376 // Auth flow should change back to Gaia. | |
| 377 std::string message; | |
| 378 do { | |
| 379 ASSERT_TRUE(message_queue.WaitForMessage(&message)); | |
| 380 } while (message != "\"GaiaLoaded\""); | |
| 381 | |
| 382 // Saml flow is gone. | |
| 383 JsExpect("!$('gaia-signin').classList.contains('saml')"); | |
| 384 } | |
| 385 | |
| 386 // Tests the sign-in flow when the credentials passing API is used. | |
| 387 IN_PROC_BROWSER_TEST_F(SamlTest, CredentialPassingAPI) { | |
| 388 fake_saml_idp()->SetLoginHTMLTemplate("saml_api_login.html"); | |
| 389 fake_saml_idp()->SetLoginAuthHTMLTemplate("saml_api_login_auth.html"); | |
| 390 StartSamlAndWaitForIdpPageLoad(kUserEmail); | |
| 391 | |
| 392 // Fill-in the SAML IdP form and submit. | |
| 393 SetSignFormField("Email", "fake_user"); | |
| 394 SetSignFormField("Password", "fake_password"); | |
| 395 ExecuteJsInSigninFrame("document.getElementById('Submit').click();"); | |
| 396 | |
| 397 // Login should finish login and a session should start. | |
| 398 content::WindowedNotificationObserver( | |
| 399 chrome::NOTIFICATION_SESSION_STARTED, | |
| 400 content::NotificationService::AllSources()).Wait(); | |
| 401 } | |
| 402 | |
| 403 // Tests the single password scraped flow. | |
| 404 IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedSingle) { | |
| 405 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html"); | |
| 406 StartSamlAndWaitForIdpPageLoad(kUserEmail); | |
| 407 | |
| 408 // Fill-in the SAML IdP form and submit. | |
| 409 SetSignFormField("Email", "fake_user"); | |
| 410 SetSignFormField("Password", "fake_password"); | |
| 411 ExecuteJsInSigninFrame("document.getElementById('Submit').click();"); | |
| 412 | |
| 413 // Lands on confirm password screen. | |
| 414 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait(); | |
| 415 | |
| 416 // Enter an unknown password should go back to confirm password screen. | |
| 417 SendConfirmPassword("wrong_password"); | |
| 418 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait(); | |
| 419 | |
| 420 // Enter a known password should finish login and start session. | |
| 421 SendConfirmPassword("fake_password"); | |
| 422 content::WindowedNotificationObserver( | |
| 423 chrome::NOTIFICATION_SESSION_STARTED, | |
| 424 content::NotificationService::AllSources()).Wait(); | |
| 425 } | |
| 426 | |
| 427 // Tests the multiple password scraped flow. | |
| 428 IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedMultiple) { | |
| 429 fake_saml_idp()->SetLoginHTMLTemplate("saml_login_two_passwords.html"); | |
| 430 | |
| 431 StartSamlAndWaitForIdpPageLoad(kUserEmail); | |
| 432 | |
| 433 SetSignFormField("Email", "fake_user"); | |
| 434 SetSignFormField("Password", "fake_password"); | |
| 435 SetSignFormField("Password1", "password1"); | |
| 436 ExecuteJsInSigninFrame("document.getElementById('Submit').click();"); | |
| 437 | |
| 438 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait(); | |
| 439 | |
| 440 // Either scraped password should be able to sign-in. | |
| 441 SendConfirmPassword("password1"); | |
| 442 content::WindowedNotificationObserver( | |
| 443 chrome::NOTIFICATION_SESSION_STARTED, | |
| 444 content::NotificationService::AllSources()).Wait(); | |
| 445 } | |
| 446 | |
| 447 // Tests the no password scraped flow. | |
| 448 IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedNone) { | |
| 449 fake_saml_idp()->SetLoginHTMLTemplate("saml_login_no_passwords.html"); | |
| 450 | |
| 451 StartSamlAndWaitForIdpPageLoad(kUserEmail); | |
| 452 | |
| 453 SetSignFormField("Email", "fake_user"); | |
| 454 ExecuteJsInSigninFrame("document.getElementById('Submit').click();"); | |
| 455 | |
| 456 OobeScreenWaiter(OobeDisplay::SCREEN_MESSAGE_BOX).Wait(); | |
| 457 JsExpect( | |
| 458 "$('message-box-title').textContent == " | |
| 459 "loadTimeData.getString('noPasswordWarningTitle')"); | |
| 460 } | |
| 461 | |
| 462 // Types |alice@example.com| into the GAIA login form but then authenticates as | |
| 463 // |bob@example.com| via SAML. Verifies that the logged-in user is correctly | |
| 464 // identified as Bob. | |
| 465 IN_PROC_BROWSER_TEST_F(SamlTest, UseAutenticatedUserEmailAddress) { | |
| 466 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html"); | |
| 467 // Type |alice@example.com| into the GAIA login form. | |
| 468 StartSamlAndWaitForIdpPageLoad(kAnotherUserEmail); | |
| 469 | |
| 470 // Authenticate as bob@example.com via SAML (the |Email| provided here is | |
| 471 // irrelevant - the authenticated user's e-mail address that FakeGAIA | |
| 472 // reports was set via SetMergeSessionParams()). | |
| 473 SetSignFormField("Email", "fake_user"); | |
| 474 SetSignFormField("Password", "fake_password"); | |
| 475 ExecuteJsInSigninFrame("document.getElementById('Submit').click();"); | |
| 476 | |
| 477 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait(); | |
| 478 | |
| 479 SendConfirmPassword("fake_password"); | |
| 480 content::WindowedNotificationObserver( | |
| 481 chrome::NOTIFICATION_SESSION_STARTED, | |
| 482 content::NotificationService::AllSources()).Wait(); | |
| 483 const User* user = UserManager::Get()->GetActiveUser(); | |
| 484 ASSERT_TRUE(user); | |
| 485 EXPECT_EQ(kUserEmail, user->email()); | |
| 486 } | |
| 487 | |
| 488 | |
| 489 } // namespace chromeos | |
| OLD | NEW |