Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(582)

Side by Side Diff: chrome/browser/policy/device_local_account_browsertest.cc

Issue 12218078: Implement a policy to autologin a public account. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more nits Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698