Removed 'gaia-endpoint-chromeos' switch.
[chromium-blink-merge.git] / chrome / browser / chromeos / login / saml / saml_browsertest.cc
blob95b0af55f7d86a2f13dbb6db31587d4958a690db
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.
5 #include <cstring>
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/command_line.h"
11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/json/json_file_value_serializer.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_screen_waiter.h"
31 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
32 #include "chrome/browser/chromeos/login/ui/webui_login_display.h"
33 #include "chrome/browser/chromeos/login/wizard_controller.h"
34 #include "chrome/browser/chromeos/policy/device_policy_builder.h"
35 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
36 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
37 #include "chrome/browser/chromeos/profiles/profile_helper.h"
38 #include "chrome/browser/chromeos/settings/cros_settings.h"
39 #include "chrome/browser/lifetime/application_lifetime.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/common/pref_names.h"
48 #include "chrome/grit/generated_resources.h"
49 #include "chrome/test/base/in_process_browser_test.h"
50 #include "chromeos/chromeos_switches.h"
51 #include "chromeos/dbus/dbus_thread_manager.h"
52 #include "chromeos/dbus/fake_session_manager_client.h"
53 #include "chromeos/dbus/session_manager_client.h"
54 #include "chromeos/settings/cros_settings_names.h"
55 #include "components/policy/core/browser/browser_policy_connector.h"
56 #include "components/policy/core/common/mock_configuration_policy_provider.h"
57 #include "components/policy/core/common/policy_map.h"
58 #include "components/policy/core/common/policy_switches.h"
59 #include "components/policy/core/common/policy_types.h"
60 #include "components/user_manager/user.h"
61 #include "components/user_manager/user_manager.h"
62 #include "content/public/browser/browser_thread.h"
63 #include "content/public/browser/render_frame_host.h"
64 #include "content/public/browser/web_contents.h"
65 #include "content/public/browser/web_contents_observer.h"
66 #include "content/public/test/browser_test_utils.h"
67 #include "content/public/test/test_utils.h"
68 #include "google_apis/gaia/fake_gaia.h"
69 #include "google_apis/gaia/gaia_constants.h"
70 #include "google_apis/gaia/gaia_switches.h"
71 #include "google_apis/gaia/gaia_urls.h"
72 #include "net/base/url_util.h"
73 #include "net/cookies/canonical_cookie.h"
74 #include "net/cookies/cookie_monster.h"
75 #include "net/cookies/cookie_store.h"
76 #include "net/dns/mock_host_resolver.h"
77 #include "net/test/embedded_test_server/embedded_test_server.h"
78 #include "net/test/embedded_test_server/http_request.h"
79 #include "net/test/embedded_test_server/http_response.h"
80 #include "net/url_request/url_request_context.h"
81 #include "net/url_request/url_request_context_getter.h"
82 #include "policy/policy_constants.h"
83 #include "policy/proto/device_management_backend.pb.h"
84 #include "testing/gmock/include/gmock/gmock.h"
85 #include "testing/gtest/include/gtest/gtest.h"
86 #include "ui/base/l10n/l10n_util.h"
87 #include "url/gurl.h"
89 namespace em = enterprise_management;
91 using net::test_server::BasicHttpResponse;
92 using net::test_server::HttpRequest;
93 using net::test_server::HttpResponse;
94 using testing::_;
95 using testing::Return;
97 namespace chromeos {
99 namespace {
101 const char kGAIASIDCookieName[] = "SID";
102 const char kGAIALSIDCookieName[] = "LSID";
104 const char kTestAuthSIDCookie1[] = "fake-auth-SID-cookie-1";
105 const char kTestAuthSIDCookie2[] = "fake-auth-SID-cookie-2";
106 const char kTestAuthLSIDCookie1[] = "fake-auth-LSID-cookie-1";
107 const char kTestAuthLSIDCookie2[] = "fake-auth-LSID-cookie-2";
109 const char kFirstSAMLUserEmail[] = "bob@example.com";
110 const char kSecondSAMLUserEmail[] = "alice@example.com";
111 const char kHTTPSAMLUserEmail[] = "carol@example.com";
112 const char kNonSAMLUserEmail[] = "dan@example.com";
113 const char kDifferentDomainSAMLUserEmail[] = "eve@example.test";
115 const char kSAMLIdPCookieName[] = "saml";
116 const char kSAMLIdPCookieValue1[] = "value-1";
117 const char kSAMLIdPCookieValue2[] = "value-2";
119 const char kRelayState[] = "RelayState";
121 const char kTestUserinfoToken[] = "fake-userinfo-token";
122 const char kTestRefreshToken[] = "fake-refresh-token";
123 const char kPolicy[] = "{\"managed_users\": [\"*\"]}";
125 // FakeSamlIdp serves IdP auth form and the form submission. The form is
126 // served with the template's RelayState placeholder expanded to the real
127 // RelayState parameter from request. The form submission redirects back to
128 // FakeGaia with the same RelayState.
129 class FakeSamlIdp {
130 public:
131 FakeSamlIdp();
132 ~FakeSamlIdp();
134 void SetUp(const std::string& base_path, const GURL& gaia_url);
136 void SetLoginHTMLTemplate(const std::string& template_file);
137 void SetLoginAuthHTMLTemplate(const std::string& template_file);
138 void SetRefreshURL(const GURL& refresh_url);
139 void SetCookieValue(const std::string& cookie_value);
141 scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request);
143 private:
144 scoped_ptr<HttpResponse> BuildHTMLResponse(const std::string& html_template,
145 const std::string& relay_state,
146 const std::string& next_path);
148 base::FilePath html_template_dir_;
150 std::string login_path_;
151 std::string login_auth_path_;
153 std::string login_html_template_;
154 std::string login_auth_html_template_;
155 GURL gaia_assertion_url_;
156 GURL refresh_url_;
157 std::string cookie_value_;
159 DISALLOW_COPY_AND_ASSIGN(FakeSamlIdp);
162 FakeSamlIdp::FakeSamlIdp() {
165 FakeSamlIdp::~FakeSamlIdp() {
168 void FakeSamlIdp::SetUp(const std::string& base_path, const GURL& gaia_url) {
169 base::FilePath test_data_dir;
170 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
171 html_template_dir_ = test_data_dir.Append("login");
173 login_path_= base_path;
174 login_auth_path_ = base_path + "Auth";
175 gaia_assertion_url_ = gaia_url.Resolve("/SSO");
178 void FakeSamlIdp::SetLoginHTMLTemplate(const std::string& template_file) {
179 EXPECT_TRUE(base::ReadFileToString(
180 html_template_dir_.Append(template_file),
181 &login_html_template_));
184 void FakeSamlIdp::SetLoginAuthHTMLTemplate(const std::string& template_file) {
185 EXPECT_TRUE(base::ReadFileToString(
186 html_template_dir_.Append(template_file),
187 &login_auth_html_template_));
190 void FakeSamlIdp::SetRefreshURL(const GURL& refresh_url) {
191 refresh_url_ = refresh_url;
194 void FakeSamlIdp::SetCookieValue(const std::string& cookie_value) {
195 cookie_value_ = cookie_value;
198 scoped_ptr<HttpResponse> FakeSamlIdp::HandleRequest(
199 const HttpRequest& request) {
200 // The scheme and host of the URL is actually not important but required to
201 // get a valid GURL in order to parse |request.relative_url|.
202 GURL request_url = GURL("http://localhost").Resolve(request.relative_url);
203 std::string request_path = request_url.path();
205 if (request_path == login_path_) {
206 std::string relay_state;
207 net::GetValueForKeyInQuery(request_url, kRelayState, &relay_state);
208 return BuildHTMLResponse(login_html_template_,
209 relay_state,
210 login_auth_path_);
213 if (request_path != login_auth_path_) {
214 // Request not understood.
215 return scoped_ptr<HttpResponse>();
218 std::string relay_state;
219 FakeGaia::GetQueryParameter(request.content, kRelayState, &relay_state);
220 GURL redirect_url = gaia_assertion_url_;
222 if (!login_auth_html_template_.empty()) {
223 return BuildHTMLResponse(login_auth_html_template_,
224 relay_state,
225 redirect_url.spec());
228 redirect_url = net::AppendQueryParameter(
229 redirect_url, "SAMLResponse", "fake_response");
230 redirect_url = net::AppendQueryParameter(
231 redirect_url, kRelayState, relay_state);
233 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse());
234 http_response->set_code(net::HTTP_TEMPORARY_REDIRECT);
235 http_response->AddCustomHeader("Location", redirect_url.spec());
236 http_response->AddCustomHeader(
237 "Set-cookie",
238 base::StringPrintf("saml=%s", cookie_value_.c_str()));
239 return http_response.Pass();
242 scoped_ptr<HttpResponse> FakeSamlIdp::BuildHTMLResponse(
243 const std::string& html_template,
244 const std::string& relay_state,
245 const std::string& next_path) {
246 std::string response_html = html_template;
247 ReplaceSubstringsAfterOffset(&response_html, 0, "$RelayState", relay_state);
248 ReplaceSubstringsAfterOffset(&response_html, 0, "$Post", next_path);
249 ReplaceSubstringsAfterOffset(
250 &response_html, 0, "$Refresh", refresh_url_.spec());
252 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse());
253 http_response->set_code(net::HTTP_OK);
254 http_response->set_content(response_html);
255 http_response->set_content_type("text/html");
257 return http_response.Pass();
260 } // namespace
262 class SamlTest : public InProcessBrowserTest,
263 public testing::WithParamInterface<bool> {
264 public:
265 SamlTest() : gaia_frame_parent_("signin-frame"), saml_load_injected_(false) {}
266 ~SamlTest() override {}
268 bool UseWebView() const {
269 return GetParam();
272 void SetUp() override {
273 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
275 // Start the GAIA https wrapper here so that the GAIA URLs can be pointed at
276 // it in SetUpCommandLine().
277 gaia_https_forwarder_.reset(
278 new HTTPSForwarder(embedded_test_server()->base_url()));
279 ASSERT_TRUE(gaia_https_forwarder_->Start());
281 // Start the SAML IdP https wrapper here so that GAIA can be pointed at it
282 // in SetUpCommandLine().
283 saml_https_forwarder_.reset(
284 new HTTPSForwarder(embedded_test_server()->base_url()));
285 ASSERT_TRUE(saml_https_forwarder_->Start());
287 // Stop IO thread here because no threads are allowed while
288 // spawning sandbox host process. See crbug.com/322732.
289 embedded_test_server()->StopThread();
291 InProcessBrowserTest::SetUp();
294 bool SetUpUserDataDirectory() override {
295 if (UseWebView()) {
296 // Fake Dev channel to enable webview signin.
297 scoped_channel_.reset(new extensions::ScopedCurrentChannel(
298 chrome::VersionInfo::CHANNEL_DEV));
300 base::FilePath user_data_dir;
301 CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
302 base::FilePath local_state_path =
303 user_data_dir.Append(chrome::kLocalStateFilename);
305 // Set webview enabled flag only when local state file does not exist.
306 // Otherwise, we break PRE tests that leave state in it.
307 if (!base::PathExists(local_state_path)) {
308 base::DictionaryValue local_state_dict;
309 local_state_dict.SetBoolean(prefs::kWebviewSigninEnabled, true);
310 // OobeCompleted to skip controller-pairing-screen which still uses
311 // iframe and ends up in a JS error in oobe page init.
312 // See http://crbug.com/467147
313 local_state_dict.SetBoolean(prefs::kOobeComplete, true);
315 CHECK(JSONFileValueSerializer(local_state_path)
316 .Serialize(local_state_dict));
320 return InProcessBrowserTest::SetUpUserDataDirectory();
323 void SetUpInProcessBrowserTestFixture() override {
324 host_resolver()->AddRule("*", "127.0.0.1");
327 void SetUpCommandLine(base::CommandLine* command_line) override {
328 command_line->AppendSwitch(switches::kLoginManager);
329 command_line->AppendSwitch(switches::kForceLoginManagerInTests);
330 command_line->AppendSwitch(switches::kOobeSkipPostLogin);
331 command_line->AppendSwitch(::switches::kDisableBackgroundNetworking);
332 command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
334 const GURL gaia_url = gaia_https_forwarder_->GetURL("");
335 command_line->AppendSwitchASCII(::switches::kGaiaUrl, gaia_url.spec());
336 command_line->AppendSwitchASCII(::switches::kLsoUrl, gaia_url.spec());
337 command_line->AppendSwitchASCII(::switches::kGoogleApisUrl,
338 gaia_url.spec());
340 const GURL saml_idp_url = saml_https_forwarder_->GetURL("SAML");
341 fake_saml_idp_.SetUp(saml_idp_url.path(), gaia_url);
342 fake_gaia_.RegisterSamlUser(kFirstSAMLUserEmail, saml_idp_url);
343 fake_gaia_.RegisterSamlUser(kSecondSAMLUserEmail, saml_idp_url);
344 fake_gaia_.RegisterSamlUser(
345 kHTTPSAMLUserEmail,
346 embedded_test_server()->base_url().Resolve("/SAML"));
347 fake_gaia_.RegisterSamlUser(kDifferentDomainSAMLUserEmail, saml_idp_url);
349 fake_gaia_.Initialize();
350 fake_gaia_.set_issue_oauth_code_cookie(UseWebView());
353 void SetUpOnMainThread() override {
354 fake_gaia_.SetFakeMergeSessionParams(kFirstSAMLUserEmail,
355 kTestAuthSIDCookie1,
356 kTestAuthLSIDCookie1);
358 embedded_test_server()->RegisterRequestHandler(
359 base::Bind(&FakeGaia::HandleRequest, base::Unretained(&fake_gaia_)));
360 embedded_test_server()->RegisterRequestHandler(base::Bind(
361 &FakeSamlIdp::HandleRequest, base::Unretained(&fake_saml_idp_)));
363 // Restart the thread as the sandbox host process has already been spawned.
364 embedded_test_server()->RestartThreadAndListen();
366 login_screen_load_observer_.reset(new content::WindowedNotificationObserver(
367 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
368 content::NotificationService::AllSources()));
371 void TearDownOnMainThread() override {
372 // If the login display is still showing, exit gracefully.
373 if (LoginDisplayHostImpl::default_host()) {
374 base::MessageLoop::current()->PostTask(FROM_HERE,
375 base::Bind(&chrome::AttemptExit));
376 content::RunMessageLoop();
380 WebUILoginDisplay* GetLoginDisplay() {
381 ExistingUserController* controller =
382 ExistingUserController::current_controller();
383 CHECK(controller);
384 return static_cast<WebUILoginDisplay*>(controller->login_display());
387 void WaitForSigninScreen() {
388 WizardController* wizard_controller =
389 WizardController::default_controller();
390 if (wizard_controller) {
391 wizard_controller->SkipToLoginForTesting(LoginScreenContext());
393 WizardController::SkipPostLoginScreensForTesting();
395 login_screen_load_observer_->Wait();
398 virtual void StartSamlAndWaitForIdpPageLoad(const std::string& gaia_email) {
399 WaitForSigninScreen();
401 if (!saml_load_injected_) {
402 saml_load_injected_ = true;
404 ASSERT_TRUE(content::ExecuteScript(
405 GetLoginUI()->GetWebContents(),
406 "$('gaia-signin').gaiaAuthHost_.addEventListener('authFlowChange',"
407 "function() {"
408 "window.domAutomationController.setAutomationId(0);"
409 "window.domAutomationController.send("
410 "$('gaia-signin').isSAML() ? 'SamlLoaded' : 'GaiaLoaded');"
411 "});"));
414 content::DOMMessageQueue message_queue; // Start observe before SAML.
415 GetLoginDisplay()->ShowSigninScreenForCreds(gaia_email, "");
417 std::string message;
418 ASSERT_TRUE(message_queue.WaitForMessage(&message));
419 EXPECT_EQ("\"SamlLoaded\"", message);
422 void SetSignFormField(const std::string& field_id,
423 const std::string& field_value) {
424 std::string js =
425 "(function(){"
426 "document.getElementById('$FieldId').value = '$FieldValue';"
427 "var e = new Event('input');"
428 "document.getElementById('$FieldId').dispatchEvent(e);"
429 "})();";
430 ReplaceSubstringsAfterOffset(&js, 0, "$FieldId", field_id);
431 ReplaceSubstringsAfterOffset(&js, 0, "$FieldValue", field_value);
432 ExecuteJsInSigninFrame(js);
435 void SendConfirmPassword(const std::string& password_to_confirm) {
436 std::string js =
437 "$('confirm-password-input').value='$Password';"
438 "$('confirm-password').onConfirmPassword_();";
439 ReplaceSubstringsAfterOffset(&js, 0, "$Password", password_to_confirm);
440 ASSERT_TRUE(content::ExecuteScript(GetLoginUI()->GetWebContents(), js));
443 void JsExpect(const std::string& js) {
444 bool result;
445 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
446 GetLoginUI()->GetWebContents(),
447 "window.domAutomationController.send(!!(" + js + "));",
448 &result));
449 EXPECT_TRUE(result) << js;
452 std::string WaitForAndGetFatalErrorMessage() {
453 OobeScreenWaiter(OobeDisplay::SCREEN_FATAL_ERROR).Wait();
454 std::string error_message;
455 if (!content::ExecuteScriptAndExtractString(
456 GetLoginUI()->GetWebContents(),
457 "window.domAutomationController.send("
458 "$('fatal-error-message').textContent);",
459 &error_message)) {
460 ADD_FAILURE();
462 return error_message;
465 content::WebUI* GetLoginUI() {
466 return static_cast<LoginDisplayHostImpl*>(
467 LoginDisplayHostImpl::default_host())->GetOobeUI()->web_ui();
470 // Executes JavaScript code in the auth iframe hosted by gaia_auth extension.
471 void ExecuteJsInSigninFrame(const std::string& js) {
472 content::RenderFrameHost* frame = InlineLoginUI::GetAuthIframe(
473 GetLoginUI()->GetWebContents(), GURL(), gaia_frame_parent_);
474 ASSERT_TRUE(content::ExecuteScript(frame, js));
477 FakeSamlIdp* fake_saml_idp() { return &fake_saml_idp_; }
479 protected:
480 scoped_ptr<content::WindowedNotificationObserver> login_screen_load_observer_;
481 FakeGaia fake_gaia_;
483 std::string gaia_frame_parent_;
485 scoped_ptr<HTTPSForwarder> gaia_https_forwarder_;
486 scoped_ptr<HTTPSForwarder> saml_https_forwarder_;
488 private:
489 FakeSamlIdp fake_saml_idp_;
490 scoped_ptr<extensions::ScopedCurrentChannel> scoped_channel_;
492 bool saml_load_injected_;
494 DISALLOW_COPY_AND_ASSIGN(SamlTest);
497 // Tests that signin frame should have 'saml' class and 'cancel' button is
498 // visible when SAML IdP page is loaded. And 'cancel' button goes back to
499 // gaia on clicking.
500 IN_PROC_BROWSER_TEST_P(SamlTest, SamlUI) {
501 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
502 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
504 // Saml flow UI expectations.
505 JsExpect("$('gaia-signin').classList.contains('full-width')");
506 if (!UseWebView()) {
507 JsExpect("!$('cancel-add-user-button').hidden");
510 // Click on 'cancel'.
511 content::DOMMessageQueue message_queue; // Observe before 'cancel'.
512 if (UseWebView()) {
513 ASSERT_TRUE(content::ExecuteScript(
514 GetLoginUI()->GetWebContents(),
515 "$('close-button-item').click();"));
516 } else {
517 ASSERT_TRUE(content::ExecuteScript(
518 GetLoginUI()->GetWebContents(),
519 "$('cancel-add-user-button').click();"));
522 // Auth flow should change back to Gaia.
523 std::string message;
524 do {
525 ASSERT_TRUE(message_queue.WaitForMessage(&message));
526 } while (message != "\"GaiaLoaded\"");
528 // Saml flow is gone.
529 JsExpect("!$('gaia-signin').classList.contains('full-width')");
532 // Tests the sign-in flow when the credentials passing API is used.
533 IN_PROC_BROWSER_TEST_P(SamlTest, CredentialPassingAPI) {
534 // Disabled for webview because the script is injected using
535 // webview.executeScript and there is no way to control the injection time.
536 // As a result, this test is flaky and fails about 20% of the time.
537 // TODO(xiyuan): Re-enable when webview.addContentScript API is ready.
538 if (UseWebView())
539 return;
541 fake_saml_idp()->SetLoginHTMLTemplate("saml_api_login.html");
542 fake_saml_idp()->SetLoginAuthHTMLTemplate("saml_api_login_auth.html");
543 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
545 content::WindowedNotificationObserver session_start_waiter(
546 chrome::NOTIFICATION_SESSION_STARTED,
547 content::NotificationService::AllSources());
549 // Fill-in the SAML IdP form and submit.
550 SetSignFormField("Email", "fake_user");
551 SetSignFormField("Password", "fake_password");
552 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
554 // Login should finish login and a session should start.
555 session_start_waiter.Wait();
558 // Tests the single password scraped flow.
559 IN_PROC_BROWSER_TEST_P(SamlTest, ScrapedSingle) {
560 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
561 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
563 // Fill-in the SAML IdP form and submit.
564 SetSignFormField("Email", "fake_user");
565 SetSignFormField("Password", "fake_password");
566 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
568 // Lands on confirm password screen.
569 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait();
571 // Entering an unknown password should go back to the confirm password screen.
572 SendConfirmPassword("wrong_password");
573 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait();
575 // Entering a known password should finish login and start session.
576 content::WindowedNotificationObserver session_start_waiter(
577 chrome::NOTIFICATION_SESSION_STARTED,
578 content::NotificationService::AllSources());
579 SendConfirmPassword("fake_password");
580 session_start_waiter.Wait();
583 // Tests password scraping from a dynamically created password field.
584 IN_PROC_BROWSER_TEST_P(SamlTest, ScrapedDynamic) {
585 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
586 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
588 ExecuteJsInSigninFrame(
589 "(function() {"
590 "var newPassInput = document.createElement('input');"
591 "newPassInput.id = 'DynamicallyCreatedPassword';"
592 "newPassInput.type = 'password';"
593 "newPassInput.name = 'Password';"
594 "document.forms[0].appendChild(newPassInput);"
595 "})();");
597 // Fill-in the SAML IdP form and submit.
598 SetSignFormField("Email", "fake_user");
599 SetSignFormField("DynamicallyCreatedPassword", "fake_password");
600 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
602 // Lands on confirm password screen.
603 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait();
605 // Entering an unknown password should go back to the confirm password screen.
606 SendConfirmPassword("wrong_password");
607 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait();
609 // Entering a known password should finish login and start session.
610 content::WindowedNotificationObserver session_start_waiter(
611 chrome::NOTIFICATION_SESSION_STARTED,
612 content::NotificationService::AllSources());
613 SendConfirmPassword("fake_password");
614 session_start_waiter.Wait();
617 // Tests the multiple password scraped flow.
618 IN_PROC_BROWSER_TEST_P(SamlTest, ScrapedMultiple) {
619 fake_saml_idp()->SetLoginHTMLTemplate("saml_login_two_passwords.html");
621 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
623 SetSignFormField("Email", "fake_user");
624 SetSignFormField("Password", "fake_password");
625 SetSignFormField("Password1", "password1");
626 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
628 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait();
630 // Either scraped password should be able to sign-in.
631 content::WindowedNotificationObserver session_start_waiter(
632 chrome::NOTIFICATION_SESSION_STARTED,
633 content::NotificationService::AllSources());
634 SendConfirmPassword("password1");
635 session_start_waiter.Wait();
638 // Tests the no password scraped flow.
639 IN_PROC_BROWSER_TEST_P(SamlTest, ScrapedNone) {
640 fake_saml_idp()->SetLoginHTMLTemplate("saml_login_no_passwords.html");
642 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
644 SetSignFormField("Email", "fake_user");
645 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
647 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_LOGIN_FATAL_ERROR_NO_PASSWORD),
648 WaitForAndGetFatalErrorMessage());
651 // Types |bob@example.com| into the GAIA login form but then authenticates as
652 // |alice@example.com| via SAML. Verifies that the logged-in user is correctly
653 // identified as Alice.
654 IN_PROC_BROWSER_TEST_P(SamlTest, UseAutenticatedUserEmailAddress) {
655 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
656 // Type |bob@example.com| into the GAIA login form.
657 StartSamlAndWaitForIdpPageLoad(kSecondSAMLUserEmail);
659 // Authenticate as alice@example.com via SAML (the |Email| provided here is
660 // irrelevant - the authenticated user's e-mail address that FakeGAIA
661 // reports was set via |SetFakeMergeSessionParams|.
662 SetSignFormField("Email", "fake_user");
663 SetSignFormField("Password", "fake_password");
664 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
666 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait();
668 content::WindowedNotificationObserver session_start_waiter(
669 chrome::NOTIFICATION_SESSION_STARTED,
670 content::NotificationService::AllSources());
671 SendConfirmPassword("fake_password");
672 session_start_waiter.Wait();
673 const user_manager::User* user =
674 user_manager::UserManager::Get()->GetActiveUser();
675 ASSERT_TRUE(user);
676 EXPECT_EQ(kFirstSAMLUserEmail, user->email());
679 // Verifies that if the authenticated user's e-mail address cannot be retrieved,
680 // an error message is shown.
681 IN_PROC_BROWSER_TEST_P(SamlTest, FailToRetrieveAutenticatedUserEmailAddress) {
682 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
683 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
685 fake_gaia_.SetFakeMergeSessionParams(
686 "", kTestAuthSIDCookie1, kTestAuthLSIDCookie1);
687 SetSignFormField("Email", "fake_user");
688 SetSignFormField("Password", "fake_password");
689 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
691 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_LOGIN_FATAL_ERROR_NO_ACCOUNT_DETAILS),
692 WaitForAndGetFatalErrorMessage());
695 // Tests the password confirm flow: show error on the first failure and
696 // fatal error on the second failure.
697 IN_PROC_BROWSER_TEST_P(SamlTest, PasswordConfirmFlow) {
698 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
699 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
701 // Fill-in the SAML IdP form and submit.
702 SetSignFormField("Email", "fake_user");
703 SetSignFormField("Password", "fake_password");
704 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
706 // Lands on confirm password screen with no error message.
707 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait();
708 JsExpect("!$('confirm-password').classList.contains('error')");
710 // Enter an unknown password for the first time should go back to confirm
711 // password screen with error message.
712 SendConfirmPassword("wrong_password");
713 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait();
714 JsExpect("$('confirm-password').classList.contains('error')");
716 // Enter an unknown password 2nd time should go back fatal error message.
717 SendConfirmPassword("wrong_password");
718 EXPECT_EQ(
719 l10n_util::GetStringUTF8(IDS_LOGIN_FATAL_ERROR_PASSWORD_VERIFICATION),
720 WaitForAndGetFatalErrorMessage());
723 // Verifies that when GAIA attempts to redirect to a SAML IdP served over http,
724 // not https, the redirect is blocked and an error message is shown.
725 IN_PROC_BROWSER_TEST_P(SamlTest, HTTPRedirectDisallowed) {
726 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
728 WaitForSigninScreen();
729 GetLoginDisplay()->ShowSigninScreenForCreds(kHTTPSAMLUserEmail, "");
731 const GURL url = embedded_test_server()->base_url().Resolve("/SAML");
732 EXPECT_EQ(l10n_util::GetStringFUTF8(
733 IDS_LOGIN_FATAL_ERROR_TEXT_INSECURE_URL,
734 base::UTF8ToUTF16(url.spec())),
735 WaitForAndGetFatalErrorMessage());
738 // Verifies that when GAIA attempts to redirect to a page served over http, not
739 // https, via an HTML meta refresh, the redirect is blocked and an error message
740 // is shown. This guards against regressions of http://crbug.com/359515.
741 IN_PROC_BROWSER_TEST_P(SamlTest, MetaRefreshToHTTPDisallowed) {
742 const GURL url = embedded_test_server()->base_url().Resolve("/SSO");
743 fake_saml_idp()->SetLoginHTMLTemplate("saml_login_instant_meta_refresh.html");
744 fake_saml_idp()->SetRefreshURL(url);
746 WaitForSigninScreen();
747 GetLoginDisplay()->ShowSigninScreenForCreds(kFirstSAMLUserEmail, "");
749 EXPECT_EQ(l10n_util::GetStringFUTF8(
750 IDS_LOGIN_FATAL_ERROR_TEXT_INSECURE_URL,
751 base::UTF8ToUTF16(url.spec())),
752 WaitForAndGetFatalErrorMessage());
755 INSTANTIATE_TEST_CASE_P(SamlSuite,
756 SamlTest,
757 testing::Bool());
759 class SAMLEnrollmentTest : public SamlTest,
760 public content::WebContentsObserver {
761 public:
762 SAMLEnrollmentTest();
763 ~SAMLEnrollmentTest() override;
765 // SamlTest:
766 void SetUp() override;
767 void SetUpCommandLine(base::CommandLine* command_line) override;
768 void SetUpOnMainThread() override;
769 void StartSamlAndWaitForIdpPageLoad(const std::string& gaia_email) override;
771 // content::WebContentsObserver:
772 void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
773 void DidFinishLoad(content::RenderFrameHost* render_frame_host,
774 const GURL& validated_url) override;
776 void WaitForEnrollmentSuccess();
778 private:
779 scoped_ptr<policy::LocalPolicyTestServer> test_server_;
780 base::ScopedTempDir temp_dir_;
782 scoped_ptr<base::RunLoop> run_loop_;
783 content::RenderFrameHost* auth_frame_;
785 DISALLOW_COPY_AND_ASSIGN(SAMLEnrollmentTest);
788 SAMLEnrollmentTest::SAMLEnrollmentTest() : auth_frame_(nullptr) {
789 gaia_frame_parent_ = "oauth-enroll-signin-frame";
792 SAMLEnrollmentTest::~SAMLEnrollmentTest() {
795 void SAMLEnrollmentTest::SetUp() {
796 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
797 const base::FilePath policy_file =
798 temp_dir_.path().AppendASCII("policy.json");
799 ASSERT_EQ(static_cast<int>(strlen(kPolicy)),
800 base::WriteFile(policy_file, kPolicy, strlen(kPolicy)));
802 test_server_.reset(new policy::LocalPolicyTestServer(policy_file));
803 ASSERT_TRUE(test_server_->Start());
805 SamlTest::SetUp();
808 void SAMLEnrollmentTest::SetUpCommandLine(base::CommandLine* command_line) {
809 command_line->AppendSwitchASCII(policy::switches::kDeviceManagementUrl,
810 test_server_->GetServiceURL().spec());
811 command_line->AppendSwitch(policy::switches::kDisablePolicyKeyVerification);
812 command_line->AppendSwitch(switches::kEnterpriseEnrollmentSkipRobotAuth);
814 SamlTest::SetUpCommandLine(command_line);
817 void SAMLEnrollmentTest::SetUpOnMainThread() {
818 Observe(GetLoginUI()->GetWebContents());
820 FakeGaia::AccessTokenInfo token_info;
821 token_info.token = kTestUserinfoToken;
822 token_info.scopes.insert(GaiaConstants::kDeviceManagementServiceOAuth);
823 token_info.scopes.insert(GaiaConstants::kOAuthWrapBridgeUserInfoScope);
824 token_info.audience = GaiaUrls::GetInstance()->oauth2_chrome_client_id();
825 token_info.email = kFirstSAMLUserEmail;
826 fake_gaia_.IssueOAuthToken(kTestRefreshToken, token_info);
828 SamlTest::SetUpOnMainThread();
831 void SAMLEnrollmentTest::StartSamlAndWaitForIdpPageLoad(
832 const std::string& gaia_email) {
833 WaitForSigninScreen();
834 run_loop_.reset(new base::RunLoop);
835 ExistingUserController::current_controller()->OnStartEnterpriseEnrollment();
836 run_loop_->Run();
838 SetSignFormField("Email", gaia_email);
840 run_loop_.reset(new base::RunLoop);
841 ExecuteJsInSigninFrame("document.getElementById('signIn').click();");
842 run_loop_->Run();
845 void SAMLEnrollmentTest::RenderFrameCreated(
846 content::RenderFrameHost* render_frame_host) {
847 content::RenderFrameHost* parent = render_frame_host->GetParent();
848 if (!parent || parent->GetFrameName() != gaia_frame_parent_)
849 return;
851 // The GAIA extension created the iframe in which the login form will be
852 // shown. Now wait for the login form to finish loading.
853 auth_frame_ = render_frame_host;
854 Observe(content::WebContents::FromRenderFrameHost(auth_frame_));
857 void SAMLEnrollmentTest::DidFinishLoad(
858 content::RenderFrameHost* render_frame_host,
859 const GURL& validated_url) {
860 if (render_frame_host != auth_frame_)
861 return;
863 const GURL origin = validated_url.GetOrigin();
864 if (origin != gaia_https_forwarder_->GetURL("") &&
865 origin != saml_https_forwarder_->GetURL("")) {
866 return;
869 // The GAIA or SAML IdP login form finished loading.
870 if (run_loop_)
871 run_loop_->Quit();
874 // Waits until the class |oauth-enroll-state-success| becomes set for the
875 // enrollment screen, indicating enrollment success.
876 void SAMLEnrollmentTest::WaitForEnrollmentSuccess() {
877 bool done = false;
878 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
879 GetLoginUI()->GetWebContents(),
880 "var enrollmentScreen = document.getElementById('oauth-enrollment');"
881 "function SendReplyIfEnrollmentDone() {"
882 " if (!enrollmentScreen.classList.contains("
883 " 'oauth-enroll-state-success')) {"
884 " return false;"
885 " }"
886 " domAutomationController.send(true);"
887 " observer.disconnect();"
888 " return true;"
890 "var observer = new MutationObserver(SendReplyIfEnrollmentDone);"
891 "if (!SendReplyIfEnrollmentDone()) {"
892 " var options = { attributes: true, attributeFilter: [ 'class' ] };"
893 " observer.observe(enrollmentScreen, options);"
894 "}",
895 &done));
898 IN_PROC_BROWSER_TEST_P(SAMLEnrollmentTest, WithoutCredentialsPassingAPI) {
899 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
900 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
902 // Fill-in the SAML IdP form and submit.
903 SetSignFormField("Email", "fake_user");
904 SetSignFormField("Password", "fake_password");
905 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
907 WaitForEnrollmentSuccess();
910 IN_PROC_BROWSER_TEST_P(SAMLEnrollmentTest, WithCredentialsPassingAPI) {
911 fake_saml_idp()->SetLoginHTMLTemplate("saml_api_login.html");
912 fake_saml_idp()->SetLoginAuthHTMLTemplate("saml_api_login_auth.html");
913 StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
915 // Fill-in the SAML IdP form and submit.
916 SetSignFormField("Email", "fake_user");
917 SetSignFormField("Password", "fake_password");
918 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
920 WaitForEnrollmentSuccess();
923 // TODO(xiyuan): Update once webview flow is implemented.
924 INSTANTIATE_TEST_CASE_P(SamlSuite,
925 SAMLEnrollmentTest,
926 testing::Values(false));
928 class SAMLPolicyTest : public SamlTest {
929 public:
930 SAMLPolicyTest();
931 ~SAMLPolicyTest() override;
933 // SamlTest:
934 void SetUpInProcessBrowserTestFixture() override;
935 void SetUpOnMainThread() override;
937 void SetSAMLOfflineSigninTimeLimitPolicy(int limit);
938 void EnableTransferSAMLCookiesPolicy();
940 void ShowGAIALoginForm();
941 void LogInWithSAML(const std::string& user_id,
942 const std::string& auth_sid_cookie,
943 const std::string& auth_lsid_cookie);
945 std::string GetCookieValue(const std::string& name);
947 void GetCookies();
949 protected:
950 void GetCookiesOnIOThread(
951 const scoped_refptr<net::URLRequestContextGetter>& request_context,
952 const base::Closure& callback);
953 void StoreCookieList(const base::Closure& callback,
954 const net::CookieList& cookie_list);
956 policy::DevicePolicyCrosTestHelper test_helper_;
958 // FakeDBusThreadManager uses FakeSessionManagerClient.
959 FakeSessionManagerClient* fake_session_manager_client_;
960 policy::DevicePolicyBuilder* device_policy_;
962 policy::MockConfigurationPolicyProvider provider_;
964 net::CookieList cookie_list_;
966 private:
967 DISALLOW_COPY_AND_ASSIGN(SAMLPolicyTest);
970 SAMLPolicyTest::SAMLPolicyTest()
971 : fake_session_manager_client_(new FakeSessionManagerClient),
972 device_policy_(test_helper_.device_policy()) {
975 SAMLPolicyTest::~SAMLPolicyTest() {
978 void SAMLPolicyTest::SetUpInProcessBrowserTestFixture() {
979 DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient(
980 scoped_ptr<SessionManagerClient>(fake_session_manager_client_));
982 SamlTest::SetUpInProcessBrowserTestFixture();
984 // Initialize device policy.
985 test_helper_.InstallOwnerKey();
986 test_helper_.MarkAsEnterpriseOwned();
987 device_policy_->SetDefaultSigningKey();
988 device_policy_->Build();
989 fake_session_manager_client_->set_device_policy(device_policy_->GetBlob());
990 fake_session_manager_client_->OnPropertyChangeComplete(true);
992 // Initialize user policy.
993 EXPECT_CALL(provider_, IsInitializationComplete(_))
994 .WillRepeatedly(Return(true));
995 policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_);
998 void SAMLPolicyTest::SetUpOnMainThread() {
999 SamlTest::SetUpOnMainThread();
1001 // Pretend that the test users' OAuth tokens are valid.
1002 user_manager::UserManager::Get()->SaveUserOAuthStatus(
1003 kFirstSAMLUserEmail, user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
1004 user_manager::UserManager::Get()->SaveUserOAuthStatus(
1005 kNonSAMLUserEmail, user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
1006 user_manager::UserManager::Get()->SaveUserOAuthStatus(
1007 kDifferentDomainSAMLUserEmail,
1008 user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
1011 void SAMLPolicyTest::SetSAMLOfflineSigninTimeLimitPolicy(int limit) {
1012 policy::PolicyMap user_policy;
1013 user_policy.Set(policy::key::kSAMLOfflineSigninTimeLimit,
1014 policy::POLICY_LEVEL_MANDATORY,
1015 policy::POLICY_SCOPE_USER,
1016 new base::FundamentalValue(limit),
1017 NULL);
1018 provider_.UpdateChromePolicy(user_policy);
1019 base::RunLoop().RunUntilIdle();
1022 void SAMLPolicyTest::EnableTransferSAMLCookiesPolicy() {
1023 em::ChromeDeviceSettingsProto& proto(device_policy_->payload());
1024 proto.mutable_saml_settings()->set_transfer_saml_cookies(true);
1026 base::RunLoop run_loop;
1027 scoped_ptr<CrosSettings::ObserverSubscription> observer =
1028 CrosSettings::Get()->AddSettingsObserver(
1029 kAccountsPrefTransferSAMLCookies,
1030 run_loop.QuitClosure());
1031 device_policy_->SetDefaultSigningKey();
1032 device_policy_->Build();
1033 fake_session_manager_client_->set_device_policy(device_policy_->GetBlob());
1034 fake_session_manager_client_->OnPropertyChangeComplete(true);
1035 run_loop.Run();
1038 void SAMLPolicyTest::ShowGAIALoginForm() {
1039 login_screen_load_observer_->Wait();
1040 ASSERT_TRUE(content::ExecuteScript(
1041 GetLoginUI()->GetWebContents(),
1042 "$('gaia-signin').gaiaAuthHost_.addEventListener('ready', function() {"
1043 " window.domAutomationController.setAutomationId(0);"
1044 " window.domAutomationController.send('ready');"
1045 "});"
1046 "$('add-user-button').click();"));
1047 content::DOMMessageQueue message_queue;
1048 std::string message;
1049 ASSERT_TRUE(message_queue.WaitForMessage(&message));
1050 EXPECT_EQ("\"ready\"", message);
1053 void SAMLPolicyTest::LogInWithSAML(const std::string& user_id,
1054 const std::string& auth_sid_cookie,
1055 const std::string& auth_lsid_cookie) {
1056 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
1057 StartSamlAndWaitForIdpPageLoad(user_id);
1059 fake_gaia_.SetFakeMergeSessionParams(
1060 user_id, auth_sid_cookie, auth_lsid_cookie);
1061 SetSignFormField("Email", "fake_user");
1062 SetSignFormField("Password", "fake_password");
1063 ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
1065 OobeScreenWaiter(OobeDisplay::SCREEN_CONFIRM_PASSWORD).Wait();
1067 content::WindowedNotificationObserver session_start_waiter(
1068 chrome::NOTIFICATION_SESSION_STARTED,
1069 content::NotificationService::AllSources());
1070 SendConfirmPassword("fake_password");
1071 session_start_waiter.Wait();
1074 std::string SAMLPolicyTest::GetCookieValue(const std::string& name) {
1075 for (net::CookieList::const_iterator it = cookie_list_.begin();
1076 it != cookie_list_.end(); ++it) {
1077 if (it->Name() == name)
1078 return it->Value();
1080 return std::string();
1083 void SAMLPolicyTest::GetCookies() {
1084 Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(
1085 user_manager::UserManager::Get()->GetActiveUser());
1086 ASSERT_TRUE(profile);
1087 base::RunLoop run_loop;
1088 content::BrowserThread::PostTask(
1089 content::BrowserThread::IO,
1090 FROM_HERE,
1091 base::Bind(&SAMLPolicyTest::GetCookiesOnIOThread,
1092 base::Unretained(this),
1093 scoped_refptr<net::URLRequestContextGetter>(
1094 profile->GetRequestContext()),
1095 run_loop.QuitClosure()));
1096 run_loop.Run();
1099 void SAMLPolicyTest::GetCookiesOnIOThread(
1100 const scoped_refptr<net::URLRequestContextGetter>& request_context,
1101 const base::Closure& callback) {
1102 request_context->GetURLRequestContext()->cookie_store()->
1103 GetCookieMonster()->GetAllCookiesAsync(base::Bind(
1104 &SAMLPolicyTest::StoreCookieList,
1105 base::Unretained(this),
1106 callback));
1109 void SAMLPolicyTest::StoreCookieList(
1110 const base::Closure& callback,
1111 const net::CookieList& cookie_list) {
1112 cookie_list_ = cookie_list;
1113 content::BrowserThread::PostTask(content::BrowserThread::UI,
1114 FROM_HERE,
1115 callback);
1118 IN_PROC_BROWSER_TEST_P(SAMLPolicyTest, PRE_NoSAML) {
1119 // Set the offline login time limit for SAML users to zero.
1120 SetSAMLOfflineSigninTimeLimitPolicy(0);
1122 WaitForSigninScreen();
1124 // Log in without SAML.
1125 GetLoginDisplay()->ShowSigninScreenForCreds(kNonSAMLUserEmail, "password");
1127 content::WindowedNotificationObserver(
1128 chrome::NOTIFICATION_SESSION_STARTED,
1129 content::NotificationService::AllSources()).Wait();
1132 // Verifies that the offline login time limit does not affect a user who
1133 // authenticated without SAML.
1134 IN_PROC_BROWSER_TEST_P(SAMLPolicyTest, NoSAML) {
1135 login_screen_load_observer_->Wait();
1136 // Verify that offline login is allowed.
1137 JsExpect("window.getComputedStyle(document.querySelector("
1138 " '#pod-row .signin-button-container')).display == 'none'");
1141 IN_PROC_BROWSER_TEST_P(SAMLPolicyTest, PRE_SAMLNoLimit) {
1142 // Remove the offline login time limit for SAML users.
1143 SetSAMLOfflineSigninTimeLimitPolicy(-1);
1145 LogInWithSAML(kFirstSAMLUserEmail, kTestAuthSIDCookie1, kTestAuthLSIDCookie1);
1148 // Verifies that when no offline login time limit is set, a user who
1149 // authenticated with SAML is allowed to log in offline.
1150 IN_PROC_BROWSER_TEST_P(SAMLPolicyTest, SAMLNoLimit) {
1151 login_screen_load_observer_->Wait();
1152 // Verify that offline login is allowed.
1153 JsExpect("window.getComputedStyle(document.querySelector("
1154 " '#pod-row .signin-button-container')).display == 'none'");
1157 IN_PROC_BROWSER_TEST_P(SAMLPolicyTest, PRE_SAMLZeroLimit) {
1158 // Set the offline login time limit for SAML users to zero.
1159 SetSAMLOfflineSigninTimeLimitPolicy(0);
1161 LogInWithSAML(kFirstSAMLUserEmail, kTestAuthSIDCookie1, kTestAuthLSIDCookie1);
1164 // Verifies that when the offline login time limit is exceeded for a user who
1165 // authenticated via SAML, that user is forced to log in online the next time.
1166 IN_PROC_BROWSER_TEST_P(SAMLPolicyTest, SAMLZeroLimit) {
1167 login_screen_load_observer_->Wait();
1168 // Verify that offline login is not allowed.
1169 JsExpect("window.getComputedStyle(document.querySelector("
1170 " '#pod-row .signin-button-container')).display != 'none'");
1173 IN_PROC_BROWSER_TEST_P(SAMLPolicyTest, PRE_PRE_TransferCookiesAffiliated) {
1174 fake_saml_idp()->SetCookieValue(kSAMLIdPCookieValue1);
1175 LogInWithSAML(kFirstSAMLUserEmail, kTestAuthSIDCookie1, kTestAuthLSIDCookie1);
1177 GetCookies();
1178 EXPECT_EQ(kTestAuthSIDCookie1, GetCookieValue(kGAIASIDCookieName));
1179 EXPECT_EQ(kTestAuthLSIDCookie1, GetCookieValue(kGAIALSIDCookieName));
1180 EXPECT_EQ(kSAMLIdPCookieValue1, GetCookieValue(kSAMLIdPCookieName));
1183 // Verifies that when the DeviceTransferSAMLCookies policy is not enabled, SAML
1184 // IdP cookies are not transferred to a user's profile on subsequent login, even
1185 // if the user belongs to the domain that the device is enrolled into. Also
1186 // verifies that GAIA cookies are not transferred.
1187 IN_PROC_BROWSER_TEST_P(SAMLPolicyTest, PRE_TransferCookiesAffiliated) {
1188 fake_saml_idp()->SetCookieValue(kSAMLIdPCookieValue2);
1189 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
1190 ShowGAIALoginForm();
1191 LogInWithSAML(kFirstSAMLUserEmail, kTestAuthSIDCookie2, kTestAuthLSIDCookie2);
1193 GetCookies();
1194 EXPECT_EQ(kTestAuthSIDCookie1, GetCookieValue(kGAIASIDCookieName));
1195 EXPECT_EQ(kTestAuthLSIDCookie1, GetCookieValue(kGAIALSIDCookieName));
1196 EXPECT_EQ(kSAMLIdPCookieValue1, GetCookieValue(kSAMLIdPCookieName));
1199 // Verifies that when the DeviceTransferSAMLCookies policy is enabled, SAML IdP
1200 // cookies are transferred to a user's profile on subsequent login when the user
1201 // belongs to the domain that the device is enrolled into. Also verifies that
1202 // GAIA cookies are not transferred.
1203 IN_PROC_BROWSER_TEST_P(SAMLPolicyTest, TransferCookiesAffiliated) {
1204 fake_saml_idp()->SetCookieValue(kSAMLIdPCookieValue2);
1205 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
1206 ShowGAIALoginForm();
1208 EnableTransferSAMLCookiesPolicy();
1209 LogInWithSAML(kFirstSAMLUserEmail, kTestAuthSIDCookie2, kTestAuthLSIDCookie2);
1211 GetCookies();
1212 EXPECT_EQ(kTestAuthSIDCookie1, GetCookieValue(kGAIASIDCookieName));
1213 EXPECT_EQ(kTestAuthLSIDCookie1, GetCookieValue(kGAIALSIDCookieName));
1214 EXPECT_EQ(kSAMLIdPCookieValue2, GetCookieValue(kSAMLIdPCookieName));
1217 IN_PROC_BROWSER_TEST_P(SAMLPolicyTest, PRE_TransferCookiesUnaffiliated) {
1218 fake_saml_idp()->SetCookieValue(kSAMLIdPCookieValue1);
1219 LogInWithSAML(kDifferentDomainSAMLUserEmail,
1220 kTestAuthSIDCookie1,
1221 kTestAuthLSIDCookie1);
1223 GetCookies();
1224 EXPECT_EQ(kTestAuthSIDCookie1, GetCookieValue(kGAIASIDCookieName));
1225 EXPECT_EQ(kTestAuthLSIDCookie1, GetCookieValue(kGAIALSIDCookieName));
1226 EXPECT_EQ(kSAMLIdPCookieValue1, GetCookieValue(kSAMLIdPCookieName));
1229 // Verifies that even if the DeviceTransferSAMLCookies policy is enabled, SAML
1230 // IdP are not transferred to a user's profile on subsequent login if the user
1231 // does not belong to the domain that the device is enrolled into. Also verifies
1232 // that GAIA cookies are not transferred.
1233 IN_PROC_BROWSER_TEST_P(SAMLPolicyTest, TransferCookiesUnaffiliated) {
1234 fake_saml_idp()->SetCookieValue(kSAMLIdPCookieValue2);
1235 fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
1236 ShowGAIALoginForm();
1238 EnableTransferSAMLCookiesPolicy();
1239 LogInWithSAML(kDifferentDomainSAMLUserEmail,
1240 kTestAuthSIDCookie1,
1241 kTestAuthLSIDCookie1);
1243 GetCookies();
1244 EXPECT_EQ(kTestAuthSIDCookie1, GetCookieValue(kGAIASIDCookieName));
1245 EXPECT_EQ(kTestAuthLSIDCookie1, GetCookieValue(kGAIALSIDCookieName));
1246 EXPECT_EQ(kSAMLIdPCookieValue1, GetCookieValue(kSAMLIdPCookieName));
1249 INSTANTIATE_TEST_CASE_P(SamlSuite,
1250 SAMLPolicyTest,
1251 testing::Bool());
1253 } // namespace chromeos