Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / chromeos / policy / blocking_login_browsertest.cc
blobdabc1f7acffcb24e4f000deab10a6052e837bf63
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 <string>
6 #include <vector>
8 #include "base/bind.h"
9 #include "base/command_line.h"
10 #include "base/run_loop.h"
11 #include "base/stl_util.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/chromeos/login/existing_user_controller.h"
15 #include "chrome/browser/chromeos/login/ui/webui_login_display.h"
16 #include "chrome/browser/chromeos/login/wizard_controller.h"
17 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
18 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
19 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
20 #include "chrome/common/chrome_switches.h"
21 #include "chrome/test/base/in_process_browser_test.h"
22 #include "chromeos/chromeos_switches.h"
23 #include "components/policy/core/common/cloud/device_management_service.h"
24 #include "components/policy/core/common/policy_switches.h"
25 #include "components/user_manager/user_manager.h"
26 #include "content/public/browser/notification_observer.h"
27 #include "content/public/browser/notification_registrar.h"
28 #include "content/public/browser/notification_service.h"
29 #include "content/public/test/test_utils.h"
30 #include "google_apis/gaia/fake_gaia.h"
31 #include "google_apis/gaia/gaia_switches.h"
32 #include "google_apis/gaia/gaia_urls.h"
33 #include "net/http/http_status_code.h"
34 #include "net/test/embedded_test_server/embedded_test_server.h"
35 #include "net/test/embedded_test_server/http_request.h"
36 #include "net/test/embedded_test_server/http_response.h"
37 #include "policy/proto/device_management_backend.pb.h"
38 #include "testing/gtest/include/gtest/gtest.h"
40 namespace chromeos {
42 namespace {
44 namespace em = enterprise_management;
46 const char kDomain[] = "domain.com";
47 const char kUsername[] = "user@domain.com";
48 const char kUsernameOtherDomain[] = "user@other.com";
50 const char kOAuthCodeCookie[] = "oauth_code=1234; Secure; HttpOnly";
52 const char kOAuth2TokenPairData[] =
53 "{"
54 " \"refresh_token\": \"1234\","
55 " \"access_token\": \"5678\","
56 " \"expires_in\": 3600"
57 "}";
59 const char kOAuth2AccessTokenData[] =
60 "{"
61 " \"access_token\": \"5678\","
62 " \"expires_in\": 3600"
63 "}";
65 const char kDMRegisterRequest[] = "/device_management?request=register";
66 const char kDMPolicyRequest[] = "/device_management?request=policy";
68 void CopyLockResult(base::RunLoop* loop,
69 policy::EnterpriseInstallAttributes::LockResult* out,
70 policy::EnterpriseInstallAttributes::LockResult result) {
71 *out = result;
72 loop->Quit();
75 } // namespace
77 struct BlockingLoginTestParam {
78 const int steps;
79 const char* username;
80 const bool enroll_device;
83 class BlockingLoginTest
84 : public InProcessBrowserTest,
85 public content::NotificationObserver,
86 public testing::WithParamInterface<BlockingLoginTestParam> {
87 public:
88 BlockingLoginTest() : profile_added_(NULL) {}
90 void SetUpCommandLine(base::CommandLine* command_line) override {
91 // Initialize the test server early, so that we can use its base url for
92 // the command line flags.
93 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
95 // Use the login manager screens and the gaia auth extension.
96 command_line->AppendSwitch(switches::kLoginManager);
97 command_line->AppendSwitch(switches::kForceLoginManagerInTests);
98 command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
99 command_line->AppendSwitchASCII(::switches::kAuthExtensionPath,
100 "gaia_auth");
102 // Redirect requests to gaia and the policy server to the test server.
103 command_line->AppendSwitchASCII(::switches::kGaiaUrl,
104 embedded_test_server()->base_url().spec());
105 command_line->AppendSwitchASCII(::switches::kLsoUrl,
106 embedded_test_server()->base_url().spec());
107 command_line->AppendSwitchASCII(
108 policy::switches::kDeviceManagementUrl,
109 embedded_test_server()->GetURL("/device_management").spec());
112 void SetUpOnMainThread() override {
113 fake_gaia_.Initialize();
115 embedded_test_server()->RegisterRequestHandler(
116 base::Bind(&BlockingLoginTest::HandleRequest, base::Unretained(this)));
117 embedded_test_server()->RegisterRequestHandler(
118 base::Bind(&FakeGaia::HandleRequest, base::Unretained(&fake_gaia_)));
120 registrar_.Add(this,
121 chrome::NOTIFICATION_PROFILE_ADDED,
122 content::NotificationService::AllSources());
125 void TearDownOnMainThread() override {
126 RunUntilIdle();
127 EXPECT_TRUE(responses_.empty());
128 STLDeleteElements(&responses_);
129 EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
132 void Observe(int type,
133 const content::NotificationSource& source,
134 const content::NotificationDetails& details) override {
135 ASSERT_EQ(chrome::NOTIFICATION_PROFILE_ADDED, type);
136 ASSERT_FALSE(profile_added_);
137 profile_added_ = content::Source<Profile>(source).ptr();
140 void RunUntilIdle() {
141 base::RunLoop().RunUntilIdle();
144 policy::BrowserPolicyConnectorChromeOS* browser_policy_connector() {
145 return g_browser_process->platform_part()
146 ->browser_policy_connector_chromeos();
149 void SkipToSigninScreen() {
150 WizardController::SkipPostLoginScreensForTesting();
151 WizardController* wizard_controller =
152 WizardController::default_controller();
153 ASSERT_TRUE(wizard_controller);
154 wizard_controller->SkipToLoginForTesting(LoginScreenContext());
156 content::WindowedNotificationObserver(
157 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
158 content::NotificationService::AllSources()).Wait();
159 RunUntilIdle();
162 void EnrollDevice(const std::string& username) {
163 base::RunLoop loop;
164 policy::EnterpriseInstallAttributes::LockResult result;
165 browser_policy_connector()->GetInstallAttributes()->LockDevice(
166 username, policy::DEVICE_MODE_ENTERPRISE, "100200300",
167 base::Bind(&CopyLockResult, &loop, &result));
168 loop.Run();
169 EXPECT_EQ(policy::EnterpriseInstallAttributes::LOCK_SUCCESS, result);
170 RunUntilIdle();
173 void Login(const std::string& username) {
174 content::WindowedNotificationObserver session_started_observer(
175 chrome::NOTIFICATION_SESSION_STARTED,
176 content::NotificationService::AllSources());
178 ExistingUserController* controller =
179 ExistingUserController::current_controller();
180 ASSERT_TRUE(controller);
181 WebUILoginDisplay* login_display =
182 static_cast<WebUILoginDisplay*>(controller->login_display());
183 ASSERT_TRUE(login_display);
185 login_display->ShowSigninScreenForCreds(username, "password");
187 // Wait for the session to start after submitting the credentials. This
188 // will wait until all the background requests are done.
189 session_started_observer.Wait();
192 // Handles an HTTP request sent to the test server. This handler either
193 // uses a canned response in |responses_| if the request path matches one
194 // of the URLs that we mock, otherwise this handler delegates to |fake_gaia_|.
195 scoped_ptr<net::test_server::HttpResponse> HandleRequest(
196 const net::test_server::HttpRequest& request) {
197 scoped_ptr<net::test_server::HttpResponse> response;
199 GaiaUrls* gaia = GaiaUrls::GetInstance();
200 if (request.relative_url == gaia->client_login_to_oauth2_url().path() ||
201 request.relative_url == gaia->oauth2_token_url().path() ||
202 request.relative_url.find(kDMRegisterRequest) == 0 ||
203 request.relative_url.find(kDMPolicyRequest) == 0) {
204 if (!responses_.empty()) {
205 response.reset(responses_.back());
206 responses_.pop_back();
210 return response.Pass();
213 // Creates a new canned response that will respond with the given HTTP
214 // status |code|. That response is appended to |responses_| and will be the
215 // next response used.
216 // Returns a reference to that response, so that it can be further customized.
217 net::test_server::BasicHttpResponse& PushResponse(net::HttpStatusCode code) {
218 net::test_server::BasicHttpResponse* response =
219 new net::test_server::BasicHttpResponse();
220 response->set_code(code);
221 responses_.push_back(response);
222 return *response;
225 // Returns the body of the register response from the policy server.
226 std::string GetRegisterResponse() {
227 em::DeviceManagementResponse response;
228 em::DeviceRegisterResponse* register_response =
229 response.mutable_register_response();
230 register_response->set_device_management_token("1234");
231 register_response->set_enrollment_type(
232 em::DeviceRegisterResponse::ENTERPRISE);
233 std::string data;
234 EXPECT_TRUE(response.SerializeToString(&data));
235 return data;
238 // Returns the body of the fetch response from the policy server.
239 std::string GetPolicyResponse() {
240 em::DeviceManagementResponse response;
241 response.mutable_policy_response()->add_response();
242 std::string data;
243 EXPECT_TRUE(response.SerializeToString(&data));
244 return data;
247 protected:
248 Profile* profile_added_;
250 private:
251 FakeGaia fake_gaia_;
252 std::vector<net::test_server::HttpResponse*> responses_;
253 content::NotificationRegistrar registrar_;
255 DISALLOW_COPY_AND_ASSIGN(BlockingLoginTest);
258 IN_PROC_BROWSER_TEST_P(BlockingLoginTest, LoginBlocksForUser) {
259 // Verify that there isn't a logged in user when the test starts.
260 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
261 EXPECT_FALSE(user_manager->IsUserLoggedIn());
262 EXPECT_FALSE(browser_policy_connector()->IsEnterpriseManaged());
263 EXPECT_FALSE(profile_added_);
265 // Enroll the device, if enrollment is enabled for this test instance.
266 if (GetParam().enroll_device) {
267 EnrollDevice(kUsername);
269 EXPECT_FALSE(user_manager->IsUserLoggedIn());
270 EXPECT_TRUE(browser_policy_connector()->IsEnterpriseManaged());
271 EXPECT_EQ(kDomain, browser_policy_connector()->GetEnterpriseDomain());
272 EXPECT_FALSE(profile_added_);
273 EXPECT_EQ(policy::USER_AFFILIATION_MANAGED,
274 browser_policy_connector()->GetUserAffiliation(kUsername));
275 RunUntilIdle();
276 EXPECT_FALSE(user_manager->IsKnownUser(kUsername));
279 // Skip the OOBE, go to the sign-in screen, and wait for the login screen to
280 // become visible.
281 SkipToSigninScreen();
282 EXPECT_FALSE(profile_added_);
284 // Prepare the fake HTTP responses.
285 if (GetParam().steps < 5) {
286 // If this instance is not going to complete the entire flow successfully
287 // then the last step will fail.
289 // This response body is important to make the gaia fetcher skip its delayed
290 // retry behavior, which makes testing harder. If this is sent to the policy
291 // fetchers then it will make them fail too.
292 PushResponse(net::HTTP_UNAUTHORIZED).set_content("Error=AccountDeleted");
295 // Push a response for each step that is going to succeed, in reverse order.
296 switch (GetParam().steps) {
297 default:
298 ADD_FAILURE() << "Invalid step number: " << GetParam().steps;
299 return;
301 case 5:
302 PushResponse(net::HTTP_OK).set_content(GetPolicyResponse());
304 case 4:
305 PushResponse(net::HTTP_OK).set_content(GetRegisterResponse());
307 case 3:
308 PushResponse(net::HTTP_OK).set_content(kOAuth2AccessTokenData);
310 case 2:
311 PushResponse(net::HTTP_OK).set_content(kOAuth2TokenPairData);
313 case 1:
314 PushResponse(net::HTTP_OK)
315 .AddCustomHeader("Set-Cookie", kOAuthCodeCookie);
316 break;
318 case 0:
319 break;
322 // Login now. This verifies that logging in with the canned responses (which
323 // may include failures) won't be blocked due to the potential failures.
324 EXPECT_FALSE(profile_added_);
325 Login(GetParam().username);
326 EXPECT_TRUE(profile_added_);
327 ASSERT_TRUE(user_manager->IsUserLoggedIn());
328 EXPECT_TRUE(user_manager->IsCurrentUserNew());
331 const BlockingLoginTestParam kBlockinLoginTestCases[] = {
332 { 0, kUsername, true },
333 { 1, kUsername, true },
334 { 2, kUsername, true },
335 { 3, kUsername, true },
336 { 4, kUsername, true },
337 { 5, kUsername, true },
338 { 0, kUsername, false },
339 { 1, kUsername, false },
340 { 2, kUsername, false },
341 { 3, kUsername, false },
342 { 4, kUsername, false },
343 { 5, kUsername, false },
344 { 0, kUsernameOtherDomain, true },
345 { 1, kUsernameOtherDomain, true },
346 { 2, kUsernameOtherDomain, true },
347 { 3, kUsernameOtherDomain, true },
348 { 4, kUsernameOtherDomain, true },
349 { 5, kUsernameOtherDomain, true },
352 INSTANTIATE_TEST_CASE_P(BlockingLoginTestInstance,
353 BlockingLoginTest,
354 testing::ValuesIn(kBlockinLoginTestCases));
356 } // namespace chromeos