| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/command_line.h" | 5 #include "base/command_line.h" |
| 6 #include "base/strings/string_util.h" | 6 #include "base/strings/string_util.h" |
| 7 #include "base/strings/utf_string_conversions.h" | 7 #include "base/strings/utf_string_conversions.h" |
| 8 #include "chrome/browser/chrome_notification_types.h" | 8 #include "chrome/browser/chrome_notification_types.h" |
| 9 #include "chrome/browser/chromeos/login/existing_user_controller.h" | 9 #include "chrome/browser/chromeos/login/existing_user_controller.h" |
| 10 #include "chrome/browser/chromeos/login/login_display_host_impl.h" | 10 #include "chrome/browser/chromeos/login/login_display_host_impl.h" |
| 11 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" | 11 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" |
| 12 #include "chrome/browser/chromeos/login/user.h" |
| 13 #include "chrome/browser/chromeos/login/user_manager.h" |
| 12 #include "chrome/browser/chromeos/login/webui_login_display.h" | 14 #include "chrome/browser/chromeos/login/webui_login_display.h" |
| 13 #include "chrome/browser/chromeos/login/wizard_controller.h" | 15 #include "chrome/browser/chromeos/login/wizard_controller.h" |
| 14 #include "chrome/browser/lifetime/application_lifetime.h" | 16 #include "chrome/browser/lifetime/application_lifetime.h" |
| 15 #include "chrome/common/chrome_switches.h" | 17 #include "chrome/common/chrome_switches.h" |
| 16 #include "chrome/test/base/in_process_browser_test.h" | 18 #include "chrome/test/base/in_process_browser_test.h" |
| 17 #include "chromeos/chromeos_switches.h" | 19 #include "chromeos/chromeos_switches.h" |
| 18 #include "content/public/browser/render_view_host.h" | 20 #include "content/public/browser/render_view_host.h" |
| 19 #include "content/public/browser/web_contents.h" | 21 #include "content/public/browser/web_contents.h" |
| 20 #include "content/public/test/browser_test_utils.h" | 22 #include "content/public/test/browser_test_utils.h" |
| 21 #include "content/public/test/test_utils.h" | 23 #include "content/public/test/test_utils.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 38 | 40 |
| 39 const char kTestAuthSIDCookie[] = "fake-auth-SID-cookie"; | 41 const char kTestAuthSIDCookie[] = "fake-auth-SID-cookie"; |
| 40 const char kTestAuthLSIDCookie[] = "fake-auth-LSID-cookie"; | 42 const char kTestAuthLSIDCookie[] = "fake-auth-LSID-cookie"; |
| 41 const char kTestAuthCode[] = "fake-auth-code"; | 43 const char kTestAuthCode[] = "fake-auth-code"; |
| 42 const char kTestGaiaUberToken[] = "fake-uber-token"; | 44 const char kTestGaiaUberToken[] = "fake-uber-token"; |
| 43 const char kTestAuthLoginAccessToken[] = "fake-access-token"; | 45 const char kTestAuthLoginAccessToken[] = "fake-access-token"; |
| 44 const char kTestRefreshToken[] = "fake-refresh-token"; | 46 const char kTestRefreshToken[] = "fake-refresh-token"; |
| 45 const char kTestSessionSIDCookie[] = "fake-session-SID-cookie"; | 47 const char kTestSessionSIDCookie[] = "fake-session-SID-cookie"; |
| 46 const char kTestSessionLSIDCookie[] = "fake-session-LSID-cookie"; | 48 const char kTestSessionLSIDCookie[] = "fake-session-LSID-cookie"; |
| 47 | 49 |
| 50 const char kAnotherUserEmail[] = "alice@example.com"; |
| 51 const char kUserEmail[] = "bob@example.com"; |
| 52 |
| 48 const char kRelayState[] = "RelayState"; | 53 const char kRelayState[] = "RelayState"; |
| 49 | 54 |
| 50 const char kDefaultIdpHtml[] = | 55 const char kDefaultIdpHtml[] = |
| 51 "<form id=IdPForm method=post action=\"$Post\">" | 56 "<form id=IdPForm method=post action=\"$Post\">" |
| 52 "<input type=hidden name=RelayState value=\"$RelayState\">" | 57 "<input type=hidden name=RelayState value=\"$RelayState\">" |
| 53 "User: <input type=text id=Email name=Email>" | 58 "User: <input type=text id=Email name=Email>" |
| 54 "Password: <input type=password id=Password name=Password>" | 59 "Password: <input type=password id=Password name=Password>" |
| 55 "<input id=Submit type=submit>" | 60 "<input id=Submit type=submit>" |
| 56 "</form>"; | 61 "</form>"; |
| 57 | 62 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 gaia_url_.spec()); | 171 gaia_url_.spec()); |
| 167 fake_gaia_.Initialize(); | 172 fake_gaia_.Initialize(); |
| 168 | 173 |
| 169 std::string saml_idp_host("saml.idp"); | 174 std::string saml_idp_host("saml.idp"); |
| 170 GURL::Replacements replace_saml_idp_host; | 175 GURL::Replacements replace_saml_idp_host; |
| 171 replace_saml_idp_host.SetHostStr(saml_idp_host); | 176 replace_saml_idp_host.SetHostStr(saml_idp_host); |
| 172 GURL saml_idp_url = server_url.ReplaceComponents(replace_saml_idp_host); | 177 GURL saml_idp_url = server_url.ReplaceComponents(replace_saml_idp_host); |
| 173 saml_idp_url = saml_idp_url.Resolve("/SAML/SSO"); | 178 saml_idp_url = saml_idp_url.Resolve("/SAML/SSO"); |
| 174 | 179 |
| 175 fake_saml_idp_.SetUp(saml_idp_url.path(), gaia_url_); | 180 fake_saml_idp_.SetUp(saml_idp_url.path(), gaia_url_); |
| 176 fake_gaia_.RegisterSamlUser("saml_user", saml_idp_url); | 181 fake_gaia_.RegisterSamlUser(kAnotherUserEmail, saml_idp_url); |
| 182 fake_gaia_.RegisterSamlUser(kUserEmail, saml_idp_url); |
| 177 } | 183 } |
| 178 | 184 |
| 179 virtual void SetUpOnMainThread() OVERRIDE { | 185 virtual void SetUpOnMainThread() OVERRIDE { |
| 180 FakeGaia::MergeSessionParams params; | 186 FakeGaia::MergeSessionParams params; |
| 181 params.auth_sid_cookie = kTestAuthSIDCookie; | 187 params.auth_sid_cookie = kTestAuthSIDCookie; |
| 182 params.auth_lsid_cookie = kTestAuthLSIDCookie; | 188 params.auth_lsid_cookie = kTestAuthLSIDCookie; |
| 183 params.auth_code = kTestAuthCode; | 189 params.auth_code = kTestAuthCode; |
| 184 params.refresh_token = kTestRefreshToken; | 190 params.refresh_token = kTestRefreshToken; |
| 185 params.access_token = kTestAuthLoginAccessToken; | 191 params.access_token = kTestAuthLoginAccessToken; |
| 186 params.gaia_uber_token = kTestGaiaUberToken; | 192 params.gaia_uber_token = kTestGaiaUberToken; |
| 187 params.session_sid_cookie = kTestSessionSIDCookie; | 193 params.session_sid_cookie = kTestSessionSIDCookie; |
| 188 params.session_lsid_cookie = kTestSessionLSIDCookie; | 194 params.session_lsid_cookie = kTestSessionLSIDCookie; |
| 195 params.email = kUserEmail; |
| 189 fake_gaia_.SetMergeSessionParams(params); | 196 fake_gaia_.SetMergeSessionParams(params); |
| 190 | 197 |
| 191 embedded_test_server()->RegisterRequestHandler( | 198 embedded_test_server()->RegisterRequestHandler( |
| 192 base::Bind(&FakeGaia::HandleRequest, base::Unretained(&fake_gaia_))); | 199 base::Bind(&FakeGaia::HandleRequest, base::Unretained(&fake_gaia_))); |
| 193 embedded_test_server()->RegisterRequestHandler(base::Bind( | 200 embedded_test_server()->RegisterRequestHandler(base::Bind( |
| 194 &FakeSamlIdp::HandleRequest, base::Unretained(&fake_saml_idp_))); | 201 &FakeSamlIdp::HandleRequest, base::Unretained(&fake_saml_idp_))); |
| 195 | 202 |
| 196 // Restart the thread as the sandbox host process has already been spawned. | 203 // Restart the thread as the sandbox host process has already been spawned. |
| 197 embedded_test_server()->RestartThreadAndListen(); | 204 embedded_test_server()->RestartThreadAndListen(); |
| 198 } | 205 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 218 WizardController* wizard_controller = | 225 WizardController* wizard_controller = |
| 219 chromeos::WizardController::default_controller(); | 226 chromeos::WizardController::default_controller(); |
| 220 CHECK(wizard_controller); | 227 CHECK(wizard_controller); |
| 221 wizard_controller->SkipToLoginForTesting(LoginScreenContext()); | 228 wizard_controller->SkipToLoginForTesting(LoginScreenContext()); |
| 222 | 229 |
| 223 content::WindowedNotificationObserver( | 230 content::WindowedNotificationObserver( |
| 224 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, | 231 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, |
| 225 content::NotificationService::AllSources()).Wait(); | 232 content::NotificationService::AllSources()).Wait(); |
| 226 } | 233 } |
| 227 | 234 |
| 228 void StartSamlAndWaitForIdpPageLoad() { | 235 void StartSamlAndWaitForIdpPageLoad(const std::string& gaia_email) { |
| 229 WaitForSigninScreen(); | 236 WaitForSigninScreen(); |
| 230 | 237 |
| 231 if (!saml_load_injected_) { | 238 if (!saml_load_injected_) { |
| 232 saml_load_injected_ = true; | 239 saml_load_injected_ = true; |
| 233 | 240 |
| 234 ASSERT_TRUE(content::ExecuteScript( | 241 ASSERT_TRUE(content::ExecuteScript( |
| 235 GetLoginUI()->GetWebContents(), | 242 GetLoginUI()->GetWebContents(), |
| 236 "$('gaia-signin').gaiaAuthHost_.addEventListener('authFlowChange'," | 243 "$('gaia-signin').gaiaAuthHost_.addEventListener('authFlowChange'," |
| 237 "function() {" | 244 "function() {" |
| 238 "window.domAutomationController.setAutomationId(0);" | 245 "window.domAutomationController.setAutomationId(0);" |
| 239 "window.domAutomationController.send(" | 246 "window.domAutomationController.send(" |
| 240 "$('gaia-signin').isSAML() ? 'SamlLoaded' : 'GaiaLoaded');" | 247 "$('gaia-signin').isSAML() ? 'SamlLoaded' : 'GaiaLoaded');" |
| 241 "});")); | 248 "});")); |
| 242 } | 249 } |
| 243 | 250 |
| 244 content::DOMMessageQueue message_queue; // Start observe before SAML. | 251 content::DOMMessageQueue message_queue; // Start observe before SAML. |
| 245 GetLoginDisplay()->ShowSigninScreenForCreds("saml_user", ""); | 252 GetLoginDisplay()->ShowSigninScreenForCreds(gaia_email, ""); |
| 246 | 253 |
| 247 std::string message; | 254 std::string message; |
| 248 ASSERT_TRUE(message_queue.WaitForMessage(&message)); | 255 ASSERT_TRUE(message_queue.WaitForMessage(&message)); |
| 249 EXPECT_EQ("\"SamlLoaded\"", message); | 256 EXPECT_EQ("\"SamlLoaded\"", message); |
| 250 } | 257 } |
| 251 | 258 |
| 252 void SetSignFormField(const std::string& field_id, | 259 void SetSignFormField(const std::string& field_id, |
| 253 const std::string& field_value) { | 260 const std::string& field_value) { |
| 254 std::string js = | 261 std::string js = |
| 255 "(function(){" | 262 "(function(){" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 | 308 |
| 302 bool saml_load_injected_; | 309 bool saml_load_injected_; |
| 303 | 310 |
| 304 DISALLOW_COPY_AND_ASSIGN(SamlTest); | 311 DISALLOW_COPY_AND_ASSIGN(SamlTest); |
| 305 }; | 312 }; |
| 306 | 313 |
| 307 // Tests that signin frame should have 'saml' class and 'cancel' button is | 314 // Tests that signin frame should have 'saml' class and 'cancel' button is |
| 308 // visible when SAML IdP page is loaded. And 'cancel' button goes back to | 315 // visible when SAML IdP page is loaded. And 'cancel' button goes back to |
| 309 // gaia on clicking. | 316 // gaia on clicking. |
| 310 IN_PROC_BROWSER_TEST_F(SamlTest, SamlUI) { | 317 IN_PROC_BROWSER_TEST_F(SamlTest, SamlUI) { |
| 311 StartSamlAndWaitForIdpPageLoad(); | 318 StartSamlAndWaitForIdpPageLoad(kUserEmail); |
| 312 | 319 |
| 313 // Saml flow UI expectations. | 320 // Saml flow UI expectations. |
| 314 JsExpect("$('gaia-signin').classList.contains('saml')"); | 321 JsExpect("$('gaia-signin').classList.contains('saml')"); |
| 315 JsExpect("!$('cancel-add-user-button').hidden"); | 322 JsExpect("!$('cancel-add-user-button').hidden"); |
| 316 | 323 |
| 317 // Click on 'cancel'. | 324 // Click on 'cancel'. |
| 318 content::DOMMessageQueue message_queue; // Observe before 'cancel'. | 325 content::DOMMessageQueue message_queue; // Observe before 'cancel'. |
| 319 ASSERT_TRUE(content::ExecuteScript( | 326 ASSERT_TRUE(content::ExecuteScript( |
| 320 GetLoginUI()->GetWebContents(), | 327 GetLoginUI()->GetWebContents(), |
| 321 "$('cancel-add-user-button').click();")); | 328 "$('cancel-add-user-button').click();")); |
| 322 | 329 |
| 323 // Auth flow should change back to Gaia. | 330 // Auth flow should change back to Gaia. |
| 324 std::string message; | 331 std::string message; |
| 325 do { | 332 do { |
| 326 ASSERT_TRUE(message_queue.WaitForMessage(&message)); | 333 ASSERT_TRUE(message_queue.WaitForMessage(&message)); |
| 327 } while (message != "\"GaiaLoaded\""); | 334 } while (message != "\"GaiaLoaded\""); |
| 328 | 335 |
| 329 // Saml flow is gone. | 336 // Saml flow is gone. |
| 330 JsExpect("!$('gaia-signin').classList.contains('saml')"); | 337 JsExpect("!$('gaia-signin').classList.contains('saml')"); |
| 331 } | 338 } |
| 332 | 339 |
| 333 // Tests the single password scraped flow. | 340 // Tests the single password scraped flow. |
| 334 IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedSingle) { | 341 IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedSingle) { |
| 335 StartSamlAndWaitForIdpPageLoad(); | 342 StartSamlAndWaitForIdpPageLoad(kUserEmail); |
| 336 | 343 |
| 337 // Fill-in the SAML IdP form and submit. | 344 // Fill-in the SAML IdP form and submit. |
| 338 SetSignFormField("Email", "fake_user"); | 345 SetSignFormField("Email", "fake_user"); |
| 339 SetSignFormField("Password", "fake_password"); | 346 SetSignFormField("Password", "fake_password"); |
| 340 ExecuteJsInSigninFrame("document.getElementById('IdPForm').submit();"); | 347 ExecuteJsInSigninFrame("document.getElementById('IdPForm').submit();"); |
| 341 | 348 |
| 342 // Lands on confirm password screen. | 349 // Lands on confirm password screen. |
| 343 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait(); | 350 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait(); |
| 344 | 351 |
| 345 // Enter an unknown password should go back to confirm password screen. | 352 // Enter an unknown password should go back to confirm password screen. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 357 IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedMultiple) { | 364 IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedMultiple) { |
| 358 fake_saml_idp()->set_html_template( | 365 fake_saml_idp()->set_html_template( |
| 359 "<form id=IdPForm method=post action=\"$Post\">" | 366 "<form id=IdPForm method=post action=\"$Post\">" |
| 360 "<input type=hidden name=RelayState value=\"$RelayState\">" | 367 "<input type=hidden name=RelayState value=\"$RelayState\">" |
| 361 "User: <input type=text id=Email name=Email>" | 368 "User: <input type=text id=Email name=Email>" |
| 362 "Password: <input type=password id=Password name=Password>" | 369 "Password: <input type=password id=Password name=Password>" |
| 363 "Password: <input type=password id=Password1 name=Password1>" | 370 "Password: <input type=password id=Password1 name=Password1>" |
| 364 "<input id=Submit type=submit>" | 371 "<input id=Submit type=submit>" |
| 365 "</form>"); | 372 "</form>"); |
| 366 | 373 |
| 367 StartSamlAndWaitForIdpPageLoad(); | 374 StartSamlAndWaitForIdpPageLoad(kUserEmail); |
| 368 | 375 |
| 369 SetSignFormField("Email", "fake_user"); | 376 SetSignFormField("Email", "fake_user"); |
| 370 SetSignFormField("Password", "fake_password"); | 377 SetSignFormField("Password", "fake_password"); |
| 371 SetSignFormField("Password1", "password1"); | 378 SetSignFormField("Password1", "password1"); |
| 372 ExecuteJsInSigninFrame("document.getElementById('IdPForm').submit();"); | 379 ExecuteJsInSigninFrame("document.getElementById('IdPForm').submit();"); |
| 373 | 380 |
| 374 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait(); | 381 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait(); |
| 375 | 382 |
| 376 // Either scraped password should be able to sign-in. | 383 // Either scraped password should be able to sign-in. |
| 377 SendConfirmPassword("password1"); | 384 SendConfirmPassword("password1"); |
| 378 content::WindowedNotificationObserver( | 385 content::WindowedNotificationObserver( |
| 379 chrome::NOTIFICATION_SESSION_STARTED, | 386 chrome::NOTIFICATION_SESSION_STARTED, |
| 380 content::NotificationService::AllSources()).Wait(); | 387 content::NotificationService::AllSources()).Wait(); |
| 381 } | 388 } |
| 382 | 389 |
| 383 // Tests the no password scraped flow. | 390 // Tests the no password scraped flow. |
| 384 IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedNone) { | 391 IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedNone) { |
| 385 fake_saml_idp()->set_html_template( | 392 fake_saml_idp()->set_html_template( |
| 386 "<form id=IdPForm method=post action=\"$Post\">" | 393 "<form id=IdPForm method=post action=\"$Post\">" |
| 387 "<input type=hidden name=RelayState value=\"$RelayState\">" | 394 "<input type=hidden name=RelayState value=\"$RelayState\">" |
| 388 "User: <input type=text id=Email name=Email>" | 395 "User: <input type=text id=Email name=Email>" |
| 389 "<input id=Submit type=submit>" | 396 "<input id=Submit type=submit>" |
| 390 "</form>"); | 397 "</form>"); |
| 391 | 398 |
| 392 StartSamlAndWaitForIdpPageLoad(); | 399 StartSamlAndWaitForIdpPageLoad(kUserEmail); |
| 393 | 400 |
| 394 SetSignFormField("Email", "fake_user"); | 401 SetSignFormField("Email", "fake_user"); |
| 395 ExecuteJsInSigninFrame("document.getElementById('IdPForm').submit();"); | 402 ExecuteJsInSigninFrame("document.getElementById('IdPForm').submit();"); |
| 396 | 403 |
| 397 OobeScreenWaiter(OobeDisplay::SCREEN_MESSAGE_BOX).Wait(); | 404 OobeScreenWaiter(OobeDisplay::SCREEN_MESSAGE_BOX).Wait(); |
| 398 JsExpect( | 405 JsExpect( |
| 399 "$('message-box-title').textContent == " | 406 "$('message-box-title').textContent == " |
| 400 "loadTimeData.getString('noPasswordWarningTitle')"); | 407 "loadTimeData.getString('noPasswordWarningTitle')"); |
| 401 } | 408 } |
| 402 | 409 |
| 410 // Types |alice@example.com| into the GAIA login form but then authenticates as |
| 411 // |bob@example.com| via SAML. Verifies that the logged-in user is correctly |
| 412 // identified as Bob. |
| 413 IN_PROC_BROWSER_TEST_F(SamlTest, UseAutenticatedUserEmailAddress) { |
| 414 // Type |alice@example.com| into the GAIA login form. |
| 415 StartSamlAndWaitForIdpPageLoad(kAnotherUserEmail); |
| 416 |
| 417 // Authenticate as bob@example.com via SAML (the |Email| provided here is |
| 418 // irrelevant - the authenticated user's e-mail address that FakeGAIA |
| 419 // reports was set via SetMergeSessionParams()). |
| 420 SetSignFormField("Email", "fake_user"); |
| 421 SetSignFormField("Password", "fake_password"); |
| 422 ExecuteJsInSigninFrame("document.getElementById('IdPForm').submit();"); |
| 423 |
| 424 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait(); |
| 425 |
| 426 SendConfirmPassword("fake_password"); |
| 427 content::WindowedNotificationObserver( |
| 428 chrome::NOTIFICATION_SESSION_STARTED, |
| 429 content::NotificationService::AllSources()).Wait(); |
| 430 const User* user = UserManager::Get()->GetActiveUser(); |
| 431 ASSERT_TRUE(user); |
| 432 EXPECT_EQ(kUserEmail, user->email()); |
| 433 } |
| 434 |
| 435 |
| 403 } // namespace chromeos | 436 } // namespace chromeos |
| OLD | NEW |