OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <map> | 5 #include <map> |
6 #include <string> | 6 #include <string> |
7 | 7 |
8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
bartfab (slow)
2013/03/07 12:17:23
You seem to have missed my comment: This is no lon
dconnelly
2013/03/07 14:45:19
Done.
| |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
13 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
14 #include "base/files/scoped_temp_dir.h" | 14 #include "base/files/scoped_temp_dir.h" |
15 #include "base/message_loop.h" | 15 #include "base/message_loop.h" |
16 #include "base/path_service.h" | 16 #include "base/path_service.h" |
17 #include "base/run_loop.h" | 17 #include "base/run_loop.h" |
18 #include "base/stl_util.h" | 18 #include "base/stl_util.h" |
19 #include "base/string_util.h" | 19 #include "base/string_util.h" |
20 #include "base/utf_string_conversions.h" | 20 #include "base/utf_string_conversions.h" |
(...skipping 15 matching lines...) Expand all Loading... | |
36 #include "chrome/browser/ui/browser_finder.h" | 36 #include "chrome/browser/ui/browser_finder.h" |
37 #include "chrome/browser/ui/host_desktop.h" | 37 #include "chrome/browser/ui/host_desktop.h" |
38 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 38 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
39 #include "chrome/common/chrome_notification_types.h" | 39 #include "chrome/common/chrome_notification_types.h" |
40 #include "chrome/common/chrome_paths.h" | 40 #include "chrome/common/chrome_paths.h" |
41 #include "chrome/common/chrome_switches.h" | 41 #include "chrome/common/chrome_switches.h" |
42 #include "chrome/test/base/in_process_browser_test.h" | 42 #include "chrome/test/base/in_process_browser_test.h" |
43 #include "chromeos/dbus/cryptohome_client.h" | 43 #include "chromeos/dbus/cryptohome_client.h" |
44 #include "chromeos/dbus/dbus_method_call_status.h" | 44 #include "chromeos/dbus/dbus_method_call_status.h" |
45 #include "chromeos/dbus/dbus_thread_manager.h" | 45 #include "chromeos/dbus/dbus_thread_manager.h" |
46 #include "chromeos/dbus/fake_session_manager_client.h" | |
46 #include "chromeos/dbus/mock_dbus_thread_manager.h" | 47 #include "chromeos/dbus/mock_dbus_thread_manager.h" |
47 #include "chromeos/dbus/session_manager_client.h" | |
48 #include "content/public/browser/notification_observer.h" | 48 #include "content/public/browser/notification_observer.h" |
bartfab (slow)
2013/03/07 12:17:23
You seem to have missed my comment: This is no lon
dconnelly
2013/03/07 14:45:19
Done.
| |
49 #include "content/public/browser/notification_registrar.h" | 49 #include "content/public/browser/notification_registrar.h" |
bartfab (slow)
2013/03/07 12:17:23
You seem to have missed my comment: This is no lon
dconnelly
2013/03/07 14:45:19
Done.
| |
50 #include "content/public/browser/notification_service.h" | 50 #include "content/public/browser/notification_service.h" |
bartfab (slow)
2013/03/07 12:17:23
You seem to have missed my comment: This is no lon
dconnelly
2013/03/07 14:45:19
Done.
| |
51 #include "content/public/browser/web_contents.h" | 51 #include "content/public/browser/web_contents.h" |
52 #include "content/public/test/notification_watcher.h" | |
52 #include "testing/gmock/include/gmock/gmock.h" | 53 #include "testing/gmock/include/gmock/gmock.h" |
53 #include "third_party/cros_system_api/dbus/service_constants.h" | 54 #include "third_party/cros_system_api/dbus/service_constants.h" |
54 | 55 |
55 namespace em = enterprise_management; | 56 namespace em = enterprise_management; |
56 | 57 |
57 using testing::Return; | 58 using testing::Return; |
58 | 59 |
59 namespace policy { | 60 namespace policy { |
60 | 61 |
61 namespace { | 62 namespace { |
62 | 63 |
63 const char kAccountId1[] = "dla1@example.com"; | 64 const char kAccountId1[] = "dla1@example.com"; |
64 const char kAccountId2[] = "dla2@example.com"; | 65 const char kAccountId2[] = "dla2@example.com"; |
65 const char kDisplayName1[] = "display name for account 1"; | 66 const char kDisplayName1[] = "display name for account 1"; |
66 const char kDisplayName2[] = "display name for account 2"; | 67 const char kDisplayName2[] = "display name for account 2"; |
67 const char* kStartupURLs[] = { | 68 const char* kStartupURLs[] = { |
68 "chrome://policy", | 69 "chrome://policy", |
69 "chrome://about", | 70 "chrome://about", |
70 }; | 71 }; |
71 | 72 |
72 // Observes a specific notification type and quits the message loop once a | |
73 // condition holds. | |
74 class NotificationWatcher : public content::NotificationObserver { | |
75 public: | |
76 // Callback invoked on notifications. Should return true when the condition | |
77 // that the caller is waiting for is satisfied. | |
78 typedef base::Callback<bool(void)> ConditionTestCallback; | |
79 | |
80 explicit NotificationWatcher(int notification_type, | |
81 const ConditionTestCallback& callback) | |
82 : type_(notification_type), | |
83 callback_(callback) {} | |
84 | |
85 void Run() { | |
86 if (callback_.Run()) | |
87 return; | |
88 | |
89 content::NotificationRegistrar registrar; | |
90 registrar.Add(this, type_, content::NotificationService::AllSources()); | |
91 run_loop_.Run(); | |
92 } | |
93 | |
94 // content::NotificationObserver: | |
95 virtual void Observe(int type, | |
96 const content::NotificationSource& source, | |
97 const content::NotificationDetails& details) OVERRIDE { | |
98 if (callback_.Run()) | |
99 run_loop_.Quit(); | |
100 } | |
101 | |
102 private: | |
103 int type_; | |
104 ConditionTestCallback callback_; | |
105 base::RunLoop run_loop_; | |
106 | |
107 DISALLOW_COPY_AND_ASSIGN(NotificationWatcher); | |
108 }; | |
109 | |
110 // A fake implementation of session_manager. Accepts policy blobs to be set and | |
111 // returns them unmodified. | |
112 class FakeSessionManagerClient : public chromeos::SessionManagerClient { | |
113 public: | |
114 FakeSessionManagerClient() {} | |
115 virtual ~FakeSessionManagerClient() {} | |
116 | |
117 // SessionManagerClient: | |
118 virtual void AddObserver(Observer* observer) OVERRIDE {} | |
119 virtual void RemoveObserver(Observer* observer) OVERRIDE {} | |
120 virtual bool HasObserver(Observer* observer) OVERRIDE { return false; } | |
121 virtual void EmitLoginPromptReady() OVERRIDE {} | |
122 virtual void EmitLoginPromptVisible() OVERRIDE {} | |
123 virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {} | |
124 virtual void RestartEntd() OVERRIDE {} | |
125 virtual void StartSession(const std::string& user_email) OVERRIDE {} | |
126 virtual void StopSession() OVERRIDE {} | |
127 virtual void StartDeviceWipe() OVERRIDE {} | |
128 virtual void RequestLockScreen() OVERRIDE {} | |
129 virtual void NotifyLockScreenShown() OVERRIDE {} | |
130 virtual void RequestUnlockScreen() OVERRIDE {} | |
131 virtual void NotifyLockScreenDismissed() OVERRIDE {} | |
132 virtual void RetrieveDevicePolicy( | |
133 const RetrievePolicyCallback& callback) OVERRIDE { | |
134 MessageLoop::current()->PostTask(FROM_HERE, | |
135 base::Bind(callback, device_policy_)); | |
136 } | |
137 virtual void RetrieveUserPolicy( | |
138 const RetrievePolicyCallback& callback) OVERRIDE { | |
139 MessageLoop::current()->PostTask(FROM_HERE, | |
140 base::Bind(callback, user_policy_)); | |
141 } | |
142 virtual void RetrieveDeviceLocalAccountPolicy( | |
143 const std::string& account_id, | |
144 const RetrievePolicyCallback& callback) OVERRIDE { | |
145 MessageLoop::current()->PostTask( | |
146 FROM_HERE, | |
147 base::Bind(callback, device_local_account_policy_[account_id])); | |
148 } | |
149 virtual void StoreDevicePolicy(const std::string& policy_blob, | |
150 const StorePolicyCallback& callback) OVERRIDE { | |
151 device_policy_ = policy_blob; | |
152 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true)); | |
153 } | |
154 virtual void StoreUserPolicy(const std::string& policy_blob, | |
155 const StorePolicyCallback& callback) OVERRIDE { | |
156 user_policy_ = policy_blob; | |
157 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true)); | |
158 } | |
159 virtual void StoreDeviceLocalAccountPolicy( | |
160 const std::string& account_id, | |
161 const std::string& policy_blob, | |
162 const StorePolicyCallback& callback) OVERRIDE { | |
163 device_local_account_policy_[account_id] = policy_blob; | |
164 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true)); | |
165 } | |
166 | |
167 const std::string& device_policy() const { | |
168 return device_policy_; | |
169 } | |
170 void set_device_policy(const std::string& policy_blob) { | |
171 device_policy_ = policy_blob; | |
172 } | |
173 | |
174 const std::string& user_policy() const { | |
175 return user_policy_; | |
176 } | |
177 void set_user_policy(const std::string& policy_blob) { | |
178 user_policy_ = policy_blob; | |
179 } | |
180 | |
181 const std::string& device_local_account_policy( | |
182 const std::string& account_id) const { | |
183 std::map<std::string, std::string>::const_iterator entry = | |
184 device_local_account_policy_.find(account_id); | |
185 return entry != device_local_account_policy_.end() ? entry->second | |
186 : EmptyString(); | |
187 } | |
188 void set_device_local_account_policy(const std::string& account_id, | |
189 const std::string& policy_blob) { | |
190 device_local_account_policy_[account_id] = policy_blob; | |
191 } | |
192 | |
193 private: | |
194 std::string device_policy_; | |
195 std::string user_policy_; | |
196 std::map<std::string, std::string> device_local_account_policy_; | |
197 | |
198 DISALLOW_COPY_AND_ASSIGN(FakeSessionManagerClient); | |
199 }; | |
200 | |
201 class FakeCryptohomeClient : public chromeos::CryptohomeClient { | 73 class FakeCryptohomeClient : public chromeos::CryptohomeClient { |
202 public: | 74 public: |
203 using chromeos::CryptohomeClient::AsyncMethodCallback; | 75 using chromeos::CryptohomeClient::AsyncMethodCallback; |
204 using chromeos::CryptohomeClient::AsyncCallStatusHandler; | 76 using chromeos::CryptohomeClient::AsyncCallStatusHandler; |
205 using chromeos::CryptohomeClient::AsyncCallStatusWithDataHandler; | 77 using chromeos::CryptohomeClient::AsyncCallStatusWithDataHandler; |
206 | 78 |
207 FakeCryptohomeClient() {} | 79 FakeCryptohomeClient() {} |
208 virtual ~FakeCryptohomeClient() {} | 80 virtual ~FakeCryptohomeClient() {} |
209 | 81 |
210 virtual void SetAsyncCallStatusHandlers( | 82 virtual void SetAsyncCallStatusHandlers( |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
477 void CheckPublicSessionPresent(const std::string& id) { | 349 void CheckPublicSessionPresent(const std::string& id) { |
478 const chromeos::User* user = chromeos::UserManager::Get()->FindUser(id); | 350 const chromeos::User* user = chromeos::UserManager::Get()->FindUser(id); |
479 ASSERT_TRUE(user); | 351 ASSERT_TRUE(user); |
480 EXPECT_EQ(id, user->email()); | 352 EXPECT_EQ(id, user->email()); |
481 EXPECT_EQ(chromeos::User::USER_TYPE_PUBLIC_ACCOUNT, user->GetType()); | 353 EXPECT_EQ(chromeos::User::USER_TYPE_PUBLIC_ACCOUNT, user->GetType()); |
482 } | 354 } |
483 | 355 |
484 LocalPolicyTestServer test_server_; | 356 LocalPolicyTestServer test_server_; |
485 base::ScopedTempDir temp_dir_; | 357 base::ScopedTempDir temp_dir_; |
486 | 358 |
487 FakeSessionManagerClient session_manager_client_; | 359 chromeos::FakeSessionManagerClient session_manager_client_; |
488 FakeCryptohomeClient cryptohome_client_; | 360 FakeCryptohomeClient cryptohome_client_; |
489 }; | 361 }; |
490 | 362 |
491 static bool IsKnownUser(const std::string& account_id) { | 363 static bool IsKnownUser(const std::string& account_id) { |
492 return chromeos::UserManager::Get()->IsKnownUser(account_id); | 364 return chromeos::UserManager::Get()->IsKnownUser(account_id); |
493 } | 365 } |
494 | 366 |
495 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, LoginScreen) { | 367 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, LoginScreen) { |
496 NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, | 368 content::NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, |
497 base::Bind(&IsKnownUser, kAccountId1)).Run(); | 369 base::Bind(&IsKnownUser, kAccountId1)).Run(); |
498 NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, | 370 content::NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, |
499 base::Bind(&IsKnownUser, kAccountId2)).Run(); | 371 base::Bind(&IsKnownUser, kAccountId2)).Run(); |
500 | 372 |
501 CheckPublicSessionPresent(kAccountId1); | 373 CheckPublicSessionPresent(kAccountId1); |
502 CheckPublicSessionPresent(kAccountId2); | 374 CheckPublicSessionPresent(kAccountId2); |
503 } | 375 } |
504 | 376 |
505 static bool DisplayNameMatches(const std::string& account_id, | 377 static bool DisplayNameMatches(const std::string& account_id, |
506 const std::string& display_name) { | 378 const std::string& display_name) { |
507 const chromeos::User* user = | 379 const chromeos::User* user = |
508 chromeos::UserManager::Get()->FindUser(account_id); | 380 chromeos::UserManager::Get()->FindUser(account_id); |
509 if (!user || user->display_name().empty()) | 381 if (!user || user->display_name().empty()) |
510 return false; | 382 return false; |
511 EXPECT_EQ(UTF8ToUTF16(display_name), user->display_name()); | 383 EXPECT_EQ(UTF8ToUTF16(display_name), user->display_name()); |
512 return true; | 384 return true; |
513 } | 385 } |
514 | 386 |
515 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DisplayName) { | 387 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DisplayName) { |
516 NotificationWatcher( | 388 content::NotificationWatcher( |
517 chrome::NOTIFICATION_USER_LIST_CHANGED, | 389 chrome::NOTIFICATION_USER_LIST_CHANGED, |
518 base::Bind(&DisplayNameMatches, kAccountId1, kDisplayName1)).Run(); | 390 base::Bind(&DisplayNameMatches, kAccountId1, kDisplayName1)).Run(); |
519 } | 391 } |
520 | 392 |
521 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, PolicyDownload) { | 393 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, PolicyDownload) { |
522 // Policy for kAccountId2 is not installed in session_manager_client, make | 394 // Policy for kAccountId2 is not installed in session_manager_client, make |
523 // sure it gets fetched from the server. Note that the test setup doesn't set | 395 // sure it gets fetched from the server. Note that the test setup doesn't set |
524 // up policy for kAccountId2, so the presence of the display name can be used | 396 // up policy for kAccountId2, so the presence of the display name can be used |
525 // as signal to indicate successful policy download. | 397 // as signal to indicate successful policy download. |
526 NotificationWatcher( | 398 ASSERT_TRUE(session_manager_client_.device_local_account_policy( |
399 kAccountId2).empty()); | |
400 content::NotificationWatcher( | |
527 chrome::NOTIFICATION_USER_LIST_CHANGED, | 401 chrome::NOTIFICATION_USER_LIST_CHANGED, |
528 base::Bind(&DisplayNameMatches, kAccountId2, kDisplayName2)).Run(); | 402 base::Bind(&DisplayNameMatches, kAccountId2, kDisplayName2)).Run(); |
529 | 403 |
530 // Sanity check: The policy should be present now. | 404 // Sanity check: The policy should be present now. |
531 ASSERT_FALSE(session_manager_client_.device_local_account_policy( | 405 ASSERT_FALSE(session_manager_client_.device_local_account_policy( |
532 kAccountId2).empty()); | 406 kAccountId2).empty()); |
533 } | 407 } |
534 | 408 |
535 static bool IsNotKnownUser(const std::string& account_id) { | 409 static bool IsNotKnownUser(const std::string& account_id) { |
536 return !IsKnownUser(account_id); | 410 return !IsKnownUser(account_id); |
537 } | 411 } |
538 | 412 |
539 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DevicePolicyChange) { | 413 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DevicePolicyChange) { |
540 // Wait until the login screen is up. | 414 // Wait until the login screen is up. |
541 NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, | 415 content::NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, |
542 base::Bind(&IsKnownUser, kAccountId1)).Run(); | 416 base::Bind(&IsKnownUser, kAccountId1)).Run(); |
543 NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, | 417 content::NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, |
544 base::Bind(&IsKnownUser, kAccountId2)).Run(); | 418 base::Bind(&IsKnownUser, kAccountId2)).Run(); |
545 | 419 |
546 // Update policy to remove kAccountId2. | 420 // Update policy to remove kAccountId2. |
547 em::ChromeDeviceSettingsProto policy; | 421 em::ChromeDeviceSettingsProto policy; |
548 policy.mutable_show_user_names()->set_show_user_names(true); | 422 policy.mutable_show_user_names()->set_show_user_names(true); |
549 policy.mutable_device_local_accounts()->add_account()->set_id(kAccountId1); | 423 policy.mutable_device_local_accounts()->add_account()->set_id(kAccountId1); |
550 | 424 |
551 test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, std::string(), | 425 test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, std::string(), |
552 policy.SerializeAsString()); | 426 policy.SerializeAsString()); |
553 g_browser_process->policy_service()->RefreshPolicies(base::Closure()); | 427 g_browser_process->policy_service()->RefreshPolicies(base::Closure()); |
554 | 428 |
555 // Make sure the second device-local account disappears. | 429 // Make sure the second device-local account disappears. |
556 NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, | 430 content::NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, |
557 base::Bind(&IsNotKnownUser, kAccountId2)).Run(); | 431 base::Bind(&IsNotKnownUser, kAccountId2)).Run(); |
558 } | 432 } |
559 | 433 |
560 static bool IsSessionStarted() { | 434 static bool IsSessionStarted() { |
561 return chromeos::UserManager::Get()->IsSessionStarted(); | 435 return chromeos::UserManager::Get()->IsSessionStarted(); |
562 } | 436 } |
563 | 437 |
564 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, StartSession) { | 438 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, StartSession) { |
565 // This observes the display name becoming available as this indicates | 439 // This observes the display name becoming available as this indicates |
566 // device-local account policy is fully loaded, which is a prerequisite for | 440 // device-local account policy is fully loaded, which is a prerequisite for |
567 // successful login. | 441 // successful login. |
568 NotificationWatcher( | 442 content::NotificationWatcher( |
569 chrome::NOTIFICATION_USER_LIST_CHANGED, | 443 chrome::NOTIFICATION_USER_LIST_CHANGED, |
570 base::Bind(&DisplayNameMatches, kAccountId1, kDisplayName1)).Run(); | 444 base::Bind(&DisplayNameMatches, kAccountId1, kDisplayName1)).Run(); |
571 | 445 |
572 chromeos::ExistingUserController* controller = | 446 chromeos::ExistingUserController* controller = |
573 chromeos::ExistingUserController::current_controller(); | 447 chromeos::ExistingUserController::current_controller(); |
574 ASSERT_TRUE(controller); | 448 ASSERT_TRUE(controller); |
575 controller->LoginAsPublicAccount(kAccountId1); | 449 controller->LoginAsPublicAccount(kAccountId1); |
576 | 450 |
577 // Wait for the session to start. | 451 // Wait for the session to start. |
578 NotificationWatcher(chrome::NOTIFICATION_SESSION_STARTED, | 452 content::NotificationWatcher(chrome::NOTIFICATION_SESSION_STARTED, |
579 base::Bind(IsSessionStarted)).Run(); | 453 base::Bind(IsSessionStarted)).Run(); |
580 | 454 |
581 // Check that the startup pages specified in policy were opened. | 455 // Check that the startup pages specified in policy were opened. |
582 EXPECT_EQ(1U, chrome::GetTotalBrowserCount()); | 456 EXPECT_EQ(1U, chrome::GetTotalBrowserCount()); |
583 Browser* browser = | 457 Browser* browser = |
584 chrome::FindLastActiveWithHostDesktopType(chrome::HOST_DESKTOP_TYPE_ASH); | 458 chrome::FindLastActiveWithHostDesktopType(chrome::HOST_DESKTOP_TYPE_ASH); |
585 ASSERT_TRUE(browser); | 459 ASSERT_TRUE(browser); |
586 | 460 |
587 TabStripModel* tabs = browser->tab_strip_model(); | 461 TabStripModel* tabs = browser->tab_strip_model(); |
588 ASSERT_TRUE(tabs); | 462 ASSERT_TRUE(tabs); |
589 int expected_tab_count = static_cast<int>(arraysize(kStartupURLs)); | 463 int expected_tab_count = static_cast<int>(arraysize(kStartupURLs)); |
590 EXPECT_EQ(expected_tab_count, tabs->count()); | 464 EXPECT_EQ(expected_tab_count, tabs->count()); |
591 for (int i = 0; i < expected_tab_count && i < tabs->count(); ++i) | 465 for (int i = 0; i < expected_tab_count && i < tabs->count(); ++i) |
592 EXPECT_EQ(GURL(kStartupURLs[i]), tabs->GetWebContentsAt(i)->GetURL()); | 466 EXPECT_EQ(GURL(kStartupURLs[i]), tabs->GetWebContentsAt(i)->GetURL()); |
593 } | 467 } |
594 | 468 |
595 } // namespace policy | 469 } // namespace policy |
OLD | NEW |