device_local_account_browsertest.cc revision 2385ea399aae016c0806a4f9ef3c9cfe3d2a39df
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 3// found in the LICENSE file. 4 5#include <map> 6#include <string> 7 8#include "base/basictypes.h" 9#include "base/bind.h" 10#include "base/command_line.h" 11#include "base/memory/scoped_ptr.h" 12#include "base/message_loop/message_loop.h" 13#include "base/run_loop.h" 14#include "base/strings/string_util.h" 15#include "base/strings/utf_string_conversions.h" 16#include "chrome/browser/browser_process.h" 17#include "chrome/browser/chrome_notification_types.h" 18#include "chrome/browser/chromeos/login/existing_user_controller.h" 19#include "chrome/browser/chromeos/login/login_display_host.h" 20#include "chrome/browser/chromeos/login/login_display_host_impl.h" 21#include "chrome/browser/chromeos/login/mock_login_status_consumer.h" 22#include "chrome/browser/chromeos/login/screens/wizard_screen.h" 23#include "chrome/browser/chromeos/login/user.h" 24#include "chrome/browser/chromeos/login/user_manager.h" 25#include "chrome/browser/chromeos/login/wizard_controller.h" 26#include "chrome/browser/chromeos/policy/device_local_account.h" 27#include "chrome/browser/chromeos/policy/device_policy_builder.h" 28#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" 29#include "chrome/browser/lifetime/application_lifetime.h" 30#include "chrome/browser/policy/cloud/cloud_policy_constants.h" 31#include "chrome/browser/policy/cloud/policy_builder.h" 32#include "chrome/browser/policy/policy_service.h" 33#include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h" 34#include "chrome/browser/policy/test/local_policy_test_server.h" 35#include "chrome/browser/prefs/session_startup_pref.h" 36#include "chrome/browser/ui/browser.h" 37#include "chrome/browser/ui/browser_finder.h" 38#include "chrome/browser/ui/browser_list.h" 39#include "chrome/browser/ui/host_desktop.h" 40#include "chrome/browser/ui/tabs/tab_strip_model.h" 41#include "chrome/common/chrome_switches.h" 42#include "chromeos/chromeos_switches.h" 43#include "chromeos/dbus/cryptohome_client.h" 44#include "chromeos/dbus/dbus_method_call_status.h" 45#include "chromeos/dbus/fake_cryptohome_client.h" 46#include "chromeos/dbus/fake_session_manager_client.h" 47#include "chromeos/dbus/session_manager_client.h" 48#include "content/public/browser/web_contents.h" 49#include "content/public/test/test_utils.h" 50#include "crypto/rsa_private_key.h" 51#include "testing/gmock/include/gmock/gmock.h" 52#include "third_party/cros_system_api/dbus/service_constants.h" 53 54namespace em = enterprise_management; 55 56using testing::InvokeWithoutArgs; 57using testing::Return; 58using testing::_; 59 60namespace policy { 61 62namespace { 63 64const char kAccountId1[] = "dla1@example.com"; 65const char kAccountId2[] = "dla2@example.com"; 66const char kDisplayName[] = "display name"; 67const char* kStartupURLs[] = { 68 "chrome://policy", 69 "chrome://about", 70}; 71 72} // namespace 73 74class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest { 75 protected: 76 DeviceLocalAccountTest() 77 : user_id_1_(GenerateDeviceLocalAccountUserId( 78 kAccountId1, DeviceLocalAccount::TYPE_PUBLIC_SESSION)), 79 user_id_2_(GenerateDeviceLocalAccountUserId( 80 kAccountId2, DeviceLocalAccount::TYPE_PUBLIC_SESSION)) {} 81 82 virtual ~DeviceLocalAccountTest() {} 83 84 virtual void SetUp() OVERRIDE { 85 // Configure and start the test server. 86 scoped_ptr<crypto::RSAPrivateKey> signing_key( 87 PolicyBuilder::CreateTestSigningKey()); 88 ASSERT_TRUE(test_server_.SetSigningKey(signing_key.get())); 89 signing_key.reset(); 90 test_server_.RegisterClient(PolicyBuilder::kFakeToken, 91 PolicyBuilder::kFakeDeviceId); 92 ASSERT_TRUE(test_server_.Start()); 93 94 DevicePolicyCrosBrowserTest::SetUp(); 95 } 96 97 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 98 command_line->AppendSwitch(chromeos::switches::kLoginManager); 99 command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); 100 command_line->AppendSwitchASCII( 101 switches::kDeviceManagementUrl, test_server_.GetServiceURL().spec()); 102 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user"); 103 } 104 105 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 106 DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture(); 107 108 // Clear command-line arguments (but keep command-line switches) so the 109 // startup pages policy takes effect. 110 CommandLine* command_line = CommandLine::ForCurrentProcess(); 111 CommandLine::StringVector argv(command_line->argv()); 112 argv.erase(argv.begin() + argv.size() - command_line->GetArgs().size(), 113 argv.end()); 114 command_line->InitFromArgv(argv); 115 116 InstallOwnerKey(); 117 MarkAsEnterpriseOwned(); 118 119 InitializePolicy(); 120 } 121 122 virtual void CleanUpOnMainThread() OVERRIDE { 123 // This shuts down the login UI. 124 base::MessageLoop::current()->PostTask(FROM_HERE, 125 base::Bind(&chrome::AttemptExit)); 126 base::RunLoop().RunUntilIdle(); 127 } 128 129 void InitializePolicy() { 130 device_policy()->policy_data().set_public_key_version(1); 131 em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); 132 proto.mutable_show_user_names()->set_show_user_names(true); 133 134 device_local_account_policy_.policy_data().set_policy_type( 135 dm_protocol::kChromePublicAccountPolicyType); 136 device_local_account_policy_.policy_data().set_username(kAccountId1); 137 device_local_account_policy_.policy_data().set_settings_entity_id( 138 kAccountId1); 139 device_local_account_policy_.policy_data().set_public_key_version(1); 140 device_local_account_policy_.payload().mutable_userdisplayname()->set_value( 141 kDisplayName); 142 } 143 144 void BuildDeviceLocalAccountPolicy() { 145 device_local_account_policy_.SetDefaultSigningKey(); 146 device_local_account_policy_.Build(); 147 } 148 149 void InstallDeviceLocalAccountPolicy() { 150 BuildDeviceLocalAccountPolicy(); 151 session_manager_client()->set_device_local_account_policy( 152 kAccountId1, device_local_account_policy_.GetBlob()); 153 } 154 155 void UploadDeviceLocalAccountPolicy() { 156 BuildDeviceLocalAccountPolicy(); 157 ASSERT_TRUE(session_manager_client()->device_local_account_policy( 158 kAccountId1).empty()); 159 test_server_.UpdatePolicy( 160 dm_protocol::kChromePublicAccountPolicyType, kAccountId1, 161 device_local_account_policy_.payload().SerializeAsString()); 162 } 163 164 void AddPublicSessionToDevicePolicy(const std::string& username) { 165 em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); 166 em::DeviceLocalAccountInfoProto* account = 167 proto.mutable_device_local_accounts()->add_account(); 168 account->set_account_id(username); 169 account->set_type( 170 em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION); 171 RefreshDevicePolicy(); 172 test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, 173 std::string(), proto.SerializeAsString()); 174 } 175 176 void CheckPublicSessionPresent(const std::string& id) { 177 const chromeos::User* user = chromeos::UserManager::Get()->FindUser(id); 178 ASSERT_TRUE(user); 179 EXPECT_EQ(id, user->email()); 180 EXPECT_EQ(chromeos::User::USER_TYPE_PUBLIC_ACCOUNT, user->GetType()); 181 } 182 183 const std::string user_id_1_; 184 const std::string user_id_2_; 185 186 UserPolicyBuilder device_local_account_policy_; 187 LocalPolicyTestServer test_server_; 188}; 189 190static bool IsKnownUser(const std::string& account_id) { 191 return chromeos::UserManager::Get()->IsKnownUser(account_id); 192} 193 194IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, LoginScreen) { 195 AddPublicSessionToDevicePolicy(kAccountId1); 196 AddPublicSessionToDevicePolicy(kAccountId2); 197 198 content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED, 199 base::Bind(&IsKnownUser, user_id_1_)) 200 .Wait(); 201 content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED, 202 base::Bind(&IsKnownUser, user_id_2_)) 203 .Wait(); 204 205 CheckPublicSessionPresent(user_id_1_); 206 CheckPublicSessionPresent(user_id_2_); 207} 208 209static bool DisplayNameMatches(const std::string& account_id, 210 const std::string& display_name) { 211 const chromeos::User* user = 212 chromeos::UserManager::Get()->FindUser(account_id); 213 if (!user || user->display_name().empty()) 214 return false; 215 EXPECT_EQ(UTF8ToUTF16(display_name), user->display_name()); 216 return true; 217} 218 219IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DisplayName) { 220 InstallDeviceLocalAccountPolicy(); 221 AddPublicSessionToDevicePolicy(kAccountId1); 222 223 content::WindowedNotificationObserver( 224 chrome::NOTIFICATION_USER_LIST_CHANGED, 225 base::Bind(&DisplayNameMatches, user_id_1_, kDisplayName)).Wait(); 226} 227 228IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, PolicyDownload) { 229 UploadDeviceLocalAccountPolicy(); 230 AddPublicSessionToDevicePolicy(kAccountId1); 231 232 // Policy for the account is not installed in session_manager_client. Because 233 // of this, the presence of the display name (which comes from policy) can be 234 // used as a signal that indicates successful policy download. 235 content::WindowedNotificationObserver( 236 chrome::NOTIFICATION_USER_LIST_CHANGED, 237 base::Bind(&DisplayNameMatches, user_id_1_, kDisplayName)).Wait(); 238 239 // Sanity check: The policy should be present now. 240 ASSERT_FALSE(session_manager_client()->device_local_account_policy( 241 kAccountId1).empty()); 242} 243 244static bool IsNotKnownUser(const std::string& account_id) { 245 return !IsKnownUser(account_id); 246} 247 248IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DevicePolicyChange) { 249 AddPublicSessionToDevicePolicy(kAccountId1); 250 AddPublicSessionToDevicePolicy(kAccountId2); 251 252 // Wait until the login screen is up. 253 content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED, 254 base::Bind(&IsKnownUser, user_id_1_)) 255 .Wait(); 256 content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED, 257 base::Bind(&IsKnownUser, user_id_2_)) 258 .Wait(); 259 260 // Update policy to remove kAccountId2. 261 em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); 262 proto.mutable_device_local_accounts()->clear_account(); 263 AddPublicSessionToDevicePolicy(kAccountId1); 264 265 em::ChromeDeviceSettingsProto policy; 266 policy.mutable_show_user_names()->set_show_user_names(true); 267 em::DeviceLocalAccountInfoProto* account1 = 268 policy.mutable_device_local_accounts()->add_account(); 269 account1->set_account_id(kAccountId1); 270 account1->set_type( 271 em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION); 272 273 test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, std::string(), 274 policy.SerializeAsString()); 275 g_browser_process->policy_service()->RefreshPolicies(base::Closure()); 276 277 // Make sure the second device-local account disappears. 278 content::WindowedNotificationObserver( 279 chrome::NOTIFICATION_USER_LIST_CHANGED, 280 base::Bind(&IsNotKnownUser, user_id_2_)).Wait(); 281} 282 283static bool IsSessionStarted() { 284 return chromeos::UserManager::Get()->IsSessionStarted(); 285} 286 287IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, StartSession) { 288 // Specify startup pages. 289 device_local_account_policy_.payload().mutable_restoreonstartup()->set_value( 290 SessionStartupPref::kPrefValueURLs); 291 em::StringListPolicyProto* startup_urls_proto = 292 device_local_account_policy_.payload().mutable_restoreonstartupurls(); 293 for (size_t i = 0; i < arraysize(kStartupURLs); ++i) 294 startup_urls_proto->mutable_value()->add_entries(kStartupURLs[i]); 295 InstallDeviceLocalAccountPolicy(); 296 AddPublicSessionToDevicePolicy(kAccountId1); 297 298 // This observes the display name becoming available as this indicates 299 // device-local account policy is fully loaded, which is a prerequisite for 300 // successful login. 301 content::WindowedNotificationObserver( 302 chrome::NOTIFICATION_USER_LIST_CHANGED, 303 base::Bind(&DisplayNameMatches, user_id_1_, kDisplayName)).Wait(); 304 305 chromeos::LoginDisplayHost* host = 306 chromeos::LoginDisplayHostImpl::default_host(); 307 ASSERT_TRUE(host); 308 host->StartSignInScreen(); 309 chromeos::ExistingUserController* controller = 310 chromeos::ExistingUserController::current_controller(); 311 ASSERT_TRUE(controller); 312 controller->LoginAsPublicAccount(user_id_1_); 313 314 // Wait for the session to start. 315 content::WindowedNotificationObserver(chrome::NOTIFICATION_SESSION_STARTED, 316 base::Bind(IsSessionStarted)).Wait(); 317 318 // Check that the startup pages specified in policy were opened. 319 BrowserList* browser_list = 320 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); 321 EXPECT_EQ(1U, browser_list->size()); 322 Browser* browser = browser_list->get(0); 323 ASSERT_TRUE(browser); 324 325 TabStripModel* tabs = browser->tab_strip_model(); 326 ASSERT_TRUE(tabs); 327 int expected_tab_count = static_cast<int>(arraysize(kStartupURLs)); 328 EXPECT_EQ(expected_tab_count, tabs->count()); 329 for (int i = 0; i < expected_tab_count && i < tabs->count(); ++i) { 330 EXPECT_EQ(GURL(kStartupURLs[i]), 331 tabs->GetWebContentsAt(i)->GetVisibleURL()); 332 } 333} 334 335IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, TermsOfService) { 336 // Specify Terms of Service. The URL does not really matter as the test does 337 // not wait for the terms to load. 338 device_local_account_policy_.payload().mutable_termsofserviceurl()->set_value( 339 "http://localhost/tos"); 340 InstallDeviceLocalAccountPolicy(); 341 AddPublicSessionToDevicePolicy(kAccountId1); 342 343 // Wait for the device-local account policy to be fully loaded. 344 content::WindowedNotificationObserver( 345 chrome::NOTIFICATION_USER_LIST_CHANGED, 346 base::Bind(&DisplayNameMatches, user_id_1_, kDisplayName)).Wait(); 347 348 // Start login into the device-local account. 349 chromeos::LoginDisplayHost* host = 350 chromeos::LoginDisplayHostImpl::default_host(); 351 ASSERT_TRUE(host); 352 host->StartSignInScreen(); 353 chromeos::ExistingUserController* controller = 354 chromeos::ExistingUserController::current_controller(); 355 ASSERT_TRUE(controller); 356 controller->LoginAsPublicAccount(user_id_1_); 357 358 // Set up an observer that will quit the message loop when login has succeeded 359 // and the first wizard screen, if any, is being shown. 360 base::RunLoop run_loop; 361 chromeos::MockConsumer login_status_consumer; 362 EXPECT_CALL(login_status_consumer, OnLoginSuccess(_, false, false)) 363 .Times(1) 364 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); 365 366 // Spin the loop until the observer fires. Then, unregister the observer. 367 controller->set_login_status_consumer(&login_status_consumer); 368 run_loop.Run(); 369 controller->set_login_status_consumer(NULL); 370 371 // Verify that the Terms of Service screen is being shown. 372 chromeos::WizardController* wizard_controller = 373 chromeos::WizardController::default_controller(); 374 ASSERT_TRUE(wizard_controller); 375 ASSERT_TRUE(wizard_controller->current_screen()); 376 EXPECT_EQ(chromeos::WizardController::kTermsOfServiceScreenName, 377 wizard_controller->current_screen()->GetName()); 378} 379 380} // namespace policy 381