1 // Copyright 2014 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.
9 #include "base/bind_helpers.h"
10 #include "base/callback.h"
11 #include "base/command_line.h"
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/files/scoped_temp_dir.h"
15 #include "base/location.h"
16 #include "base/macros.h"
17 #include "base/memory/ref_counted.h"
18 #include "base/memory/scoped_ptr.h"
19 #include "base/path_service.h"
20 #include "base/run_loop.h"
21 #include "base/strings/string16.h"
22 #include "base/strings/string_util.h"
23 #include "base/strings/stringprintf.h"
24 #include "base/strings/utf_string_conversions.h"
25 #include "base/values.h"
26 #include "chrome/browser/chrome_notification_types.h"
27 #include "chrome/browser/chromeos/login/existing_user_controller.h"
28 #include "chrome/browser/chromeos/login/startup_utils.h"
29 #include "chrome/browser/chromeos/login/test/https_forwarder.h"
30 #include "chrome/browser/chromeos/login/test/oobe_base_test.h"
31 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
32 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
33 #include "chrome/browser/chromeos/login/ui/webui_login_display.h"
34 #include "chrome/browser/chromeos/login/wizard_controller.h"
35 #include "chrome/browser/chromeos/policy/device_policy_builder.h"
36 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
37 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
38 #include "chrome/browser/chromeos/profiles/profile_helper.h"
39 #include "chrome/browser/chromeos/settings/cros_settings.h"
40 #include "chrome/browser/policy/test/local_policy_test_server.h"
41 #include "chrome/browser/profiles/profile.h"
42 #include "chrome/browser/ui/webui/signin/inline_login_ui.h"
43 #include "chrome/common/chrome_constants.h"
44 #include "chrome/common/chrome_paths.h"
45 #include "chrome/common/chrome_switches.h"
46 #include "chrome/common/extensions/features/feature_channel.h"
47 #include "chrome/grit/generated_resources.h"
48 #include "chrome/test/base/in_process_browser_test.h"
49 #include "chromeos/chromeos_switches.h"
50 #include "chromeos/cryptohome/system_salt_getter.h"
51 #include "chromeos/dbus/cryptohome/key.pb.h"
52 #include "chromeos/dbus/cryptohome/rpc.pb.h"
53 #include "chromeos/dbus/cryptohome_client.h"
54 #include "chromeos/dbus/dbus_thread_manager.h"
55 #include "chromeos/dbus/fake_cryptohome_client.h"
56 #include "chromeos/dbus/fake_session_manager_client.h"
57 #include "chromeos/dbus/session_manager_client.h"
58 #include "chromeos/dbus/shill_manager_client.h"
59 #include "chromeos/login/auth/key.h"
60 #include "chromeos/settings/cros_settings_names.h"
61 #include "components/guest_view/browser/test_guest_view_manager.h"
62 #include "components/policy/core/browser/browser_policy_connector.h"
63 #include "components/policy/core/common/mock_configuration_policy_provider.h"
64 #include "components/policy/core/common/policy_map.h"
65 #include "components/policy/core/common/policy_switches.h"
66 #include "components/policy/core/common/policy_types.h"
67 #include "components/user_manager/user.h"
68 #include "components/user_manager/user_manager.h"
69 #include "content/public/browser/browser_thread.h"
70 #include "content/public/browser/render_frame_host.h"
71 #include "content/public/browser/web_contents.h"
72 #include "content/public/browser/web_contents_observer.h"
73 #include "content/public/test/browser_test_utils.h"
74 #include "content/public/test/test_utils.h"
75 #include "extensions/browser/guest_view/web_view/web_view_guest.h"
76 #include "google_apis/gaia/fake_gaia.h"
77 #include "google_apis/gaia/gaia_constants.h"
78 #include "google_apis/gaia/gaia_switches.h"
79 #include "google_apis/gaia/gaia_urls.h"
80 #include "net/base/url_util.h"
81 #include "net/cookies/canonical_cookie.h"
82 #include "net/cookies/cookie_monster.h"
83 #include "net/cookies/cookie_store.h"
84 #include "net/dns/mock_host_resolver.h"
85 #include "net/test/embedded_test_server/embedded_test_server.h"
86 #include "net/test/embedded_test_server/http_request.h"
87 #include "net/test/embedded_test_server/http_response.h"
88 #include "net/url_request/url_request_context.h"
89 #include "net/url_request/url_request_context_getter.h"
90 #include "policy/policy_constants.h"
91 #include "policy/proto/device_management_backend.pb.h"
92 #include "testing/gmock/include/gmock/gmock.h"
93 #include "testing/gtest/include/gtest/gtest.h"
94 #include "ui/base/l10n/l10n_util.h"
97 namespace em
= enterprise_management
;
99 using net::test_server::BasicHttpResponse
;
100 using net::test_server::HttpRequest
;
101 using net::test_server::HttpResponse
;
102 using testing::Return
;
109 const char kGAIASIDCookieName
[] = "SID";
110 const char kGAIALSIDCookieName
[] = "LSID";
112 const char kTestAuthSIDCookie1
[] = "fake-auth-SID-cookie-1";
113 const char kTestAuthSIDCookie2
[] = "fake-auth-SID-cookie-2";
114 const char kTestAuthLSIDCookie1
[] = "fake-auth-LSID-cookie-1";
115 const char kTestAuthLSIDCookie2
[] = "fake-auth-LSID-cookie-2";
117 const char kFirstSAMLUserEmail
[] = "bob@example.com";
118 const char kSecondSAMLUserEmail
[] = "alice@example.com";
119 const char kHTTPSAMLUserEmail
[] = "carol@example.com";
120 const char kNonSAMLUserEmail
[] = "dan@example.com";
121 const char kDifferentDomainSAMLUserEmail
[] = "eve@example.test";
123 const char kIdPHost
[] = "login.example.com";
124 const char kAdditionalIdPHost
[] = "login2.example.com";
126 const char kSAMLIdPCookieName
[] = "saml";
127 const char kSAMLIdPCookieValue1
[] = "value-1";
128 const char kSAMLIdPCookieValue2
[] = "value-2";
130 const char kRelayState
[] = "RelayState";
132 const char kTestUserinfoToken
[] = "fake-userinfo-token";
133 const char kTestRefreshToken
[] = "fake-refresh-token";
134 const char kPolicy
[] = "{\"managed_users\": [\"*\"]}";
136 // FakeSamlIdp serves IdP auth form and the form submission. The form is
137 // served with the template's RelayState placeholder expanded to the real
138 // RelayState parameter from request. The form submission redirects back to
139 // FakeGaia with the same RelayState.
145 void SetUp(const std::string
& base_path
, const GURL
& gaia_url
);
147 void SetLoginHTMLTemplate(const std::string
& template_file
);
148 void SetLoginAuthHTMLTemplate(const std::string
& template_file
);
149 void SetRefreshURL(const GURL
& refresh_url
);
150 void SetCookieValue(const std::string
& cookie_value
);
152 scoped_ptr
<HttpResponse
> HandleRequest(const HttpRequest
& request
);
155 scoped_ptr
<HttpResponse
> BuildHTMLResponse(const std::string
& html_template
,
156 const std::string
& relay_state
,
157 const std::string
& next_path
);
159 base::FilePath html_template_dir_
;
161 std::string login_path_
;
162 std::string login_auth_path_
;
164 std::string login_html_template_
;
165 std::string login_auth_html_template_
;
166 GURL gaia_assertion_url_
;
168 std::string cookie_value_
;
170 DISALLOW_COPY_AND_ASSIGN(FakeSamlIdp
);
173 FakeSamlIdp::FakeSamlIdp() {
176 FakeSamlIdp::~FakeSamlIdp() {
179 void FakeSamlIdp::SetUp(const std::string
& base_path
, const GURL
& gaia_url
) {
180 base::FilePath test_data_dir
;
181 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA
, &test_data_dir
));
182 html_template_dir_
= test_data_dir
.Append("login");
184 login_path_
= base_path
;
185 login_auth_path_
= base_path
+ "Auth";
186 gaia_assertion_url_
= gaia_url
.Resolve("/SSO");
189 void FakeSamlIdp::SetLoginHTMLTemplate(const std::string
& template_file
) {
190 EXPECT_TRUE(base::ReadFileToString(
191 html_template_dir_
.Append(template_file
),
192 &login_html_template_
));
195 void FakeSamlIdp::SetLoginAuthHTMLTemplate(const std::string
& template_file
) {
196 EXPECT_TRUE(base::ReadFileToString(
197 html_template_dir_
.Append(template_file
),
198 &login_auth_html_template_
));
201 void FakeSamlIdp::SetRefreshURL(const GURL
& refresh_url
) {
202 refresh_url_
= refresh_url
;
205 void FakeSamlIdp::SetCookieValue(const std::string
& cookie_value
) {
206 cookie_value_
= cookie_value
;
209 scoped_ptr
<HttpResponse
> FakeSamlIdp::HandleRequest(
210 const HttpRequest
& request
) {
211 // The scheme and host of the URL is actually not important but required to
212 // get a valid GURL in order to parse |request.relative_url|.
213 GURL request_url
= GURL("http://localhost").Resolve(request
.relative_url
);
214 std::string request_path
= request_url
.path();
216 if (request_path
== login_path_
) {
217 std::string relay_state
;
218 net::GetValueForKeyInQuery(request_url
, kRelayState
, &relay_state
);
219 return BuildHTMLResponse(login_html_template_
,
224 if (request_path
!= login_auth_path_
) {
225 // Request not understood.
226 return scoped_ptr
<HttpResponse
>();
229 std::string relay_state
;
230 FakeGaia::GetQueryParameter(request
.content
, kRelayState
, &relay_state
);
231 GURL redirect_url
= gaia_assertion_url_
;
233 if (!login_auth_html_template_
.empty()) {
234 return BuildHTMLResponse(login_auth_html_template_
,
236 redirect_url
.spec());
239 redirect_url
= net::AppendQueryParameter(
240 redirect_url
, "SAMLResponse", "fake_response");
241 redirect_url
= net::AppendQueryParameter(
242 redirect_url
, kRelayState
, relay_state
);
244 scoped_ptr
<BasicHttpResponse
> http_response(new BasicHttpResponse());
245 http_response
->set_code(net::HTTP_TEMPORARY_REDIRECT
);
246 http_response
->AddCustomHeader("Location", redirect_url
.spec());
247 http_response
->AddCustomHeader(
249 base::StringPrintf("saml=%s", cookie_value_
.c_str()));
250 return http_response
.Pass();
253 scoped_ptr
<HttpResponse
> FakeSamlIdp::BuildHTMLResponse(
254 const std::string
& html_template
,
255 const std::string
& relay_state
,
256 const std::string
& next_path
) {
257 std::string response_html
= html_template
;
258 base::ReplaceSubstringsAfterOffset(
259 &response_html
, 0, "$RelayState", relay_state
);
260 base::ReplaceSubstringsAfterOffset(
261 &response_html
, 0, "$Post", next_path
);
262 base::ReplaceSubstringsAfterOffset(
263 &response_html
, 0, "$Refresh", refresh_url_
.spec());
265 scoped_ptr
<BasicHttpResponse
> http_response(new BasicHttpResponse());
266 http_response
->set_code(net::HTTP_OK
);
267 http_response
->set_content(response_html
);
268 http_response
->set_content_type("text/html");
270 return http_response
.Pass();
273 // A FakeCryptohomeClient that stores the salted and hashed secret passed to
275 class SecretInterceptingFakeCryptohomeClient
: public FakeCryptohomeClient
{
277 SecretInterceptingFakeCryptohomeClient();
279 void MountEx(const cryptohome::AccountIdentifier
& id
,
280 const cryptohome::AuthorizationRequest
& auth
,
281 const cryptohome::MountRequest
& request
,
282 const ProtobufMethodCallback
& callback
) override
;
284 const std::string
& salted_hashed_secret() { return salted_hashed_secret_
; }
287 std::string salted_hashed_secret_
;
289 DISALLOW_COPY_AND_ASSIGN(SecretInterceptingFakeCryptohomeClient
);
292 SecretInterceptingFakeCryptohomeClient::
293 SecretInterceptingFakeCryptohomeClient() {
296 void SecretInterceptingFakeCryptohomeClient::MountEx(
297 const cryptohome::AccountIdentifier
& id
,
298 const cryptohome::AuthorizationRequest
& auth
,
299 const cryptohome::MountRequest
& request
,
300 const ProtobufMethodCallback
& callback
) {
301 salted_hashed_secret_
= auth
.key().secret();
302 FakeCryptohomeClient::MountEx(id
, auth
, request
, callback
);
307 class SamlTest
: public OobeBaseTest
{
309 SamlTest() : cryptohome_client_(new SecretInterceptingFakeCryptohomeClient
) {
310 set_initialize_fake_merge_session(false);
312 ~SamlTest() override
{}
314 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
315 command_line
->AppendSwitch(switches::kOobeSkipPostLogin
);
317 const GURL gaia_url
= gaia_https_forwarder_
.GetURLForSSLHost("");
318 const GURL saml_idp_url
= saml_https_forwarder_
.GetURLForSSLHost("SAML");
319 fake_saml_idp_
.SetUp(saml_idp_url
.path(), gaia_url
);
320 fake_gaia_
->RegisterSamlUser(kFirstSAMLUserEmail
, saml_idp_url
);
321 fake_gaia_
->RegisterSamlUser(kSecondSAMLUserEmail
, saml_idp_url
);
322 fake_gaia_
->RegisterSamlUser(
324 embedded_test_server()->base_url().Resolve("/SAML"));
325 fake_gaia_
->RegisterSamlUser(kDifferentDomainSAMLUserEmail
, saml_idp_url
);
327 OobeBaseTest::SetUpCommandLine(command_line
);
330 void SetUpInProcessBrowserTestFixture() override
{
331 DBusThreadManager::GetSetterForTesting()->SetCryptohomeClient(
332 scoped_ptr
<CryptohomeClient
>(cryptohome_client_
));
334 OobeBaseTest::SetUpInProcessBrowserTestFixture();
337 void SetUpOnMainThread() override
{
338 fake_gaia_
->SetFakeMergeSessionParams(
339 kFirstSAMLUserEmail
, kTestAuthSIDCookie1
, kTestAuthLSIDCookie1
);
341 embedded_test_server()->RegisterRequestHandler(base::Bind(
342 &FakeSamlIdp::HandleRequest
, base::Unretained(&fake_saml_idp_
)));
344 OobeBaseTest::SetUpOnMainThread();
347 void SetupAuthFlowChangeListener() {
348 ASSERT_TRUE(content::ExecuteScript(
349 GetLoginUI()->GetWebContents(),
350 "$('gaia-signin').gaiaAuthHost_.addEventListener('authFlowChange',"
352 "$('gaia-signin').gaiaAuthHost_.removeEventListener("
353 "'authFlowChange', f);"
354 "window.domAutomationController.setAutomationId(0);"
355 "window.domAutomationController.send("
356 "$('gaia-signin').isSAML() ? 'SamlLoaded' : 'GaiaLoaded');"
360 virtual void StartSamlAndWaitForIdpPageLoad(const std::string
& gaia_email
) {
361 WaitForSigninScreen();
363 SetupAuthFlowChangeListener();
365 content::DOMMessageQueue message_queue
; // Start observe before SAML.
366 GetLoginDisplay()->ShowSigninScreenForCreds(gaia_email
, "");
369 ASSERT_TRUE(message_queue
.WaitForMessage(&message
));
370 EXPECT_EQ("\"SamlLoaded\"", message
);
373 void SendConfirmPassword(const std::string
& password_to_confirm
) {
375 "$('confirm-password-input').value='$Password';"
376 "$('confirm-password').onConfirmPassword_();";
377 base::ReplaceSubstringsAfterOffset(
378 &js
, 0, "$Password", password_to_confirm
);
379 ASSERT_TRUE(content::ExecuteScript(GetLoginUI()->GetWebContents(), js
));
382 std::string
WaitForAndGetFatalErrorMessage() {
383 OobeScreenWaiter(OobeDisplay::SCREEN_FATAL_ERROR
).Wait();
384 std::string message_element
= "$('fatal-error-card')";
385 std::string error_message
;
386 if (!content::ExecuteScriptAndExtractString(
387 GetLoginUI()->GetWebContents(),
388 "window.domAutomationController.send(" + message_element
+
393 return error_message
;
396 FakeSamlIdp
* fake_saml_idp() { return &fake_saml_idp_
; }
399 void InitHttpsForwarders() override
{
400 ASSERT_TRUE(saml_https_forwarder_
.Initialize(
401 kIdPHost
, embedded_test_server()->base_url()));
402 OobeBaseTest::InitHttpsForwarders();
405 HTTPSForwarder saml_https_forwarder_
;
407 SecretInterceptingFakeCryptohomeClient
* cryptohome_client_
;
410 FakeSamlIdp fake_saml_idp_
;
412 DISALLOW_COPY_AND_ASSIGN(SamlTest
);
415 // Tests that signin frame should have 'saml' class and 'cancel' button is
416 // visible when SAML IdP page is loaded. And 'cancel' button goes back to
419 // Times out on CrOS MSAN. https://crbug.com/504141
420 #if defined(MEMORY_SANITIZER)
421 #define MAYBE_SamlUI DISABLED_SamlUI
423 #define MAYBE_SamlUI SamlUI
425 IN_PROC_BROWSER_TEST_F(SamlTest
, MAYBE_SamlUI
) {
426 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
427 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail
);
429 // Saml flow UI expectations.
430 JsExpect("$('gaia-signin').classList.contains('full-width')");
431 JsExpect("!$('saml-notice-container').hidden");
432 std::string js
= "$('saml-notice-message').textContent.indexOf('$Host') > -1";
433 base::ReplaceSubstringsAfterOffset(&js
, 0, "$Host", kIdPHost
);
436 SetupAuthFlowChangeListener();
438 // Click on 'cancel'.
439 content::DOMMessageQueue message_queue
; // Observe before 'cancel'.
440 ASSERT_TRUE(content::ExecuteScript(GetLoginUI()->GetWebContents(),
441 "$('close-button-item').click();"));
443 // Auth flow should change back to Gaia.
446 ASSERT_TRUE(message_queue
.WaitForMessage(&message
));
447 } while (message
!= "\"GaiaLoaded\"");
449 // Saml flow is gone.
450 JsExpect("!$('gaia-signin').classList.contains('full-width')");
453 // Tests the sign-in flow when the credentials passing API is used.
454 IN_PROC_BROWSER_TEST_F(SamlTest
, CredentialPassingAPI
) {
455 fake_saml_idp()->SetLoginHTMLTemplate("saml_api_login.html");
456 fake_saml_idp()->SetLoginAuthHTMLTemplate("saml_api_login_auth.html");
457 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail
);
459 content::WindowedNotificationObserver
session_start_waiter(
460 chrome::NOTIFICATION_SESSION_STARTED
,
461 content::NotificationService::AllSources());
463 // Fill-in the SAML IdP form and submit.
464 SetSignFormField("Email", "fake_user");
465 SetSignFormField("Dummy", "not_the_password");
466 SetSignFormField("Password", "actual_password");
467 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
469 // Login should finish login and a session should start.
470 session_start_waiter
.Wait();
472 // Regression test for http://crbug.com/490737: Verify that the user's actual
473 // password was used, not the contents of the first type=password input field
474 // found on the page.
475 Key
key("actual_password");
476 key
.Transform(Key::KEY_TYPE_SALTED_SHA256_TOP_HALF
,
477 SystemSaltGetter::ConvertRawSaltToHexString(
478 FakeCryptohomeClient::GetStubSystemSalt()));
479 EXPECT_EQ(key
.GetSecret(), cryptohome_client_
->salted_hashed_secret());
482 // Tests the single password scraped flow.
483 IN_PROC_BROWSER_TEST_F(SamlTest
, ScrapedSingle
) {
484 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
485 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail
);
487 // Fill-in the SAML IdP form and submit.
488 SetSignFormField("Email", "fake_user");
489 SetSignFormField("Password", "fake_password");
490 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
492 // Lands on confirm password screen.
493 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD
).Wait();
495 // Entering an unknown password should go back to the confirm password screen.
496 SendConfirmPassword("wrong_password");
497 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD
).Wait();
499 // Entering a known password should finish login and start session.
500 content::WindowedNotificationObserver
session_start_waiter(
501 chrome::NOTIFICATION_SESSION_STARTED
,
502 content::NotificationService::AllSources());
503 SendConfirmPassword("fake_password");
504 session_start_waiter
.Wait();
507 // Tests password scraping from a dynamically created password field.
508 IN_PROC_BROWSER_TEST_F(SamlTest
, ScrapedDynamic
) {
509 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
510 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail
);
512 ExecuteJsInSigninFrame(
514 "var newPassInput = document.createElement('input');"
515 "newPassInput.id = 'DynamicallyCreatedPassword';"
516 "newPassInput.type = 'password';"
517 "newPassInput.name = 'Password';"
518 "document.forms[0].appendChild(newPassInput);"
521 // Fill-in the SAML IdP form and submit.
522 SetSignFormField("Email", "fake_user");
523 SetSignFormField("DynamicallyCreatedPassword", "fake_password");
524 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
526 // Lands on confirm password screen.
527 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD
).Wait();
529 // Entering an unknown password should go back to the confirm password screen.
530 SendConfirmPassword("wrong_password");
531 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD
).Wait();
533 // Entering a known password should finish login and start session.
534 content::WindowedNotificationObserver
session_start_waiter(
535 chrome::NOTIFICATION_SESSION_STARTED
,
536 content::NotificationService::AllSources());
537 SendConfirmPassword("fake_password");
538 session_start_waiter
.Wait();
541 // Tests the multiple password scraped flow.
542 IN_PROC_BROWSER_TEST_F(SamlTest
, ScrapedMultiple
) {
543 fake_saml_idp()->SetLoginHTMLTemplate("saml_login_two_passwords.html");
545 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail
);
547 SetSignFormField("Email", "fake_user");
548 SetSignFormField("Password", "fake_password");
549 SetSignFormField("Password1", "password1");
550 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
552 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD
).Wait();
554 // Either scraped password should be able to sign-in.
555 content::WindowedNotificationObserver
session_start_waiter(
556 chrome::NOTIFICATION_SESSION_STARTED
,
557 content::NotificationService::AllSources());
558 SendConfirmPassword("password1");
559 session_start_waiter
.Wait();
562 // Tests the no password scraped flow.
563 IN_PROC_BROWSER_TEST_F(SamlTest
, ScrapedNone
) {
564 fake_saml_idp()->SetLoginHTMLTemplate("saml_login_no_passwords.html");
566 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail
);
568 SetSignFormField("Email", "fake_user");
569 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
571 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_LOGIN_FATAL_ERROR_NO_PASSWORD
),
572 WaitForAndGetFatalErrorMessage());
575 // Types |bob@example.com| into the GAIA login form but then authenticates as
576 // |alice@example.com| via SAML. Verifies that the logged-in user is correctly
577 // identified as Alice.
578 IN_PROC_BROWSER_TEST_F(SamlTest
, UseAutenticatedUserEmailAddress
) {
579 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
580 // Type |bob@example.com| into the GAIA login form.
581 StartSamlAndWaitForIdpPageLoad(kSecondSAMLUserEmail
);
583 // Authenticate as alice@example.com via SAML (the |Email| provided here is
584 // irrelevant - the authenticated user's e-mail address that FakeGAIA
585 // reports was set via |SetFakeMergeSessionParams|.
586 SetSignFormField("Email", "fake_user");
587 SetSignFormField("Password", "fake_password");
588 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
590 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD
).Wait();
592 content::WindowedNotificationObserver
session_start_waiter(
593 chrome::NOTIFICATION_SESSION_STARTED
,
594 content::NotificationService::AllSources());
595 SendConfirmPassword("fake_password");
596 session_start_waiter
.Wait();
597 const user_manager::User
* user
=
598 user_manager::UserManager::Get()->GetActiveUser();
600 EXPECT_EQ(kFirstSAMLUserEmail
, user
->email());
603 // Verifies that if the authenticated user's e-mail address cannot be retrieved,
604 // an error message is shown.
605 IN_PROC_BROWSER_TEST_F(SamlTest
, FailToRetrieveAutenticatedUserEmailAddress
) {
606 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
607 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail
);
609 fake_gaia_
->SetFakeMergeSessionParams("", kTestAuthSIDCookie1
,
610 kTestAuthLSIDCookie1
);
611 SetSignFormField("Email", "fake_user");
612 SetSignFormField("Password", "fake_password");
613 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
615 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_LOGIN_FATAL_ERROR_NO_ACCOUNT_DETAILS
),
616 WaitForAndGetFatalErrorMessage());
619 // Tests the password confirm flow: show error on the first failure and
620 // fatal error on the second failure.
621 IN_PROC_BROWSER_TEST_F(SamlTest
, PasswordConfirmFlow
) {
622 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
623 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail
);
625 // Fill-in the SAML IdP form and submit.
626 SetSignFormField("Email", "fake_user");
627 SetSignFormField("Password", "fake_password");
628 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
630 // Lands on confirm password screen with no error message.
631 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD
).Wait();
632 JsExpect("!$('confirm-password').classList.contains('error')");
634 // Enter an unknown password for the first time should go back to confirm
635 // password screen with error message.
636 SendConfirmPassword("wrong_password");
637 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD
).Wait();
638 JsExpect("$('confirm-password').classList.contains('error')");
640 // Enter an unknown password 2nd time should go back fatal error message.
641 SendConfirmPassword("wrong_password");
643 l10n_util::GetStringUTF8(IDS_LOGIN_FATAL_ERROR_PASSWORD_VERIFICATION
),
644 WaitForAndGetFatalErrorMessage());
647 // Verifies that when the login flow redirects from one host to another, the
648 // notice shown to the user is updated. This guards against regressions of
649 // http://crbug.com/447818.
650 IN_PROC_BROWSER_TEST_F(SamlTest
, NoticeUpdatedOnRedirect
) {
651 // Start another https server at |kAdditionalIdPHost|.
652 HTTPSForwarder saml_https_forwarder_2
;
653 ASSERT_TRUE(saml_https_forwarder_2
.Initialize(
654 kAdditionalIdPHost
, embedded_test_server()->base_url()));
656 // Make the login flow redirect to |kAdditionalIdPHost|.
657 fake_saml_idp()->SetLoginHTMLTemplate("saml_login_instant_meta_refresh.html");
658 fake_saml_idp()->SetRefreshURL(
659 saml_https_forwarder_2
.GetURLForSSLHost("simple.html"));
660 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail
);
662 // Wait until the notice shown to the user is updated to contain
663 // |kAdditionalIdPHost|.
665 "var sendIfHostFound = function() {"
667 " $('saml-notice-message').textContent.indexOf('$Host') > -1;"
669 " window.domAutomationController.send(true);"
672 "var processEventsAndSendIfHostFound = function() {"
673 " window.setTimeout(function() {"
674 " if (sendIfHostFound()) {"
675 " $('gaia-signin').gaiaAuthHost_.removeEventListener("
676 " 'authDomainChange',"
677 " processEventsAndSendIfHostFound);"
681 "if (!sendIfHostFound()) {"
682 " $('gaia-signin').gaiaAuthHost_.addEventListener("
683 " 'authDomainChange',"
684 " processEventsAndSendIfHostFound);"
686 base::ReplaceSubstringsAfterOffset(&js
, 0, "$Host", kAdditionalIdPHost
);
688 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
689 GetLoginUI()->GetWebContents(), js
, &dummy
));
691 // Verify that the notice is visible.
692 JsExpect("!$('saml-notice-container').hidden");
695 // Verifies that when GAIA attempts to redirect to a SAML IdP served over http,
696 // not https, the redirect is blocked and an error message is shown.
697 IN_PROC_BROWSER_TEST_F(SamlTest
, HTTPRedirectDisallowed
) {
698 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
700 WaitForSigninScreen();
701 GetLoginDisplay()->ShowSigninScreenForCreds(kHTTPSAMLUserEmail
, "");
703 const GURL url
= embedded_test_server()->base_url().Resolve("/SAML");
704 EXPECT_EQ(l10n_util::GetStringFUTF8(
705 IDS_LOGIN_FATAL_ERROR_TEXT_INSECURE_URL
,
706 base::UTF8ToUTF16(url
.spec())),
707 WaitForAndGetFatalErrorMessage());
710 // Verifies that when GAIA attempts to redirect to a page served over http, not
711 // https, via an HTML meta refresh, the redirect is blocked and an error message
712 // is shown. This guards against regressions of http://crbug.com/359515.
713 IN_PROC_BROWSER_TEST_F(SamlTest
, MetaRefreshToHTTPDisallowed
) {
714 const GURL url
= embedded_test_server()->base_url().Resolve("/SSO");
715 fake_saml_idp()->SetLoginHTMLTemplate("saml_login_instant_meta_refresh.html");
716 fake_saml_idp()->SetRefreshURL(url
);
718 WaitForSigninScreen();
719 GetLoginDisplay()->ShowSigninScreenForCreds(kFirstSAMLUserEmail
, "");
721 EXPECT_EQ(l10n_util::GetStringFUTF8(
722 IDS_LOGIN_FATAL_ERROR_TEXT_INSECURE_URL
,
723 base::UTF8ToUTF16(url
.spec())),
724 WaitForAndGetFatalErrorMessage());
727 class SAMLEnrollmentTest
: public SamlTest
,
728 public content::WebContentsObserver
{
730 SAMLEnrollmentTest();
731 ~SAMLEnrollmentTest() override
;
734 void SetUp() override
;
735 void SetUpCommandLine(base::CommandLine
* command_line
) override
;
736 void SetUpOnMainThread() override
;
737 void StartSamlAndWaitForIdpPageLoad(const std::string
& gaia_email
) override
;
739 // content::WebContentsObserver:
740 void DidFinishLoad(content::RenderFrameHost
* render_frame_host
,
741 const GURL
& validated_url
) override
;
743 void WaitForEnrollmentSuccess();
744 guest_view::TestGuestViewManager
* GetGuestViewManager();
745 content::WebContents
* GetEnrollmentContents();
748 scoped_ptr
<policy::LocalPolicyTestServer
> test_server_
;
749 base::ScopedTempDir temp_dir_
;
751 scoped_ptr
<base::RunLoop
> run_loop_
;
753 guest_view::TestGuestViewManagerFactory guest_view_manager_factory_
;
755 DISALLOW_COPY_AND_ASSIGN(SAMLEnrollmentTest
);
758 SAMLEnrollmentTest::SAMLEnrollmentTest() {
759 guest_view::GuestViewManager::set_factory_for_testing(
760 &guest_view_manager_factory_
);
761 gaia_frame_parent_
= "oauth-enroll-auth-view";
764 SAMLEnrollmentTest::~SAMLEnrollmentTest() {
767 void SAMLEnrollmentTest::SetUp() {
768 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
769 const base::FilePath policy_file
=
770 temp_dir_
.path().AppendASCII("policy.json");
771 ASSERT_EQ(static_cast<int>(strlen(kPolicy
)),
772 base::WriteFile(policy_file
, kPolicy
, strlen(kPolicy
)));
774 test_server_
.reset(new policy::LocalPolicyTestServer(policy_file
));
775 ASSERT_TRUE(test_server_
->Start());
780 void SAMLEnrollmentTest::SetUpCommandLine(base::CommandLine
* command_line
) {
781 command_line
->AppendSwitchASCII(policy::switches::kDeviceManagementUrl
,
782 test_server_
->GetServiceURL().spec());
783 command_line
->AppendSwitch(policy::switches::kDisablePolicyKeyVerification
);
785 SamlTest::SetUpCommandLine(command_line
);
788 void SAMLEnrollmentTest::SetUpOnMainThread() {
789 FakeGaia::AccessTokenInfo token_info
;
790 token_info
.token
= kTestUserinfoToken
;
791 token_info
.scopes
.insert(GaiaConstants::kDeviceManagementServiceOAuth
);
792 token_info
.scopes
.insert(GaiaConstants::kOAuthWrapBridgeUserInfoScope
);
793 token_info
.audience
= GaiaUrls::GetInstance()->oauth2_chrome_client_id();
794 token_info
.email
= kFirstSAMLUserEmail
;
795 fake_gaia_
->IssueOAuthToken(kTestRefreshToken
, token_info
);
797 SamlTest::SetUpOnMainThread();
800 void SAMLEnrollmentTest::StartSamlAndWaitForIdpPageLoad(
801 const std::string
& gaia_email
) {
802 WaitForSigninScreen();
803 run_loop_
.reset(new base::RunLoop
);
804 ExistingUserController::current_controller()->OnStartEnterpriseEnrollment();
805 while (!GetEnrollmentContents()) {
806 GetGuestViewManager()->WaitForNextGuestCreated();
808 Observe(GetEnrollmentContents());
811 SetSignFormField("identifier", gaia_email
);
813 run_loop_
.reset(new base::RunLoop
);
814 ExecuteJsInSigninFrame("document.getElementById('nextButton').click();");
818 void SAMLEnrollmentTest::DidFinishLoad(
819 content::RenderFrameHost
* render_frame_host
,
820 const GURL
& validated_url
) {
821 const GURL origin
= validated_url
.GetOrigin();
822 if (origin
!= gaia_https_forwarder_
.GetURLForSSLHost(std::string()) &&
823 origin
!= saml_https_forwarder_
.GetURLForSSLHost(std::string())) {
827 // The GAIA or SAML IdP login form finished loading.
832 // Waits until the class |oauth-enroll-state-success| becomes set for the
833 // enrollment screen, indicating enrollment success.
834 void SAMLEnrollmentTest::WaitForEnrollmentSuccess() {
836 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
837 GetLoginUI()->GetWebContents(),
838 "var enrollmentScreen = document.getElementById('oauth-enrollment');"
839 "function SendReplyIfEnrollmentDone() {"
840 " if (!enrollmentScreen.classList.contains("
841 " 'oauth-enroll-state-success')) {"
844 " domAutomationController.send(true);"
845 " observer.disconnect();"
848 "var observer = new MutationObserver(SendReplyIfEnrollmentDone);"
849 "if (!SendReplyIfEnrollmentDone()) {"
850 " var options = { attributes: true, attributeFilter: [ 'class' ] };"
851 " observer.observe(enrollmentScreen, options);"
856 guest_view::TestGuestViewManager
* SAMLEnrollmentTest::GetGuestViewManager() {
857 using namespace guest_view
;
858 return static_cast<TestGuestViewManager
*>(
859 TestGuestViewManager::FromBrowserContext(
860 ProfileHelper::GetSigninProfile()));
863 content::WebContents
* SAMLEnrollmentTest::GetEnrollmentContents() {
864 content::RenderFrameHost
* frame_host
= InlineLoginUI::GetAuthFrame(
865 GetLoginUI()->GetWebContents(), GURL(), gaia_frame_parent_
);
868 return content::WebContents::FromRenderFrameHost(frame_host
);
871 IN_PROC_BROWSER_TEST_F(SAMLEnrollmentTest
, WithoutCredentialsPassingAPI
) {
872 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
873 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail
);
875 // Fill-in the SAML IdP form and submit.
876 SetSignFormField("Email", "fake_user");
877 SetSignFormField("Password", "fake_password");
878 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
880 WaitForEnrollmentSuccess();
883 IN_PROC_BROWSER_TEST_F(SAMLEnrollmentTest
, WithCredentialsPassingAPI
) {
884 fake_saml_idp()->SetLoginHTMLTemplate("saml_api_login.html");
885 fake_saml_idp()->SetLoginAuthHTMLTemplate("saml_api_login_auth.html");
886 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail
);
888 // Fill-in the SAML IdP form and submit.
889 SetSignFormField("Email", "fake_user");
890 SetSignFormField("Password", "fake_password");
891 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
893 WaitForEnrollmentSuccess();
896 class SAMLPolicyTest
: public SamlTest
{
899 ~SAMLPolicyTest() override
;
902 void SetUpInProcessBrowserTestFixture() override
;
903 void SetUpOnMainThread() override
;
905 void SetSAMLOfflineSigninTimeLimitPolicy(int limit
);
906 void EnableTransferSAMLCookiesPolicy();
908 void ShowGAIALoginForm();
909 void LogInWithSAML(const std::string
& user_id
,
910 const std::string
& auth_sid_cookie
,
911 const std::string
& auth_lsid_cookie
);
913 std::string
GetCookieValue(const std::string
& name
);
918 void GetCookiesOnIOThread(
919 const scoped_refptr
<net::URLRequestContextGetter
>& request_context
,
920 const base::Closure
& callback
);
921 void StoreCookieList(const base::Closure
& callback
,
922 const net::CookieList
& cookie_list
);
924 policy::DevicePolicyCrosTestHelper test_helper_
;
926 // FakeDBusThreadManager uses FakeSessionManagerClient.
927 FakeSessionManagerClient
* fake_session_manager_client_
;
928 policy::DevicePolicyBuilder
* device_policy_
;
930 policy::MockConfigurationPolicyProvider provider_
;
932 net::CookieList cookie_list_
;
935 DISALLOW_COPY_AND_ASSIGN(SAMLPolicyTest
);
938 SAMLPolicyTest::SAMLPolicyTest()
939 : fake_session_manager_client_(new FakeSessionManagerClient
),
940 device_policy_(test_helper_
.device_policy()) {
943 SAMLPolicyTest::~SAMLPolicyTest() {
946 void SAMLPolicyTest::SetUpInProcessBrowserTestFixture() {
947 DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient(
948 scoped_ptr
<SessionManagerClient
>(fake_session_manager_client_
));
950 SamlTest::SetUpInProcessBrowserTestFixture();
952 // Initialize device policy.
953 test_helper_
.InstallOwnerKey();
954 test_helper_
.MarkAsEnterpriseOwned();
955 device_policy_
->SetDefaultSigningKey();
956 device_policy_
->Build();
957 fake_session_manager_client_
->set_device_policy(device_policy_
->GetBlob());
958 fake_session_manager_client_
->OnPropertyChangeComplete(true);
960 // Initialize user policy.
961 EXPECT_CALL(provider_
, IsInitializationComplete(_
))
962 .WillRepeatedly(Return(true));
963 policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_
);
966 void SAMLPolicyTest::SetUpOnMainThread() {
967 SamlTest::SetUpOnMainThread();
969 // Pretend that the test users' OAuth tokens are valid.
970 user_manager::UserManager::Get()->SaveUserOAuthStatus(
971 kFirstSAMLUserEmail
, user_manager::User::OAUTH2_TOKEN_STATUS_VALID
);
972 user_manager::UserManager::Get()->SaveUserOAuthStatus(
973 kNonSAMLUserEmail
, user_manager::User::OAUTH2_TOKEN_STATUS_VALID
);
974 user_manager::UserManager::Get()->SaveUserOAuthStatus(
975 kDifferentDomainSAMLUserEmail
,
976 user_manager::User::OAUTH2_TOKEN_STATUS_VALID
);
978 // Set up fake networks.
979 DBusThreadManager::Get()
980 ->GetShillManagerClient()
982 ->SetupDefaultEnvironment();
985 void SAMLPolicyTest::SetSAMLOfflineSigninTimeLimitPolicy(int limit
) {
986 policy::PolicyMap user_policy
;
987 user_policy
.Set(policy::key::kSAMLOfflineSigninTimeLimit
,
988 policy::POLICY_LEVEL_MANDATORY
,
989 policy::POLICY_SCOPE_USER
,
990 policy::POLICY_SOURCE_CLOUD
,
991 new base::FundamentalValue(limit
),
993 provider_
.UpdateChromePolicy(user_policy
);
994 base::RunLoop().RunUntilIdle();
997 void SAMLPolicyTest::EnableTransferSAMLCookiesPolicy() {
998 em::ChromeDeviceSettingsProto
& proto(device_policy_
->payload());
999 proto
.mutable_saml_settings()->set_transfer_saml_cookies(true);
1001 base::RunLoop run_loop
;
1002 scoped_ptr
<CrosSettings::ObserverSubscription
> observer
=
1003 CrosSettings::Get()->AddSettingsObserver(
1004 kAccountsPrefTransferSAMLCookies
,
1005 run_loop
.QuitClosure());
1006 device_policy_
->SetDefaultSigningKey();
1007 device_policy_
->Build();
1008 fake_session_manager_client_
->set_device_policy(device_policy_
->GetBlob());
1009 fake_session_manager_client_
->OnPropertyChangeComplete(true);
1013 void SAMLPolicyTest::ShowGAIALoginForm() {
1014 login_screen_load_observer_
->Wait();
1015 ASSERT_TRUE(content::ExecuteScript(
1016 GetLoginUI()->GetWebContents(),
1017 "$('gaia-signin').gaiaAuthHost_.addEventListener('ready', function() {"
1018 " window.domAutomationController.setAutomationId(0);"
1019 " window.domAutomationController.send('ready');"
1021 "$('add-user-button').click();"));
1022 content::DOMMessageQueue message_queue
;
1023 std::string message
;
1024 ASSERT_TRUE(message_queue
.WaitForMessage(&message
));
1025 EXPECT_EQ("\"ready\"", message
);
1028 void SAMLPolicyTest::LogInWithSAML(const std::string
& user_id
,
1029 const std::string
& auth_sid_cookie
,
1030 const std::string
& auth_lsid_cookie
) {
1031 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
1032 StartSamlAndWaitForIdpPageLoad(user_id
);
1034 fake_gaia_
->SetFakeMergeSessionParams(user_id
, auth_sid_cookie
,
1036 SetSignFormField("Email", "fake_user");
1037 SetSignFormField("Password", "fake_password");
1038 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
1040 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD
).Wait();
1042 content::WindowedNotificationObserver
session_start_waiter(
1043 chrome::NOTIFICATION_SESSION_STARTED
,
1044 content::NotificationService::AllSources());
1045 SendConfirmPassword("fake_password");
1046 session_start_waiter
.Wait();
1049 std::string
SAMLPolicyTest::GetCookieValue(const std::string
& name
) {
1050 for (net::CookieList::const_iterator it
= cookie_list_
.begin();
1051 it
!= cookie_list_
.end(); ++it
) {
1052 if (it
->Name() == name
)
1055 return std::string();
1058 void SAMLPolicyTest::GetCookies() {
1059 Profile
* profile
= chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(
1060 user_manager::UserManager::Get()->GetActiveUser());
1061 ASSERT_TRUE(profile
);
1062 base::RunLoop run_loop
;
1063 content::BrowserThread::PostTask(
1064 content::BrowserThread::IO
,
1066 base::Bind(&SAMLPolicyTest::GetCookiesOnIOThread
,
1067 base::Unretained(this),
1068 scoped_refptr
<net::URLRequestContextGetter
>(
1069 profile
->GetRequestContext()),
1070 run_loop
.QuitClosure()));
1074 void SAMLPolicyTest::GetCookiesOnIOThread(
1075 const scoped_refptr
<net::URLRequestContextGetter
>& request_context
,
1076 const base::Closure
& callback
) {
1077 request_context
->GetURLRequestContext()->cookie_store()->
1078 GetCookieMonster()->GetAllCookiesAsync(base::Bind(
1079 &SAMLPolicyTest::StoreCookieList
,
1080 base::Unretained(this),
1084 void SAMLPolicyTest::StoreCookieList(
1085 const base::Closure
& callback
,
1086 const net::CookieList
& cookie_list
) {
1087 cookie_list_
= cookie_list
;
1088 content::BrowserThread::PostTask(content::BrowserThread::UI
,
1093 IN_PROC_BROWSER_TEST_F(SAMLPolicyTest
, PRE_NoSAML
) {
1094 // Set the offline login time limit for SAML users to zero.
1095 SetSAMLOfflineSigninTimeLimitPolicy(0);
1097 WaitForSigninScreen();
1099 // Log in without SAML.
1100 GetLoginDisplay()->ShowSigninScreenForCreds(kNonSAMLUserEmail
, "password");
1102 content::WindowedNotificationObserver(
1103 chrome::NOTIFICATION_SESSION_STARTED
,
1104 content::NotificationService::AllSources()).Wait();
1107 // Verifies that the offline login time limit does not affect a user who
1108 // authenticated without SAML.
1109 IN_PROC_BROWSER_TEST_F(SAMLPolicyTest
, NoSAML
) {
1110 login_screen_load_observer_
->Wait();
1111 // Verify that offline login is allowed.
1113 "window.getComputedStyle(document.querySelector("
1114 " '#pod-row .reauth-hint-container')).display == 'none'");
1117 IN_PROC_BROWSER_TEST_F(SAMLPolicyTest
, PRE_SAMLNoLimit
) {
1118 // Remove the offline login time limit for SAML users.
1119 SetSAMLOfflineSigninTimeLimitPolicy(-1);
1121 LogInWithSAML(kFirstSAMLUserEmail
, kTestAuthSIDCookie1
, kTestAuthLSIDCookie1
);
1124 // Verifies that when no offline login time limit is set, a user who
1125 // authenticated with SAML is allowed to log in offline.
1126 IN_PROC_BROWSER_TEST_F(SAMLPolicyTest
, SAMLNoLimit
) {
1127 login_screen_load_observer_
->Wait();
1128 // Verify that offline login is allowed.
1130 "window.getComputedStyle(document.querySelector("
1131 " '#pod-row .reauth-hint-container')).display == 'none'");
1134 IN_PROC_BROWSER_TEST_F(SAMLPolicyTest
, PRE_SAMLZeroLimit
) {
1135 // Set the offline login time limit for SAML users to zero.
1136 SetSAMLOfflineSigninTimeLimitPolicy(0);
1138 LogInWithSAML(kFirstSAMLUserEmail
, kTestAuthSIDCookie1
, kTestAuthLSIDCookie1
);
1141 // Verifies that when the offline login time limit is exceeded for a user who
1142 // authenticated via SAML, that user is forced to log in online the next time.
1143 IN_PROC_BROWSER_TEST_F(SAMLPolicyTest
, SAMLZeroLimit
) {
1144 login_screen_load_observer_
->Wait();
1145 // Verify that offline login is not allowed.
1147 "window.getComputedStyle(document.querySelector("
1148 " '#pod-row .reauth-hint-container')).display != 'none'");
1151 IN_PROC_BROWSER_TEST_F(SAMLPolicyTest
, PRE_PRE_TransferCookiesAffiliated
) {
1152 fake_saml_idp()->SetCookieValue(kSAMLIdPCookieValue1
);
1153 LogInWithSAML(kFirstSAMLUserEmail
, kTestAuthSIDCookie1
, kTestAuthLSIDCookie1
);
1156 EXPECT_EQ(kTestAuthSIDCookie1
, GetCookieValue(kGAIASIDCookieName
));
1157 EXPECT_EQ(kTestAuthLSIDCookie1
, GetCookieValue(kGAIALSIDCookieName
));
1158 EXPECT_EQ(kSAMLIdPCookieValue1
, GetCookieValue(kSAMLIdPCookieName
));
1161 // Verifies that when the DeviceTransferSAMLCookies policy is not enabled, SAML
1162 // IdP cookies are not transferred to a user's profile on subsequent login, even
1163 // if the user belongs to the domain that the device is enrolled into. Also
1164 // verifies that GAIA cookies are not transferred.
1165 IN_PROC_BROWSER_TEST_F(SAMLPolicyTest
, PRE_TransferCookiesAffiliated
) {
1166 fake_saml_idp()->SetCookieValue(kSAMLIdPCookieValue2
);
1167 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
1168 ShowGAIALoginForm();
1169 LogInWithSAML(kFirstSAMLUserEmail
, kTestAuthSIDCookie2
, kTestAuthLSIDCookie2
);
1172 EXPECT_EQ(kTestAuthSIDCookie1
, GetCookieValue(kGAIASIDCookieName
));
1173 EXPECT_EQ(kTestAuthLSIDCookie1
, GetCookieValue(kGAIALSIDCookieName
));
1174 EXPECT_EQ(kSAMLIdPCookieValue1
, GetCookieValue(kSAMLIdPCookieName
));
1177 // Verifies that when the DeviceTransferSAMLCookies policy is enabled, SAML IdP
1178 // cookies are transferred to a user's profile on subsequent login when the user
1179 // belongs to the domain that the device is enrolled into. Also verifies that
1180 // GAIA cookies are not transferred.
1181 IN_PROC_BROWSER_TEST_F(SAMLPolicyTest
, TransferCookiesAffiliated
) {
1182 fake_saml_idp()->SetCookieValue(kSAMLIdPCookieValue2
);
1183 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
1184 ShowGAIALoginForm();
1186 EnableTransferSAMLCookiesPolicy();
1187 LogInWithSAML(kFirstSAMLUserEmail
, kTestAuthSIDCookie2
, kTestAuthLSIDCookie2
);
1190 EXPECT_EQ(kTestAuthSIDCookie1
, GetCookieValue(kGAIASIDCookieName
));
1191 EXPECT_EQ(kTestAuthLSIDCookie1
, GetCookieValue(kGAIALSIDCookieName
));
1192 EXPECT_EQ(kSAMLIdPCookieValue2
, GetCookieValue(kSAMLIdPCookieName
));
1195 IN_PROC_BROWSER_TEST_F(SAMLPolicyTest
, PRE_TransferCookiesUnaffiliated
) {
1196 fake_saml_idp()->SetCookieValue(kSAMLIdPCookieValue1
);
1197 LogInWithSAML(kDifferentDomainSAMLUserEmail
,
1198 kTestAuthSIDCookie1
,
1199 kTestAuthLSIDCookie1
);
1202 EXPECT_EQ(kTestAuthSIDCookie1
, GetCookieValue(kGAIASIDCookieName
));
1203 EXPECT_EQ(kTestAuthLSIDCookie1
, GetCookieValue(kGAIALSIDCookieName
));
1204 EXPECT_EQ(kSAMLIdPCookieValue1
, GetCookieValue(kSAMLIdPCookieName
));
1207 // Verifies that even if the DeviceTransferSAMLCookies policy is enabled, SAML
1208 // IdP are not transferred to a user's profile on subsequent login if the user
1209 // does not belong to the domain that the device is enrolled into. Also verifies
1210 // that GAIA cookies are not transferred.
1211 IN_PROC_BROWSER_TEST_F(SAMLPolicyTest
, TransferCookiesUnaffiliated
) {
1212 fake_saml_idp()->SetCookieValue(kSAMLIdPCookieValue2
);
1213 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
1214 ShowGAIALoginForm();
1216 EnableTransferSAMLCookiesPolicy();
1217 LogInWithSAML(kDifferentDomainSAMLUserEmail
,
1218 kTestAuthSIDCookie1
,
1219 kTestAuthLSIDCookie1
);
1222 EXPECT_EQ(kTestAuthSIDCookie1
, GetCookieValue(kGAIASIDCookieName
));
1223 EXPECT_EQ(kTestAuthLSIDCookie1
, GetCookieValue(kGAIALSIDCookieName
));
1224 EXPECT_EQ(kSAMLIdPCookieValue1
, GetCookieValue(kSAMLIdPCookieName
));
1228 } // namespace chromeos