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 |