15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file.
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <string>
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <vector>
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/bind.h"
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/command_line.h"
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/run_loop.h"
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/stl_util.h"
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/browser_process.h"
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chrome_notification_types.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/login/existing_user_controller.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/login/wizard_controller.h"
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chromeos/chromeos_switches.h"
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/policy/core/common/cloud/device_management_service.h"
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/policy/core/common/policy_switches.h"
256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h"
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/notification_observer.h"
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/notification_registrar.h"
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/notification_service.h"
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/test/test_utils.h"
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "google_apis/gaia/fake_gaia.h"
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "google_apis/gaia/gaia_switches.h"
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "google_apis/gaia/gaia_urls.h"
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/http/http_status_code.h"
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/test/embedded_test_server/embedded_test_server.h"
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/test/embedded_test_server/http_request.h"
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/test/embedded_test_server/http_response.h"
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "policy/proto/device_management_backend.pb.h"
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace chromeos {
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace {
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace em = enterprise_management;
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kDomain[] = "domain.com";
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kUsername[] = "user@domain.com";
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kUsernameOtherDomain[] = "user@other.com";
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const char kOAuthCodeCookie[] = "oauth_code=1234; Secure; HttpOnly";
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kOAuth2TokenPairData[] =
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "{"
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "  \"refresh_token\": \"1234\","
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "  \"access_token\": \"5678\","
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "  \"expires_in\": 3600"
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "}";
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kOAuth2AccessTokenData[] =
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "{"
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "  \"access_token\": \"5678\","
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "  \"expires_in\": 3600"
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "}";
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kDMRegisterRequest[] = "/device_management?request=register";
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kDMPolicyRequest[] = "/device_management?request=policy";
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void CopyLockResult(base::RunLoop* loop,
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    policy::EnterpriseInstallAttributes::LockResult* out,
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    policy::EnterpriseInstallAttributes::LockResult result) {
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  *out = result;
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  loop->Quit();
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)struct BlockingLoginTestParam {
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int steps;
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const char* username;
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const bool enroll_device;
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class BlockingLoginTest
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : public InProcessBrowserTest,
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      public content::NotificationObserver,
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      public testing::WithParamInterface<BlockingLoginTestParam> {
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  BlockingLoginTest() : profile_added_(NULL) {}
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Initialize the test server early, so that we can use its base url for
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // the command line flags.
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Use the login manager screens and the gaia auth extension.
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    command_line->AppendSwitch(switches::kLoginManager);
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    command_line->AppendSwitch(switches::kForceLoginManagerInTests);
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    command_line->AppendSwitchASCII(::switches::kAuthExtensionPath,
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    "gaia_auth");
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Redirect requests to gaia and the policy server to the test server.
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    command_line->AppendSwitchASCII(::switches::kGaiaUrl,
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    embedded_test_server()->base_url().spec());
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    command_line->AppendSwitchASCII(::switches::kLsoUrl,
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    embedded_test_server()->base_url().spec());
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    command_line->AppendSwitchASCII(
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        policy::switches::kDeviceManagementUrl,
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        embedded_test_server()->GetURL("/device_management").spec());
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void SetUpOnMainThread() OVERRIDE {
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    fake_gaia_.Initialize();
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    embedded_test_server()->RegisterRequestHandler(
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::Bind(&BlockingLoginTest::HandleRequest, base::Unretained(this)));
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    embedded_test_server()->RegisterRequestHandler(
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::Bind(&FakeGaia::HandleRequest, base::Unretained(&fake_gaia_)));
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    registrar_.Add(this,
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   chrome::NOTIFICATION_PROFILE_ADDED,
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   content::NotificationService::AllSources());
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void TearDownOnMainThread() OVERRIDE {
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    RunUntilIdle();
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_TRUE(responses_.empty());
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    STLDeleteElements(&responses_);
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void Observe(int type,
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       const content::NotificationSource& source,
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE {
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ASSERT_EQ(chrome::NOTIFICATION_PROFILE_ADDED, type);
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ASSERT_FALSE(profile_added_);
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    profile_added_ = content::Source<Profile>(source).ptr();
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void RunUntilIdle() {
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  policy::BrowserPolicyConnectorChromeOS* browser_policy_connector() {
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return g_browser_process->platform_part()
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        ->browser_policy_connector_chromeos();
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void SkipToSigninScreen() {
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    WizardController::SkipPostLoginScreensForTesting();
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    WizardController* wizard_controller =
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        WizardController::default_controller();
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ASSERT_TRUE(wizard_controller);
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    wizard_controller->SkipToLoginForTesting(LoginScreenContext());
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::WindowedNotificationObserver(
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        content::NotificationService::AllSources()).Wait();
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    RunUntilIdle();
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void EnrollDevice(const std::string& username) {
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::RunLoop loop;
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    policy::EnterpriseInstallAttributes::LockResult result;
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    browser_policy_connector()->GetInstallAttributes()->LockDevice(
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        username, policy::DEVICE_MODE_ENTERPRISE, "100200300",
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::Bind(&CopyLockResult, &loop, &result));
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    loop.Run();
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(policy::EnterpriseInstallAttributes::LOCK_SUCCESS, result);
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    RunUntilIdle();
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void Login(const std::string& username) {
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::WindowedNotificationObserver session_started_observer(
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        chrome::NOTIFICATION_SESSION_STARTED,
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        content::NotificationService::AllSources());
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ExistingUserController* controller =
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        ExistingUserController::current_controller();
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ASSERT_TRUE(controller);
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    WebUILoginDisplay* login_display =
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        static_cast<WebUILoginDisplay*>(controller->login_display());
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ASSERT_TRUE(login_display);
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    login_display->ShowSigninScreenForCreds(username, "password");
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Wait for the session to start after submitting the credentials. This
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // will wait until all the background requests are done.
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    session_started_observer.Wait();
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Handles an HTTP request sent to the test server. This handler either
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // uses a canned response in |responses_| if the request path matches one
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // of the URLs that we mock, otherwise this handler delegates to |fake_gaia_|.
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<net::test_server::HttpResponse> HandleRequest(
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const net::test_server::HttpRequest& request) {
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<net::test_server::HttpResponse> response;
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    GaiaUrls* gaia = GaiaUrls::GetInstance();
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (request.relative_url == gaia->client_login_to_oauth2_url().path() ||
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        request.relative_url == gaia->oauth2_token_url().path() ||
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        request.relative_url.find(kDMRegisterRequest) == 0 ||
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        request.relative_url.find(kDMPolicyRequest) == 0) {
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      if (!responses_.empty()) {
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        response.reset(responses_.back());
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        responses_.pop_back();
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      }
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return response.Pass();
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Creates a new canned response that will respond with the given HTTP
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // status |code|. That response is appended to |responses_| and will be the
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // next response used.
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Returns a reference to that response, so that it can be further customized.
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  net::test_server::BasicHttpResponse& PushResponse(net::HttpStatusCode code) {
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    net::test_server::BasicHttpResponse* response =
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        new net::test_server::BasicHttpResponse();
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    response->set_code(code);
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    responses_.push_back(response);
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return *response;
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Returns the body of the register response from the policy server.
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string GetRegisterResponse() {
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    em::DeviceManagementResponse response;
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    em::DeviceRegisterResponse* register_response =
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        response.mutable_register_response();
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    register_response->set_device_management_token("1234");
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    register_response->set_enrollment_type(
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        em::DeviceRegisterResponse::ENTERPRISE);
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    std::string data;
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_TRUE(response.SerializeToString(&data));
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return data;
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Returns the body of the fetch response from the policy server.
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string GetPolicyResponse() {
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    em::DeviceManagementResponse response;
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    response.mutable_policy_response()->add_response();
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    std::string data;
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_TRUE(response.SerializeToString(&data));
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return data;
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) protected:
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Profile* profile_added_;
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private:
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FakeGaia fake_gaia_;
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::vector<net::test_server::HttpResponse*> responses_;
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  content::NotificationRegistrar registrar_;
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BlockingLoginTest);
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)IN_PROC_BROWSER_TEST_P(BlockingLoginTest, LoginBlocksForUser) {
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Verify that there isn't a logged in user when the test starts.
2606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  user_manager::UserManager* user_manager = user_manager::UserManager::Get();
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(user_manager->IsUserLoggedIn());
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(browser_policy_connector()->IsEnterpriseManaged());
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(profile_added_);
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Enroll the device, if enrollment is enabled for this test instance.
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (GetParam().enroll_device) {
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EnrollDevice(kUsername);
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_FALSE(user_manager->IsUserLoggedIn());
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_TRUE(browser_policy_connector()->IsEnterpriseManaged());
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(kDomain, browser_policy_connector()->GetEnterpriseDomain());
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_FALSE(profile_added_);
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(policy::USER_AFFILIATION_MANAGED,
2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              browser_policy_connector()->GetUserAffiliation(kUsername));
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    RunUntilIdle();
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_FALSE(user_manager->IsKnownUser(kUsername));
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Skip the OOBE, go to the sign-in screen, and wait for the login screen to
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // become visible.
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SkipToSigninScreen();
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(profile_added_);
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Prepare the fake HTTP responses.
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (GetParam().steps < 5) {
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // If this instance is not going to complete the entire flow successfully
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // then the last step will fail.
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // This response body is important to make the gaia fetcher skip its delayed
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // retry behavior, which makes testing harder. If this is sent to the policy
2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // fetchers then it will make them fail too.
2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    PushResponse(net::HTTP_UNAUTHORIZED).set_content("Error=AccountDeleted");
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Push a response for each step that is going to succeed, in reverse order.
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  switch (GetParam().steps) {
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    default:
2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ADD_FAILURE() << "Invalid step number: " << GetParam().steps;
2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return;
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case 5:
3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      PushResponse(net::HTTP_OK).set_content(GetPolicyResponse());
3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case 4:
3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      PushResponse(net::HTTP_OK).set_content(GetRegisterResponse());
3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case 3:
3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      PushResponse(net::HTTP_OK).set_content(kOAuth2AccessTokenData);
3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case 2:
3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      PushResponse(net::HTTP_OK).set_content(kOAuth2TokenPairData);
3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case 1:
3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      PushResponse(net::HTTP_OK)
3156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          .AddCustomHeader("Set-Cookie", kOAuthCodeCookie);
3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      break;
3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case 0:
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      break;
3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Login now. This verifies that logging in with the canned responses (which
3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // may include failures) won't be blocked due to the potential failures.
3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(profile_added_);
3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Login(GetParam().username);
3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(profile_added_);
3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(user_manager->IsUserLoggedIn());
3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(user_manager->IsCurrentUserNew());
3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const BlockingLoginTestParam kBlockinLoginTestCases[] = {
3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 0, kUsername, true },
3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 1, kUsername, true },
3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 2, kUsername, true },
3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 3, kUsername, true },
3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 4, kUsername, true },
3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 5, kUsername, true },
3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 0, kUsername, false },
3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 1, kUsername, false },
3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 2, kUsername, false },
3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 3, kUsername, false },
3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 4, kUsername, false },
3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 5, kUsername, false },
3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 0, kUsernameOtherDomain, true },
3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 1, kUsernameOtherDomain, true },
3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 2, kUsernameOtherDomain, true },
3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 3, kUsernameOtherDomain, true },
3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 4, kUsernameOtherDomain, true },
3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    { 5, kUsernameOtherDomain, true },
3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)INSTANTIATE_TEST_CASE_P(BlockingLoginTestInstance,
3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        BlockingLoginTest,
3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        testing::ValuesIn(kBlockinLoginTestCases));
3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace chromeos
357