| Index: chrome/browser/chromeos/login/saml/saml_browsertest.cc
|
| diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
|
| index f0d0a6db6b3687f8c0fe89320b6d0ca7cb2f5023..e82f1d0b3968d3a17b4f6461df83b3775a106c7b 100644
|
| --- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc
|
| +++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
|
| @@ -2,13 +2,17 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| +#include <cstring>
|
| +
|
| #include "base/bind.h"
|
| #include "base/bind_helpers.h"
|
| #include "base/callback.h"
|
| #include "base/command_line.h"
|
| #include "base/files/file_path.h"
|
| #include "base/files/file_util.h"
|
| +#include "base/files/scoped_temp_dir.h"
|
| #include "base/location.h"
|
| +#include "base/macros.h"
|
| #include "base/memory/ref_counted.h"
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/path_service.h"
|
| @@ -31,6 +35,7 @@
|
| #include "chrome/browser/chromeos/profiles/profile_helper.h"
|
| #include "chrome/browser/chromeos/settings/cros_settings.h"
|
| #include "chrome/browser/lifetime/application_lifetime.h"
|
| +#include "chrome/browser/policy/test/local_policy_test_server.h"
|
| #include "chrome/browser/profiles/profile.h"
|
| #include "chrome/browser/ui/webui/signin/inline_login_ui.h"
|
| #include "chrome/common/chrome_paths.h"
|
| @@ -45,15 +50,20 @@
|
| #include "components/policy/core/browser/browser_policy_connector.h"
|
| #include "components/policy/core/common/mock_configuration_policy_provider.h"
|
| #include "components/policy/core/common/policy_map.h"
|
| +#include "components/policy/core/common/policy_switches.h"
|
| #include "components/policy/core/common/policy_types.h"
|
| #include "components/user_manager/user.h"
|
| #include "components/user_manager/user_manager.h"
|
| #include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/render_frame_host.h"
|
| #include "content/public/browser/web_contents.h"
|
| +#include "content/public/browser/web_contents_observer.h"
|
| #include "content/public/test/browser_test_utils.h"
|
| #include "content/public/test/test_utils.h"
|
| #include "google_apis/gaia/fake_gaia.h"
|
| +#include "google_apis/gaia/gaia_constants.h"
|
| #include "google_apis/gaia/gaia_switches.h"
|
| +#include "google_apis/gaia/gaia_urls.h"
|
| #include "net/base/url_util.h"
|
| #include "net/cookies/canonical_cookie.h"
|
| #include "net/cookies/cookie_monster.h"
|
| @@ -103,6 +113,10 @@ const char kSAMLIdPCookieValue2[] = "value-2";
|
|
|
| const char kRelayState[] = "RelayState";
|
|
|
| +const char kTestUserinfoToken[] = "fake-userinfo-token";
|
| +const char kTestRefreshToken[] = "fake-refresh-token";
|
| +const char kPolicy[] = "{\"managed_users\": [\"*\"]}";
|
| +
|
| // FakeSamlIdp serves IdP auth form and the form submission. The form is
|
| // served with the template's RelayState placeholder expanded to the real
|
| // RelayState parameter from request. The form submission redirects back to
|
| @@ -242,7 +256,7 @@ scoped_ptr<HttpResponse> FakeSamlIdp::BuildHTMLResponse(
|
|
|
| class SamlTest : public InProcessBrowserTest {
|
| public:
|
| - SamlTest() : saml_load_injected_(false) {}
|
| + SamlTest() : gaia_frame_parent_("signin-frame"), saml_load_injected_(false) {}
|
| virtual ~SamlTest() {}
|
|
|
| virtual void SetUp() override {
|
| @@ -340,7 +354,7 @@ class SamlTest : public InProcessBrowserTest {
|
| login_screen_load_observer_->Wait();
|
| }
|
|
|
| - void StartSamlAndWaitForIdpPageLoad(const std::string& gaia_email) {
|
| + virtual void StartSamlAndWaitForIdpPageLoad(const std::string& gaia_email) {
|
| WaitForSigninScreen();
|
|
|
| if (!saml_load_injected_) {
|
| @@ -415,7 +429,7 @@ class SamlTest : public InProcessBrowserTest {
|
| // Executes JavaScript code in the auth iframe hosted by gaia_auth extension.
|
| void ExecuteJsInSigninFrame(const std::string& js) {
|
| content::RenderFrameHost* frame = InlineLoginUI::GetAuthIframe(
|
| - GetLoginUI()->GetWebContents(), GURL(), "signin-frame");
|
| + GetLoginUI()->GetWebContents(), GURL(), gaia_frame_parent_);
|
| ASSERT_TRUE(content::ExecuteScript(frame, js));
|
| }
|
|
|
| @@ -425,11 +439,14 @@ class SamlTest : public InProcessBrowserTest {
|
| scoped_ptr<content::WindowedNotificationObserver> login_screen_load_observer_;
|
| FakeGaia fake_gaia_;
|
|
|
| - private:
|
| - FakeSamlIdp fake_saml_idp_;
|
| + std::string gaia_frame_parent_;
|
| +
|
| scoped_ptr<HTTPSForwarder> gaia_https_forwarder_;
|
| scoped_ptr<HTTPSForwarder> saml_https_forwarder_;
|
|
|
| + private:
|
| + FakeSamlIdp fake_saml_idp_;
|
| +
|
| bool saml_load_injected_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(SamlTest);
|
| @@ -639,6 +656,170 @@ IN_PROC_BROWSER_TEST_F(SamlTest, MetaRefreshToHTTPDisallowed) {
|
| WaitForAndGetFatalErrorMessage());
|
| }
|
|
|
| +class SAMLEnrollmentTest : public SamlTest,
|
| + public content::WebContentsObserver {
|
| + public:
|
| + SAMLEnrollmentTest();
|
| + ~SAMLEnrollmentTest() override;
|
| +
|
| + // SamlTest:
|
| + void SetUp() override;
|
| + void SetUpCommandLine(CommandLine* command_line) override;
|
| + void SetUpOnMainThread() override;
|
| + void StartSamlAndWaitForIdpPageLoad(const std::string& gaia_email) override;
|
| +
|
| + // content::WebContentsObserver:
|
| + void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
|
| + void DidFinishLoad(content::RenderFrameHost* render_frame_host,
|
| + const GURL& validated_url) override;
|
| +
|
| + void WaitForEnrollmentSuccess();
|
| +
|
| + private:
|
| + scoped_ptr<policy::LocalPolicyTestServer> test_server_;
|
| + base::ScopedTempDir temp_dir_;
|
| +
|
| + scoped_ptr<base::RunLoop> run_loop_;
|
| + content::RenderFrameHost* auth_frame_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(SAMLEnrollmentTest);
|
| +};
|
| +
|
| +SAMLEnrollmentTest::SAMLEnrollmentTest() : auth_frame_(nullptr) {
|
| + gaia_frame_parent_ = "oauth-enroll-signin-frame";
|
| +}
|
| +
|
| +SAMLEnrollmentTest::~SAMLEnrollmentTest() {
|
| +}
|
| +
|
| +void SAMLEnrollmentTest::SetUp() {
|
| + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
|
| + const base::FilePath policy_file =
|
| + temp_dir_.path().AppendASCII("policy.json");
|
| + ASSERT_EQ(static_cast<int>(strlen(kPolicy)),
|
| + base::WriteFile(policy_file, kPolicy, strlen(kPolicy)));
|
| +
|
| + test_server_.reset(new policy::LocalPolicyTestServer(policy_file));
|
| + ASSERT_TRUE(test_server_->Start());
|
| +
|
| + SamlTest::SetUp();
|
| +}
|
| +
|
| +void SAMLEnrollmentTest::SetUpCommandLine(CommandLine* command_line) {
|
| + command_line->AppendSwitchASCII(policy::switches::kDeviceManagementUrl,
|
| + test_server_->GetServiceURL().spec());
|
| + command_line->AppendSwitch(policy::switches::kDisablePolicyKeyVerification);
|
| + command_line->AppendSwitch(switches::kEnterpriseEnrollmentSkipRobotAuth);
|
| +
|
| + SamlTest::SetUpCommandLine(command_line);
|
| +}
|
| +
|
| +void SAMLEnrollmentTest::SetUpOnMainThread() {
|
| + Observe(GetLoginUI()->GetWebContents());
|
| +
|
| + FakeGaia::AccessTokenInfo token_info;
|
| + token_info.token = kTestUserinfoToken;
|
| + token_info.scopes.insert(GaiaConstants::kDeviceManagementServiceOAuth);
|
| + token_info.scopes.insert(GaiaConstants::kOAuthWrapBridgeUserInfoScope);
|
| + token_info.audience = GaiaUrls::GetInstance()->oauth2_chrome_client_id();
|
| + token_info.email = kFirstSAMLUserEmail;
|
| + fake_gaia_.IssueOAuthToken(kTestRefreshToken, token_info);
|
| +
|
| + SamlTest::SetUpOnMainThread();
|
| +}
|
| +
|
| +void SAMLEnrollmentTest::StartSamlAndWaitForIdpPageLoad(
|
| + const std::string& gaia_email) {
|
| + WaitForSigninScreen();
|
| + run_loop_.reset(new base::RunLoop);
|
| + ExistingUserController::current_controller()->OnStartEnterpriseEnrollment();
|
| + run_loop_->Run();
|
| +
|
| + SetSignFormField("Email", gaia_email);
|
| +
|
| + run_loop_.reset(new base::RunLoop);
|
| + ExecuteJsInSigninFrame("document.getElementById('signIn').click();");
|
| + run_loop_->Run();
|
| +}
|
| +
|
| +void SAMLEnrollmentTest::RenderFrameCreated(
|
| + content::RenderFrameHost* render_frame_host) {
|
| + content::RenderFrameHost* parent = render_frame_host->GetParent();
|
| + if (!parent || parent->GetFrameName() != gaia_frame_parent_)
|
| + return;
|
| +
|
| + // The GAIA extension created the iframe in which the login form will be
|
| + // shown. Now wait for the login form to finish loading.
|
| + auth_frame_ = render_frame_host;
|
| + Observe(content::WebContents::FromRenderFrameHost(auth_frame_));
|
| +}
|
| +
|
| +void SAMLEnrollmentTest::DidFinishLoad(
|
| + content::RenderFrameHost* render_frame_host,
|
| + const GURL& validated_url) {
|
| + if (render_frame_host != auth_frame_)
|
| + return;
|
| +
|
| + const GURL origin = validated_url.GetOrigin();
|
| + if (origin != gaia_https_forwarder_->GetURL("") &&
|
| + origin != saml_https_forwarder_->GetURL("")) {
|
| + return;
|
| + }
|
| +
|
| + // The GAIA or SAML IdP login form finished loading.
|
| + if (run_loop_)
|
| + run_loop_->Quit();
|
| +}
|
| +
|
| +// Waits until the class |oauth-enroll-state-success| becomes set for the
|
| +// enrollment screen, indicating enrollment success.
|
| +void SAMLEnrollmentTest::WaitForEnrollmentSuccess() {
|
| + bool done = false;
|
| + ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
|
| + GetLoginUI()->GetWebContents(),
|
| + "var enrollmentScreen = document.getElementById('oauth-enrollment');"
|
| + "function SendReplyIfEnrollmentDone() {"
|
| + " if (!enrollmentScreen.classList.contains("
|
| + " 'oauth-enroll-state-success')) {"
|
| + " return false;"
|
| + " }"
|
| + " domAutomationController.send(true);"
|
| + " observer.disconnect();"
|
| + " return true;"
|
| + "}"
|
| + "var observer = new MutationObserver(SendReplyIfEnrollmentDone);"
|
| + "if (!SendReplyIfEnrollmentDone()) {"
|
| + " var options = { attributes: true, attributeFilter: [ 'class' ] };"
|
| + " observer.observe(enrollmentScreen, options);"
|
| + "}",
|
| + &done));
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(SAMLEnrollmentTest, WithoutCredentialsPassingAPI) {
|
| + fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
|
| + StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
|
| +
|
| + // Fill-in the SAML IdP form and submit.
|
| + SetSignFormField("Email", "fake_user");
|
| + SetSignFormField("Password", "fake_password");
|
| + ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
|
| +
|
| + WaitForEnrollmentSuccess();
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(SAMLEnrollmentTest, WithCredentialsPassingAPI) {
|
| + fake_saml_idp()->SetLoginHTMLTemplate("saml_api_login.html");
|
| + fake_saml_idp()->SetLoginAuthHTMLTemplate("saml_api_login_auth.html");
|
| + StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
|
| +
|
| + // Fill-in the SAML IdP form and submit.
|
| + SetSignFormField("Email", "fake_user");
|
| + SetSignFormField("Password", "fake_password");
|
| + ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
|
| +
|
| + WaitForEnrollmentSuccess();
|
| +}
|
| +
|
| class SAMLPolicyTest : public SamlTest {
|
| public:
|
| SAMLPolicyTest();
|
|
|