device_local_account_browsertest.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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/bind_helpers.h" 11#include "base/callback.h" 12#include "base/command_line.h" 13#include "base/file_util.h" 14#include "base/files/file_path.h" 15#include "base/files/scoped_temp_dir.h" 16#include "base/json/json_reader.h" 17#include "base/json/json_writer.h" 18#include "base/location.h" 19#include "base/memory/ref_counted.h" 20#include "base/memory/scoped_ptr.h" 21#include "base/message_loop/message_loop.h" 22#include "base/message_loop/message_loop_proxy.h" 23#include "base/path_service.h" 24#include "base/prefs/pref_service.h" 25#include "base/run_loop.h" 26#include "base/sequenced_task_runner.h" 27#include "base/strings/string_number_conversions.h" 28#include "base/strings/string_util.h" 29#include "base/strings/stringprintf.h" 30#include "base/strings/utf_string_conversions.h" 31#include "base/test/scoped_path_override.h" 32#include "base/values.h" 33#include "chrome/browser/browser_process.h" 34#include "chrome/browser/chrome_notification_types.h" 35#include "chrome/browser/chromeos/login/existing_user_controller.h" 36#include "chrome/browser/chromeos/login/login_display_host.h" 37#include "chrome/browser/chromeos/login/login_display_host_impl.h" 38#include "chrome/browser/chromeos/login/mock_login_status_consumer.h" 39#include "chrome/browser/chromeos/login/screens/wizard_screen.h" 40#include "chrome/browser/chromeos/login/user.h" 41#include "chrome/browser/chromeos/login/user_image_manager.h" 42#include "chrome/browser/chromeos/login/user_image_manager_impl.h" 43#include "chrome/browser/chromeos/login/user_image_manager_test_util.h" 44#include "chrome/browser/chromeos/login/user_manager.h" 45#include "chrome/browser/chromeos/login/user_manager_impl.h" 46#include "chrome/browser/chromeos/login/webui_login_view.h" 47#include "chrome/browser/chromeos/login/wizard_controller.h" 48#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" 49#include "chrome/browser/chromeos/policy/cloud_external_data_manager_base_test_util.h" 50#include "chrome/browser/chromeos/policy/device_local_account.h" 51#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h" 52#include "chrome/browser/chromeos/policy/device_policy_builder.h" 53#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" 54#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" 55#include "chrome/browser/extensions/extension_service.h" 56#include "chrome/browser/lifetime/application_lifetime.h" 57#include "chrome/browser/policy/profile_policy_connector.h" 58#include "chrome/browser/policy/profile_policy_connector_factory.h" 59#include "chrome/browser/policy/test/local_policy_test_server.h" 60#include "chrome/browser/prefs/session_startup_pref.h" 61#include "chrome/browser/profiles/profile.h" 62#include "chrome/browser/profiles/profile_manager.h" 63#include "chrome/browser/ui/browser.h" 64#include "chrome/browser/ui/browser_commands.h" 65#include "chrome/browser/ui/browser_finder.h" 66#include "chrome/browser/ui/browser_list.h" 67#include "chrome/browser/ui/browser_window.h" 68#include "chrome/browser/ui/host_desktop.h" 69#include "chrome/browser/ui/tabs/tab_strip_model.h" 70#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" 71#include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" 72#include "chrome/common/chrome_paths.h" 73#include "chromeos/chromeos_paths.h" 74#include "chromeos/chromeos_switches.h" 75#include "chromeos/dbus/fake_session_manager_client.h" 76#include "components/policy/core/common/cloud/cloud_policy_constants.h" 77#include "components/policy/core/common/cloud/cloud_policy_core.h" 78#include "components/policy/core/common/cloud/cloud_policy_store.h" 79#include "components/policy/core/common/cloud/policy_builder.h" 80#include "components/policy/core/common/external_data_fetcher.h" 81#include "components/policy/core/common/policy_map.h" 82#include "components/policy/core/common/policy_namespace.h" 83#include "components/policy/core/common/policy_service.h" 84#include "components/policy/core/common/policy_switches.h" 85#include "content/public/browser/notification_details.h" 86#include "content/public/browser/notification_source.h" 87#include "content/public/browser/web_contents.h" 88#include "content/public/browser/web_ui.h" 89#include "content/public/test/browser_test_utils.h" 90#include "content/public/test/test_utils.h" 91#include "crypto/rsa_private_key.h" 92#include "extensions/browser/extension_system.h" 93#include "extensions/common/extension.h" 94#include "grit/chromium_strings.h" 95#include "grit/generated_resources.h" 96#include "net/base/url_util.h" 97#include "net/http/http_status_code.h" 98#include "net/test/embedded_test_server/embedded_test_server.h" 99#include "net/test/embedded_test_server/http_request.h" 100#include "net/test/embedded_test_server/http_response.h" 101#include "net/url_request/test_url_fetcher_factory.h" 102#include "net/url_request/url_fetcher_delegate.h" 103#include "net/url_request/url_request_status.h" 104#include "policy/policy_constants.h" 105#include "testing/gmock/include/gmock/gmock.h" 106#include "ui/base/l10n/l10n_util.h" 107#include "ui/gfx/image/image_skia.h" 108#include "url/gurl.h" 109//#include "third_party/cros_system_api/dbus/service_constants.h" 110 111namespace em = enterprise_management; 112 113using chromeos::LoginScreenContext; 114using testing::InvokeWithoutArgs; 115using testing::Return; 116using testing::_; 117 118namespace policy { 119 120namespace { 121 122const char kDomain[] = "example.com"; 123const char kAccountId1[] = "dla1@example.com"; 124const char kAccountId2[] = "dla2@example.com"; 125const char kDisplayName[] = "display name"; 126const char* kStartupURLs[] = { 127 "chrome://policy", 128 "chrome://about", 129}; 130const char kExistentTermsOfServicePath[] = "chromeos/enterprise/tos.txt"; 131const char kNonexistentTermsOfServicePath[] = "chromeos/enterprise/tos404.txt"; 132const char kRelativeUpdateURL[] = "/service/update2/crx"; 133const char kUpdateManifestHeader[] = 134 "<?xml version='1.0' encoding='UTF-8'?>\n" 135 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>\n"; 136const char kUpdateManifestTemplate[] = 137 " <app appid='%s'>\n" 138 " <updatecheck codebase='%s' version='%s' />\n" 139 " </app>\n"; 140const char kUpdateManifestFooter[] = 141 "</gupdate>\n"; 142const char kHostedAppID[] = "kbmnembihfiondgfjekmnmcbddelicoi"; 143const char kHostedAppCRXPath[] = "extensions/hosted_app.crx"; 144const char kHostedAppVersion[] = "1.0.0.0"; 145const char kGoodExtensionID[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; 146const char kGoodExtensionCRXPath[] = "extensions/good.crx"; 147const char kGoodExtensionVersion[] = "1.0"; 148 149const char kExternalData[] = "External data"; 150const char kExternalDataURL[] = "http://localhost/external_data"; 151 152// Helper that serves extension update manifests to Chrome. 153class TestingUpdateManifestProvider { 154 public: 155 156 // Update manifests will be served at |relative_update_url|. 157 explicit TestingUpdateManifestProvider( 158 const std::string& relative_update_url); 159 ~TestingUpdateManifestProvider(); 160 161 // When an update manifest is requested for the given extension |id|, indicate 162 // that |version| of the extension can be downloaded at |crx_url|. 163 void AddUpdate(const std::string& id, 164 const std::string& version, 165 const GURL& crx_url); 166 167 // This method must be registered with the test's EmbeddedTestServer to start 168 // serving update manifests. 169 scoped_ptr<net::test_server::HttpResponse> HandleRequest( 170 const net::test_server::HttpRequest& request); 171 172 private: 173 struct Update { 174 public: 175 Update(const std::string& version, const GURL& crx_url); 176 Update(); 177 178 std::string version; 179 GURL crx_url; 180 }; 181 typedef std::map<std::string, Update> UpdateMap; 182 UpdateMap updates_; 183 184 const std::string relative_update_url_; 185 186 DISALLOW_COPY_AND_ASSIGN(TestingUpdateManifestProvider); 187}; 188 189TestingUpdateManifestProvider::Update::Update(const std::string& version, 190 const GURL& crx_url) 191 : version(version), 192 crx_url(crx_url) { 193} 194 195TestingUpdateManifestProvider::Update::Update() { 196} 197 198TestingUpdateManifestProvider::TestingUpdateManifestProvider( 199 const std::string& relative_update_url) 200 : relative_update_url_(relative_update_url) { 201} 202 203TestingUpdateManifestProvider::~TestingUpdateManifestProvider() { 204} 205 206void TestingUpdateManifestProvider::AddUpdate(const std::string& id, 207 const std::string& version, 208 const GURL& crx_url) { 209 updates_[id] = Update(version, crx_url); 210} 211 212scoped_ptr<net::test_server::HttpResponse> 213 TestingUpdateManifestProvider::HandleRequest( 214 const net::test_server::HttpRequest& request) { 215 const GURL url("http://localhost" + request.relative_url); 216 if (url.path() != relative_update_url_) 217 return scoped_ptr<net::test_server::HttpResponse>(); 218 219 std::string content = kUpdateManifestHeader; 220 for (net::QueryIterator it(url); !it.IsAtEnd(); it.Advance()) { 221 if (it.GetKey() != "x") 222 continue; 223 // Extract the extension id from the subquery. Since GetValueForKeyInQuery() 224 // expects a complete URL, dummy scheme and host must be prepended. 225 std::string id; 226 net::GetValueForKeyInQuery(GURL("http://dummy?" + it.GetUnescapedValue()), 227 "id", &id); 228 UpdateMap::const_iterator entry = updates_.find(id); 229 if (entry != updates_.end()) { 230 content += base::StringPrintf(kUpdateManifestTemplate, 231 id.c_str(), 232 entry->second.crx_url.spec().c_str(), 233 entry->second.version.c_str()); 234 } 235 } 236 content += kUpdateManifestFooter; 237 scoped_ptr<net::test_server::BasicHttpResponse> 238 http_response(new net::test_server::BasicHttpResponse); 239 http_response->set_code(net::HTTP_OK); 240 http_response->set_content(content); 241 http_response->set_content_type("text/xml"); 242 return http_response.PassAs<net::test_server::HttpResponse>(); 243} 244 245bool DoesInstallSuccessReferToId(const std::string& id, 246 const content::NotificationSource& source, 247 const content::NotificationDetails& details) { 248 return content::Details<const extensions::InstalledExtensionInfo>(details)-> 249 extension->id() == id; 250} 251 252bool DoesInstallFailureReferToId(const std::string& id, 253 const content::NotificationSource& source, 254 const content::NotificationDetails& details) { 255 return content::Details<const base::string16>(details)-> 256 find(base::UTF8ToUTF16(id)) != base::string16::npos; 257} 258 259scoped_ptr<net::FakeURLFetcher> RunCallbackAndReturnFakeURLFetcher( 260 scoped_refptr<base::SequencedTaskRunner> task_runner, 261 const base::Closure& callback, 262 const GURL& url, 263 net::URLFetcherDelegate* delegate, 264 const std::string& response_data, 265 net::HttpStatusCode response_code, 266 net::URLRequestStatus::Status status) { 267 task_runner->PostTask(FROM_HERE, callback); 268 return make_scoped_ptr(new net::FakeURLFetcher( 269 url, delegate, response_data, response_code, status)); 270} 271 272} // namespace 273 274class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest, 275 public chromeos::UserManager::Observer { 276 protected: 277 DeviceLocalAccountTest() 278 : user_id_1_(GenerateDeviceLocalAccountUserId( 279 kAccountId1, DeviceLocalAccount::TYPE_PUBLIC_SESSION)), 280 user_id_2_(GenerateDeviceLocalAccountUserId( 281 kAccountId2, DeviceLocalAccount::TYPE_PUBLIC_SESSION)) {} 282 283 virtual ~DeviceLocalAccountTest() {} 284 285 virtual void SetUp() OVERRIDE { 286 // Configure and start the test server. 287 scoped_ptr<crypto::RSAPrivateKey> signing_key( 288 PolicyBuilder::CreateTestSigningKey()); 289 ASSERT_TRUE(test_server_.SetSigningKey(signing_key.get())); 290 signing_key.reset(); 291 test_server_.RegisterClient(PolicyBuilder::kFakeToken, 292 PolicyBuilder::kFakeDeviceId); 293 ASSERT_TRUE(test_server_.Start()); 294 295 ASSERT_TRUE(extension_cache_root_dir_.CreateUniqueTempDir()); 296 extension_cache_root_dir_override_.reset(new base::ScopedPathOverride( 297 chromeos::DIR_DEVICE_LOCAL_ACCOUNT_EXTENSIONS, 298 extension_cache_root_dir_.path())); 299 ASSERT_TRUE(external_data_cache_dir_.CreateUniqueTempDir()); 300 external_data_cache_dir_override_.reset(new base::ScopedPathOverride( 301 chromeos::DIR_DEVICE_LOCAL_ACCOUNT_EXTERNAL_DATA, 302 external_data_cache_dir_.path())); 303 DevicePolicyCrosBrowserTest::SetUp(); 304 } 305 306 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 307 DevicePolicyCrosBrowserTest::SetUpCommandLine(command_line); 308 command_line->AppendSwitch(chromeos::switches::kLoginManager); 309 command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); 310 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user"); 311 command_line->AppendSwitchASCII(policy::switches::kDeviceManagementUrl, 312 test_server_.GetServiceURL().spec()); 313 } 314 315 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 316 DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture(); 317 318 // Clear command-line arguments (but keep command-line switches) so the 319 // startup pages policy takes effect. 320 CommandLine* command_line = CommandLine::ForCurrentProcess(); 321 CommandLine::StringVector argv(command_line->argv()); 322 argv.erase(argv.begin() + argv.size() - command_line->GetArgs().size(), 323 argv.end()); 324 command_line->InitFromArgv(argv); 325 326 InstallOwnerKey(); 327 MarkAsEnterpriseOwned(); 328 329 InitializePolicy(); 330 } 331 332 virtual void CleanUpOnMainThread() OVERRIDE { 333 // This shuts down the login UI. 334 base::MessageLoop::current()->PostTask(FROM_HERE, 335 base::Bind(&chrome::AttemptExit)); 336 base::RunLoop().RunUntilIdle(); 337 } 338 339 virtual void LocalStateChanged(chromeos::UserManager* user_manager) OVERRIDE { 340 run_loop_->Quit(); 341 } 342 343 void InitializePolicy() { 344 device_policy()->policy_data().set_public_key_version(1); 345 em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); 346 proto.mutable_show_user_names()->set_show_user_names(true); 347 348 device_local_account_policy_.policy_data().set_policy_type( 349 dm_protocol::kChromePublicAccountPolicyType); 350 device_local_account_policy_.policy_data().set_username(kAccountId1); 351 device_local_account_policy_.policy_data().set_settings_entity_id( 352 kAccountId1); 353 device_local_account_policy_.policy_data().set_public_key_version(1); 354 device_local_account_policy_.payload().mutable_userdisplayname()->set_value( 355 kDisplayName); 356 } 357 358 void BuildDeviceLocalAccountPolicy() { 359 device_local_account_policy_.SetDefaultSigningKey(); 360 device_local_account_policy_.Build(); 361 } 362 363 void UploadDeviceLocalAccountPolicy() { 364 BuildDeviceLocalAccountPolicy(); 365 test_server_.UpdatePolicy( 366 dm_protocol::kChromePublicAccountPolicyType, kAccountId1, 367 device_local_account_policy_.payload().SerializeAsString()); 368 } 369 370 void UploadAndInstallDeviceLocalAccountPolicy() { 371 UploadDeviceLocalAccountPolicy(); 372 session_manager_client()->set_device_local_account_policy( 373 kAccountId1, device_local_account_policy_.GetBlob()); 374 } 375 376 void AddPublicSessionToDevicePolicy(const std::string& username) { 377 em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); 378 em::DeviceLocalAccountInfoProto* account = 379 proto.mutable_device_local_accounts()->add_account(); 380 account->set_account_id(username); 381 account->set_type( 382 em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION); 383 RefreshDevicePolicy(); 384 test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, 385 std::string(), proto.SerializeAsString()); 386 } 387 388 void CheckPublicSessionPresent(const std::string& id) { 389 const chromeos::User* user = chromeos::UserManager::Get()->FindUser(id); 390 ASSERT_TRUE(user); 391 EXPECT_EQ(id, user->email()); 392 EXPECT_EQ(chromeos::User::USER_TYPE_PUBLIC_ACCOUNT, user->GetType()); 393 } 394 395 base::FilePath GetCacheDirectoryForAccountID(const std::string& account_id) { 396 return extension_cache_root_dir_.path() 397 .Append(base::HexEncode(account_id.c_str(), account_id.size())); 398 } 399 400 base::FilePath GetCacheCRXFile(const std::string& account_id, 401 const std::string& id, 402 const std::string& version) { 403 return GetCacheDirectoryForAccountID(account_id) 404 .Append(base::StringPrintf("%s-%s.crx", id.c_str(), version.c_str())); 405 } 406 407 // Returns a profile which can be used for testing. 408 Profile* GetProfileForTest() { 409 // Any profile can be used here since this test does not test multi profile. 410 return ProfileManager::GetActiveUserProfile(); 411 } 412 413 const std::string user_id_1_; 414 const std::string user_id_2_; 415 416 scoped_ptr<base::RunLoop> run_loop_; 417 418 UserPolicyBuilder device_local_account_policy_; 419 LocalPolicyTestServer test_server_; 420 421 private: 422 base::ScopedTempDir extension_cache_root_dir_; 423 base::ScopedTempDir external_data_cache_dir_; 424 scoped_ptr<base::ScopedPathOverride> extension_cache_root_dir_override_; 425 scoped_ptr<base::ScopedPathOverride> external_data_cache_dir_override_; 426 427 DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountTest); 428}; 429 430static bool IsKnownUser(const std::string& account_id) { 431 return chromeos::UserManager::Get()->IsKnownUser(account_id); 432} 433 434IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, LoginScreen) { 435 AddPublicSessionToDevicePolicy(kAccountId1); 436 AddPublicSessionToDevicePolicy(kAccountId2); 437 438 content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED, 439 base::Bind(&IsKnownUser, user_id_1_)) 440 .Wait(); 441 content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED, 442 base::Bind(&IsKnownUser, user_id_2_)) 443 .Wait(); 444 445 CheckPublicSessionPresent(user_id_1_); 446 CheckPublicSessionPresent(user_id_2_); 447} 448 449static bool DisplayNameMatches(const std::string& account_id, 450 const std::string& display_name) { 451 const chromeos::User* user = 452 chromeos::UserManager::Get()->FindUser(account_id); 453 if (!user || user->display_name().empty()) 454 return false; 455 EXPECT_EQ(base::UTF8ToUTF16(display_name), user->display_name()); 456 return true; 457} 458 459IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DisplayName) { 460 UploadAndInstallDeviceLocalAccountPolicy(); 461 AddPublicSessionToDevicePolicy(kAccountId1); 462 463 content::WindowedNotificationObserver( 464 chrome::NOTIFICATION_USER_LIST_CHANGED, 465 base::Bind(&DisplayNameMatches, user_id_1_, kDisplayName)).Wait(); 466} 467 468IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, PolicyDownload) { 469 UploadDeviceLocalAccountPolicy(); 470 AddPublicSessionToDevicePolicy(kAccountId1); 471 472 // Policy for the account is not installed in session_manager_client. Because 473 // of this, the presence of the display name (which comes from policy) can be 474 // used as a signal that indicates successful policy download. 475 content::WindowedNotificationObserver( 476 chrome::NOTIFICATION_USER_LIST_CHANGED, 477 base::Bind(&DisplayNameMatches, user_id_1_, kDisplayName)).Wait(); 478 479 // Sanity check: The policy should be present now. 480 ASSERT_FALSE(session_manager_client()->device_local_account_policy( 481 kAccountId1).empty()); 482} 483 484static bool IsNotKnownUser(const std::string& account_id) { 485 return !IsKnownUser(account_id); 486} 487 488IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DevicePolicyChange) { 489 AddPublicSessionToDevicePolicy(kAccountId1); 490 AddPublicSessionToDevicePolicy(kAccountId2); 491 492 // Wait until the login screen is up. 493 content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED, 494 base::Bind(&IsKnownUser, user_id_1_)) 495 .Wait(); 496 content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED, 497 base::Bind(&IsKnownUser, user_id_2_)) 498 .Wait(); 499 500 // Update policy to remove kAccountId2. 501 em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); 502 proto.mutable_device_local_accounts()->clear_account(); 503 AddPublicSessionToDevicePolicy(kAccountId1); 504 505 em::ChromeDeviceSettingsProto policy; 506 policy.mutable_show_user_names()->set_show_user_names(true); 507 em::DeviceLocalAccountInfoProto* account1 = 508 policy.mutable_device_local_accounts()->add_account(); 509 account1->set_account_id(kAccountId1); 510 account1->set_type( 511 em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION); 512 513 test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, std::string(), 514 policy.SerializeAsString()); 515 g_browser_process->policy_service()->RefreshPolicies(base::Closure()); 516 517 // Make sure the second device-local account disappears. 518 content::WindowedNotificationObserver( 519 chrome::NOTIFICATION_USER_LIST_CHANGED, 520 base::Bind(&IsNotKnownUser, user_id_2_)).Wait(); 521} 522 523static bool IsSessionStarted() { 524 return chromeos::UserManager::Get()->IsSessionStarted(); 525} 526 527IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, StartSession) { 528 // Specify startup pages. 529 device_local_account_policy_.payload().mutable_restoreonstartup()->set_value( 530 SessionStartupPref::kPrefValueURLs); 531 em::StringListPolicyProto* startup_urls_proto = 532 device_local_account_policy_.payload().mutable_restoreonstartupurls(); 533 for (size_t i = 0; i < arraysize(kStartupURLs); ++i) 534 startup_urls_proto->mutable_value()->add_entries(kStartupURLs[i]); 535 UploadAndInstallDeviceLocalAccountPolicy(); 536 AddPublicSessionToDevicePolicy(kAccountId1); 537 538 // This observes the display name becoming available as this indicates 539 // device-local account policy is fully loaded, which is a prerequisite for 540 // successful login. 541 content::WindowedNotificationObserver( 542 chrome::NOTIFICATION_USER_LIST_CHANGED, 543 base::Bind(&DisplayNameMatches, user_id_1_, kDisplayName)).Wait(); 544 545 // Wait for the login UI to be ready. 546 chromeos::LoginDisplayHostImpl* host = 547 reinterpret_cast<chromeos::LoginDisplayHostImpl*>( 548 chromeos::LoginDisplayHostImpl::default_host()); 549 ASSERT_TRUE(host); 550 chromeos::OobeUI* oobe_ui = host->GetOobeUI(); 551 ASSERT_TRUE(oobe_ui); 552 base::RunLoop run_loop; 553 const bool oobe_ui_ready = oobe_ui->IsJSReady(run_loop.QuitClosure()); 554 if (!oobe_ui_ready) 555 run_loop.Run(); 556 557 // Start login into the device-local account. 558 host->StartSignInScreen(LoginScreenContext()); 559 chromeos::ExistingUserController* controller = 560 chromeos::ExistingUserController::current_controller(); 561 ASSERT_TRUE(controller); 562 controller->LoginAsPublicAccount(user_id_1_); 563 564 // Wait for the session to start. 565 content::WindowedNotificationObserver(chrome::NOTIFICATION_SESSION_STARTED, 566 base::Bind(IsSessionStarted)).Wait(); 567 568 // Check that the startup pages specified in policy were opened. 569 BrowserList* browser_list = 570 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); 571 EXPECT_EQ(1U, browser_list->size()); 572 Browser* browser = browser_list->get(0); 573 ASSERT_TRUE(browser); 574 575 TabStripModel* tabs = browser->tab_strip_model(); 576 ASSERT_TRUE(tabs); 577 int expected_tab_count = static_cast<int>(arraysize(kStartupURLs)); 578 EXPECT_EQ(expected_tab_count, tabs->count()); 579 for (int i = 0; i < expected_tab_count && i < tabs->count(); ++i) { 580 EXPECT_EQ(GURL(kStartupURLs[i]), 581 tabs->GetWebContentsAt(i)->GetVisibleURL()); 582 } 583} 584 585IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, FullscreenDisallowed) { 586 UploadAndInstallDeviceLocalAccountPolicy(); 587 AddPublicSessionToDevicePolicy(kAccountId1); 588 589 // This observes the display name becoming available as this indicates 590 // device-local account policy is fully loaded, which is a prerequisite for 591 // successful login. 592 content::WindowedNotificationObserver( 593 chrome::NOTIFICATION_USER_LIST_CHANGED, 594 base::Bind(&DisplayNameMatches, user_id_1_, kDisplayName)).Wait(); 595 596 // Wait for the login UI to be ready. 597 chromeos::LoginDisplayHostImpl* host = 598 reinterpret_cast<chromeos::LoginDisplayHostImpl*>( 599 chromeos::LoginDisplayHostImpl::default_host()); 600 ASSERT_TRUE(host); 601 chromeos::OobeUI* oobe_ui = host->GetOobeUI(); 602 ASSERT_TRUE(oobe_ui); 603 base::RunLoop run_loop; 604 const bool oobe_ui_ready = oobe_ui->IsJSReady(run_loop.QuitClosure()); 605 if (!oobe_ui_ready) 606 run_loop.Run(); 607 608 // Ensure that the browser stays alive, even though no windows are opened 609 // during session start. 610 chrome::StartKeepAlive(); 611 612 // Start login into the device-local account. 613 host->StartSignInScreen(LoginScreenContext()); 614 chromeos::ExistingUserController* controller = 615 chromeos::ExistingUserController::current_controller(); 616 ASSERT_TRUE(controller); 617 controller->LoginAsPublicAccount(user_id_1_); 618 619 // Wait for the session to start. 620 content::WindowedNotificationObserver(chrome::NOTIFICATION_SESSION_STARTED, 621 base::Bind(IsSessionStarted)).Wait(); 622 623 // Open a browser window. 624 chrome::NewEmptyWindow(GetProfileForTest(), chrome::HOST_DESKTOP_TYPE_ASH); 625 BrowserList* browser_list = 626 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); 627 EXPECT_EQ(1U, browser_list->size()); 628 Browser* browser = browser_list->get(0); 629 ASSERT_TRUE(browser); 630 BrowserWindow* browser_window = browser->window(); 631 ASSERT_TRUE(browser_window); 632 chrome::EndKeepAlive(); 633 634 // Verify that an attempt to enter fullscreen mode is denied. 635 EXPECT_FALSE(browser_window->IsFullscreen()); 636 chrome::ToggleFullscreenMode(browser); 637 EXPECT_FALSE(browser_window->IsFullscreen()); 638} 639 640IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, ExtensionsUncached) { 641 // Make it possible to force-install a hosted app and an extension. 642 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 643 TestingUpdateManifestProvider testing_update_manifest_provider( 644 kRelativeUpdateURL); 645 testing_update_manifest_provider.AddUpdate( 646 kHostedAppID, 647 kHostedAppVersion, 648 embedded_test_server()->GetURL(std::string("/") + kHostedAppCRXPath)); 649 testing_update_manifest_provider.AddUpdate( 650 kGoodExtensionID, 651 kGoodExtensionVersion, 652 embedded_test_server()->GetURL(std::string("/") + kGoodExtensionCRXPath)); 653 embedded_test_server()->RegisterRequestHandler( 654 base::Bind(&TestingUpdateManifestProvider::HandleRequest, 655 base::Unretained(&testing_update_manifest_provider))); 656 657 // Specify policy to force-install the hosted app and the extension. 658 em::StringList* forcelist = device_local_account_policy_.payload() 659 .mutable_extensioninstallforcelist()->mutable_value(); 660 forcelist->add_entries(base::StringPrintf( 661 "%s;%s", 662 kHostedAppID, 663 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str())); 664 forcelist->add_entries(base::StringPrintf( 665 "%s;%s", 666 kGoodExtensionID, 667 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str())); 668 669 UploadAndInstallDeviceLocalAccountPolicy(); 670 AddPublicSessionToDevicePolicy(kAccountId1); 671 672 // This observes the display name becoming available as this indicates 673 // device-local account policy is fully loaded, which is a prerequisite for 674 // successful login. 675 content::WindowedNotificationObserver( 676 chrome::NOTIFICATION_USER_LIST_CHANGED, 677 base::Bind(&DisplayNameMatches, user_id_1_, kDisplayName)).Wait(); 678 679 // Wait for the login UI to be ready. 680 chromeos::LoginDisplayHostImpl* host = 681 reinterpret_cast<chromeos::LoginDisplayHostImpl*>( 682 chromeos::LoginDisplayHostImpl::default_host()); 683 ASSERT_TRUE(host); 684 chromeos::OobeUI* oobe_ui = host->GetOobeUI(); 685 ASSERT_TRUE(oobe_ui); 686 base::RunLoop run_loop; 687 const bool oobe_ui_ready = oobe_ui->IsJSReady(run_loop.QuitClosure()); 688 if (!oobe_ui_ready) 689 run_loop.Run(); 690 691 // Ensure that the browser stays alive, even though no windows are opened 692 // during session start. 693 chrome::StartKeepAlive(); 694 695 // Start listening for app/extension installation results. 696 content::WindowedNotificationObserver hosted_app_observer( 697 chrome::NOTIFICATION_EXTENSION_INSTALLED, 698 base::Bind(DoesInstallSuccessReferToId, kHostedAppID)); 699 content::WindowedNotificationObserver extension_observer( 700 chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR, 701 base::Bind(DoesInstallFailureReferToId, kGoodExtensionID)); 702 703 // Start login into the device-local account. 704 host->StartSignInScreen(LoginScreenContext()); 705 chromeos::ExistingUserController* controller = 706 chromeos::ExistingUserController::current_controller(); 707 ASSERT_TRUE(controller); 708 controller->LoginAsPublicAccount(user_id_1_); 709 710 // Wait for the hosted app installation to succeed and the extension 711 // installation to fail (because hosted apps are whitelisted for use in 712 // device-local accounts and extensions are not). 713 hosted_app_observer.Wait(); 714 extension_observer.Wait(); 715 716 // Verify that the hosted app was installed. 717 Profile* profile = GetProfileForTest(); 718 ASSERT_TRUE(profile); 719 ExtensionService* extension_service = 720 extensions::ExtensionSystem::Get(profile)->extension_service(); 721 EXPECT_TRUE(extension_service->GetExtensionById(kHostedAppID, true)); 722 723 // Verify that the extension was not installed. 724 EXPECT_FALSE(extension_service->GetExtensionById(kGoodExtensionID, true)); 725 726 // Verify that the app was copied to the account's extension cache. 727 base::FilePath test_dir; 728 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir)); 729 EXPECT_TRUE(ContentsEqual( 730 GetCacheCRXFile(kAccountId1, kHostedAppID, kHostedAppVersion), 731 test_dir.Append(kHostedAppCRXPath))); 732 733 // Verify that the extension was not copied to the account's extension cache. 734 EXPECT_FALSE(PathExists(GetCacheCRXFile( 735 kAccountId1, kGoodExtensionID, kGoodExtensionVersion))); 736} 737 738IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, ExtensionsCached) { 739 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 740 741 // Pre-populate the device local account's extension cache with a hosted app 742 // and an extension. 743 EXPECT_TRUE(base::CreateDirectory( 744 GetCacheDirectoryForAccountID(kAccountId1))); 745 base::FilePath test_dir; 746 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir)); 747 const base::FilePath cached_hosted_app = 748 GetCacheCRXFile(kAccountId1, kHostedAppID, kHostedAppVersion); 749 EXPECT_TRUE(CopyFile(test_dir.Append(kHostedAppCRXPath), 750 cached_hosted_app)); 751 const base::FilePath cached_extension = 752 GetCacheCRXFile(kAccountId1, kGoodExtensionID, kGoodExtensionVersion); 753 EXPECT_TRUE(CopyFile(test_dir.Append(kGoodExtensionCRXPath), 754 cached_extension)); 755 756 // Specify policy to force-install the hosted app. 757 em::StringList* forcelist = device_local_account_policy_.payload() 758 .mutable_extensioninstallforcelist()->mutable_value(); 759 forcelist->add_entries(base::StringPrintf( 760 "%s;%s", 761 kHostedAppID, 762 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str())); 763 forcelist->add_entries(base::StringPrintf( 764 "%s;%s", 765 kGoodExtensionID, 766 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str())); 767 768 UploadAndInstallDeviceLocalAccountPolicy(); 769 AddPublicSessionToDevicePolicy(kAccountId1); 770 771 // This observes the display name becoming available as this indicates 772 // device-local account policy is fully loaded, which is a prerequisite for 773 // successful login. 774 content::WindowedNotificationObserver( 775 chrome::NOTIFICATION_USER_LIST_CHANGED, 776 base::Bind(&DisplayNameMatches, user_id_1_, kDisplayName)).Wait(); 777 778 // Wait for the login UI to be ready. 779 chromeos::LoginDisplayHostImpl* host = 780 reinterpret_cast<chromeos::LoginDisplayHostImpl*>( 781 chromeos::LoginDisplayHostImpl::default_host()); 782 ASSERT_TRUE(host); 783 chromeos::OobeUI* oobe_ui = host->GetOobeUI(); 784 ASSERT_TRUE(oobe_ui); 785 base::RunLoop run_loop; 786 const bool oobe_ui_ready = oobe_ui->IsJSReady(run_loop.QuitClosure()); 787 if (!oobe_ui_ready) 788 run_loop.Run(); 789 790 // Ensure that the browser stays alive, even though no windows are opened 791 // during session start. 792 chrome::StartKeepAlive(); 793 794 // Start listening for app/extension installation results. 795 content::WindowedNotificationObserver hosted_app_observer( 796 chrome::NOTIFICATION_EXTENSION_INSTALLED, 797 base::Bind(DoesInstallSuccessReferToId, kHostedAppID)); 798 content::WindowedNotificationObserver extension_observer( 799 chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR, 800 base::Bind(DoesInstallFailureReferToId, kGoodExtensionID)); 801 802 // Start login into the device-local account. 803 host->StartSignInScreen(LoginScreenContext()); 804 chromeos::ExistingUserController* controller = 805 chromeos::ExistingUserController::current_controller(); 806 ASSERT_TRUE(controller); 807 controller->LoginAsPublicAccount(user_id_1_); 808 809 // Wait for the hosted app installation to succeed and the extension 810 // installation to fail. 811 hosted_app_observer.Wait(); 812 extension_observer.Wait(); 813 814 // Verify that the hosted app was installed. 815 Profile* profile = GetProfileForTest(); 816 ASSERT_TRUE(profile); 817 ExtensionService* extension_service = 818 extensions::ExtensionSystem::Get(profile)->extension_service(); 819 EXPECT_TRUE(extension_service->GetExtensionById(kHostedAppID, true)); 820 821 // Verify that the extension was not installed. 822 EXPECT_FALSE(extension_service->GetExtensionById(kGoodExtensionID, true)); 823 824 // Verify that the app is still in the account's extension cache. 825 EXPECT_TRUE(PathExists(cached_hosted_app)); 826 827 // Verify that the extension was removed from the account's extension cache. 828 EXPECT_FALSE(PathExists(cached_extension)); 829} 830 831IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, ExternalData) { 832 // chromeos::UserManager requests an external data fetch whenever 833 // the key::kUserAvatarImage policy is set. Since this test wants to 834 // verify that the underlying policy subsystem will start a fetch 835 // without this request as well, the chromeos::UserManager must be 836 // prevented from seeing the policy change. 837 reinterpret_cast<chromeos::UserManagerImpl*>(chromeos::UserManager::Get())-> 838 StopPolicyObserverForTesting(); 839 840 UploadDeviceLocalAccountPolicy(); 841 AddPublicSessionToDevicePolicy(kAccountId1); 842 843 // This observes the display name becoming available as this indicates 844 // device-local account policy is fully loaded. 845 content::WindowedNotificationObserver( 846 chrome::NOTIFICATION_USER_LIST_CHANGED, 847 base::Bind(&DisplayNameMatches, user_id_1_, kDisplayName)).Wait(); 848 849 // Start serving external data at |kExternalDataURL|. 850 scoped_ptr<base::RunLoop> run_loop(new base::RunLoop); 851 scoped_ptr<net::FakeURLFetcherFactory> fetcher_factory( 852 new net::FakeURLFetcherFactory( 853 NULL, 854 base::Bind(&RunCallbackAndReturnFakeURLFetcher, 855 base::MessageLoopProxy::current(), 856 run_loop->QuitClosure()))); 857 fetcher_factory->SetFakeResponse(GURL(kExternalDataURL), 858 kExternalData, 859 net::HTTP_OK, 860 net::URLRequestStatus::SUCCESS); 861 862 // Specify an external data reference for the key::kUserAvatarImage policy. 863 scoped_ptr<base::DictionaryValue> metadata = 864 test::ConstructExternalDataReference(kExternalDataURL, kExternalData); 865 std::string policy; 866 base::JSONWriter::Write(metadata.get(), &policy); 867 device_local_account_policy_.payload().mutable_useravatarimage()->set_value( 868 policy); 869 UploadAndInstallDeviceLocalAccountPolicy(); 870 policy::BrowserPolicyConnectorChromeOS* connector = 871 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 872 DeviceLocalAccountPolicyBroker* broker = 873 connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser( 874 user_id_1_); 875 ASSERT_TRUE(broker); 876 broker->core()->store()->Load(); 877 878 // The external data should be fetched and cached automatically. Wait for this 879 // fetch. 880 run_loop->Run(); 881 882 // Stop serving external data at |kExternalDataURL|. 883 fetcher_factory.reset(); 884 885 const PolicyMap::Entry* policy_entry = 886 broker->core()->store()->policy_map().Get(key::kUserAvatarImage); 887 ASSERT_TRUE(policy_entry); 888 ASSERT_TRUE(policy_entry->external_data_fetcher); 889 890 // Retrieve the external data. Although the data is no longer being served at 891 // |kExternalDataURL|, the retrieval should succeed because the data has been 892 // cached. 893 run_loop.reset(new base::RunLoop); 894 scoped_ptr<std::string> fetched_external_data; 895 policy_entry->external_data_fetcher->Fetch(base::Bind( 896 &test::ExternalDataFetchCallback, 897 &fetched_external_data, 898 run_loop->QuitClosure())); 899 run_loop->Run(); 900 901 ASSERT_TRUE(fetched_external_data); 902 EXPECT_EQ(kExternalData, *fetched_external_data); 903 904 // Wait for the login UI to be ready. 905 chromeos::LoginDisplayHostImpl* host = 906 reinterpret_cast<chromeos::LoginDisplayHostImpl*>( 907 chromeos::LoginDisplayHostImpl::default_host()); 908 ASSERT_TRUE(host); 909 chromeos::OobeUI* oobe_ui = host->GetOobeUI(); 910 ASSERT_TRUE(oobe_ui); 911 run_loop.reset(new base::RunLoop); 912 const bool oobe_ui_ready = oobe_ui->IsJSReady(run_loop->QuitClosure()); 913 if (!oobe_ui_ready) 914 run_loop->Run(); 915 916 // Ensure that the browser stays alive, even though no windows are opened 917 // during session start. 918 chrome::StartKeepAlive(); 919 920 // Start login into the device-local account. 921 host->StartSignInScreen(LoginScreenContext()); 922 chromeos::ExistingUserController* controller = 923 chromeos::ExistingUserController::current_controller(); 924 ASSERT_TRUE(controller); 925 controller->LoginAsPublicAccount(user_id_1_); 926 927 // Wait for the session to start. 928 content::WindowedNotificationObserver(chrome::NOTIFICATION_SESSION_STARTED, 929 base::Bind(IsSessionStarted)).Wait(); 930 931 // Verify that the external data reference has propagated to the device-local 932 // account's ProfilePolicyConnector. 933 ProfilePolicyConnector* policy_connector = 934 ProfilePolicyConnectorFactory::GetForProfile(GetProfileForTest()); 935 ASSERT_TRUE(policy_connector); 936 const PolicyMap& policies = policy_connector->policy_service()->GetPolicies( 937 PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); 938 policy_entry = policies.Get(key::kUserAvatarImage); 939 ASSERT_TRUE(policy_entry); 940 EXPECT_TRUE(base::Value::Equals(metadata.get(), policy_entry->value)); 941 ASSERT_TRUE(policy_entry->external_data_fetcher); 942 943 // Retrieve the external data via the ProfilePolicyConnector. The retrieval 944 // should succeed because the data has been cached. 945 run_loop.reset(new base::RunLoop); 946 fetched_external_data.reset(); 947 policy_entry->external_data_fetcher->Fetch(base::Bind( 948 &test::ExternalDataFetchCallback, 949 &fetched_external_data, 950 run_loop->QuitClosure())); 951 run_loop->Run(); 952 953 ASSERT_TRUE(fetched_external_data); 954 EXPECT_EQ(kExternalData, *fetched_external_data); 955} 956 957IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, UserAvatarImage) { 958 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 959 960 UploadDeviceLocalAccountPolicy(); 961 AddPublicSessionToDevicePolicy(kAccountId1); 962 963 // This observes the display name becoming available as this indicates 964 // device-local account policy is fully loaded. 965 content::WindowedNotificationObserver( 966 chrome::NOTIFICATION_USER_LIST_CHANGED, 967 base::Bind(&DisplayNameMatches, user_id_1_, kDisplayName)).Wait(); 968 969 base::FilePath test_dir; 970 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir)); 971 std::string image_data; 972 ASSERT_TRUE(base::ReadFileToString( 973 test_dir.Append(chromeos::test::kUserAvatarImage1RelativePath), 974 &image_data)); 975 976 std::string policy; 977 base::JSONWriter::Write(test::ConstructExternalDataReference( 978 embedded_test_server()->GetURL(std::string("/") + 979 chromeos::test::kUserAvatarImage1RelativePath).spec(), 980 image_data).get(), 981 &policy); 982 device_local_account_policy_.payload().mutable_useravatarimage()->set_value( 983 policy); 984 UploadAndInstallDeviceLocalAccountPolicy(); 985 policy::BrowserPolicyConnectorChromeOS* connector = 986 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 987 DeviceLocalAccountPolicyBroker* broker = 988 connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser( 989 user_id_1_); 990 ASSERT_TRUE(broker); 991 992 run_loop_.reset(new base::RunLoop); 993 chromeos::UserManager::Get()->AddObserver(this); 994 broker->core()->store()->Load(); 995 run_loop_->Run(); 996 chromeos::UserManager::Get()->RemoveObserver(this); 997 998 scoped_ptr<gfx::ImageSkia> policy_image = chromeos::test::ImageLoader( 999 test_dir.Append(chromeos::test::kUserAvatarImage1RelativePath)).Load(); 1000 ASSERT_TRUE(policy_image); 1001 1002 const chromeos::User* user = 1003 chromeos::UserManager::Get()->FindUser(user_id_1_); 1004 ASSERT_TRUE(user); 1005 1006 base::FilePath user_data_dir; 1007 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)); 1008 const base::FilePath saved_image_path = 1009 user_data_dir.Append(user_id_1_).AddExtension("jpg"); 1010 1011 EXPECT_FALSE(user->HasDefaultImage()); 1012 EXPECT_EQ(chromeos::User::kExternalImageIndex, user->image_index()); 1013 EXPECT_TRUE(chromeos::test::AreImagesEqual(*policy_image, user->image())); 1014 const base::DictionaryValue* images_pref = 1015 g_browser_process->local_state()->GetDictionary("user_image_info"); 1016 ASSERT_TRUE(images_pref); 1017 const base::DictionaryValue* image_properties; 1018 ASSERT_TRUE(images_pref->GetDictionaryWithoutPathExpansion( 1019 user_id_1_, 1020 &image_properties)); 1021 int image_index; 1022 std::string image_path; 1023 ASSERT_TRUE(image_properties->GetInteger("index", &image_index)); 1024 ASSERT_TRUE(image_properties->GetString("path", &image_path)); 1025 EXPECT_EQ(chromeos::User::kExternalImageIndex, image_index); 1026 EXPECT_EQ(saved_image_path.value(), image_path); 1027 1028 scoped_ptr<gfx::ImageSkia> saved_image = 1029 chromeos::test::ImageLoader(saved_image_path).Load(); 1030 ASSERT_TRUE(saved_image); 1031 1032 // Check image dimensions. Images can't be compared since JPEG is lossy. 1033 EXPECT_EQ(policy_image->width(), saved_image->width()); 1034 EXPECT_EQ(policy_image->height(), saved_image->height()); 1035} 1036 1037class TermsOfServiceTest : public DeviceLocalAccountTest, 1038 public testing::WithParamInterface<bool> { 1039}; 1040 1041IN_PROC_BROWSER_TEST_P(TermsOfServiceTest, TermsOfServiceScreen) { 1042 // Specify Terms of Service URL. 1043 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 1044 device_local_account_policy_.payload().mutable_termsofserviceurl()->set_value( 1045 embedded_test_server()->GetURL( 1046 std::string("/") + 1047 (GetParam() ? kExistentTermsOfServicePath 1048 : kNonexistentTermsOfServicePath)).spec()); 1049 UploadAndInstallDeviceLocalAccountPolicy(); 1050 AddPublicSessionToDevicePolicy(kAccountId1); 1051 1052 // Wait for the device-local account policy to be fully loaded. 1053 content::WindowedNotificationObserver( 1054 chrome::NOTIFICATION_USER_LIST_CHANGED, 1055 base::Bind(&DisplayNameMatches, user_id_1_, kDisplayName)).Wait(); 1056 1057 // Wait for the login UI to be ready. 1058 chromeos::LoginDisplayHostImpl* host = 1059 reinterpret_cast<chromeos::LoginDisplayHostImpl*>( 1060 chromeos::LoginDisplayHostImpl::default_host()); 1061 ASSERT_TRUE(host); 1062 chromeos::OobeUI* oobe_ui = host->GetOobeUI(); 1063 ASSERT_TRUE(oobe_ui); 1064 base::RunLoop oobe_ui_wait_run_loop; 1065 const bool oobe_ui_ready = 1066 oobe_ui->IsJSReady(oobe_ui_wait_run_loop.QuitClosure()); 1067 if (!oobe_ui_ready) 1068 oobe_ui_wait_run_loop.Run(); 1069 1070 // Start login into the device-local account. 1071 host->StartSignInScreen(LoginScreenContext()); 1072 chromeos::ExistingUserController* controller = 1073 chromeos::ExistingUserController::current_controller(); 1074 ASSERT_TRUE(controller); 1075 controller->LoginAsPublicAccount(user_id_1_); 1076 1077 // Set up an observer that will quit the message loop when login has succeeded 1078 // and the first wizard screen, if any, is being shown. 1079 base::RunLoop login_wait_run_loop; 1080 chromeos::MockConsumer login_status_consumer; 1081 EXPECT_CALL(login_status_consumer, OnLoginSuccess(_)) 1082 .Times(1) 1083 .WillOnce(InvokeWithoutArgs(&login_wait_run_loop, &base::RunLoop::Quit)); 1084 1085 // Spin the loop until the observer fires. Then, unregister the observer. 1086 controller->set_login_status_consumer(&login_status_consumer); 1087 login_wait_run_loop.Run(); 1088 controller->set_login_status_consumer(NULL); 1089 1090 // Verify that the Terms of Service screen is being shown. 1091 chromeos::WizardController* wizard_controller = 1092 chromeos::WizardController::default_controller(); 1093 ASSERT_TRUE(wizard_controller); 1094 ASSERT_TRUE(wizard_controller->current_screen()); 1095 EXPECT_EQ(chromeos::WizardController::kTermsOfServiceScreenName, 1096 wizard_controller->current_screen()->GetName()); 1097 1098 // Wait for the Terms of Service to finish downloading, then get the status of 1099 // the screen's UI elements. 1100 chromeos::WebUILoginView* web_ui_login_view = host->GetWebUILoginView(); 1101 ASSERT_TRUE(web_ui_login_view); 1102 content::WebUI* web_ui = web_ui_login_view->GetWebUI(); 1103 ASSERT_TRUE(web_ui); 1104 content::WebContents* contents = web_ui->GetWebContents(); 1105 ASSERT_TRUE(contents); 1106 std::string json; 1107 ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents, 1108 "var screen = document.getElementById('terms-of-service');" 1109 "function SendReplyIfDownloadDone() {" 1110 " if (screen.classList.contains('tos-loading'))" 1111 " return false;" 1112 " var status = {};" 1113 " status.heading = document.getElementById('tos-heading').textContent;" 1114 " status.subheading =" 1115 " document.getElementById('tos-subheading').textContent;" 1116 " status.contentHeading =" 1117 " document.getElementById('tos-content-heading').textContent;" 1118 " status.content =" 1119 " document.getElementById('tos-content-main').textContent;" 1120 " status.error = screen.classList.contains('error');" 1121 " status.acceptEnabled =" 1122 " !document.getElementById('tos-accept-button').disabled;" 1123 " domAutomationController.send(JSON.stringify(status));" 1124 " observer.disconnect();" 1125 " return true;" 1126 "}" 1127 "var observer = new MutationObserver(SendReplyIfDownloadDone);" 1128 "if (!SendReplyIfDownloadDone()) {" 1129 " var options = { attributes: true, attributeFilter: [ 'class' ] };" 1130 " observer.observe(screen, options);" 1131 "}", 1132 &json)); 1133 scoped_ptr<base::Value> value_ptr(base::JSONReader::Read(json)); 1134 const base::DictionaryValue* status = NULL; 1135 ASSERT_TRUE(value_ptr.get()); 1136 ASSERT_TRUE(value_ptr->GetAsDictionary(&status)); 1137 std::string heading; 1138 EXPECT_TRUE(status->GetString("heading", &heading)); 1139 std::string subheading; 1140 EXPECT_TRUE(status->GetString("subheading", &subheading)); 1141 std::string content_heading; 1142 EXPECT_TRUE(status->GetString("contentHeading", &content_heading)); 1143 std::string content; 1144 EXPECT_TRUE(status->GetString("content", &content)); 1145 bool error; 1146 EXPECT_TRUE(status->GetBoolean("error", &error)); 1147 bool accept_enabled; 1148 EXPECT_TRUE(status->GetBoolean("acceptEnabled", &accept_enabled)); 1149 1150 // Verify that the screen's headings have been set correctly. 1151 EXPECT_EQ( 1152 l10n_util::GetStringFUTF8(IDS_TERMS_OF_SERVICE_SCREEN_HEADING, 1153 base::UTF8ToUTF16(kDomain)), 1154 heading); 1155 EXPECT_EQ( 1156 l10n_util::GetStringFUTF8(IDS_TERMS_OF_SERVICE_SCREEN_SUBHEADING, 1157 base::UTF8ToUTF16(kDomain)), 1158 subheading); 1159 EXPECT_EQ( 1160 l10n_util::GetStringFUTF8(IDS_TERMS_OF_SERVICE_SCREEN_CONTENT_HEADING, 1161 base::UTF8ToUTF16(kDomain)), 1162 content_heading); 1163 1164 if (!GetParam()) { 1165 // The Terms of Service URL was invalid. Verify that the screen is showing 1166 // an error and the accept button is disabled. 1167 EXPECT_TRUE(error); 1168 EXPECT_FALSE(accept_enabled); 1169 return; 1170 } 1171 1172 // The Terms of Service URL was valid. Verify that the screen is showing the 1173 // downloaded Terms of Service and the accept button is enabled. 1174 base::FilePath test_dir; 1175 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir)); 1176 std::string terms_of_service; 1177 ASSERT_TRUE(base::ReadFileToString( 1178 test_dir.Append(kExistentTermsOfServicePath), &terms_of_service)); 1179 EXPECT_EQ(terms_of_service, content); 1180 EXPECT_FALSE(error); 1181 EXPECT_TRUE(accept_enabled); 1182 1183 // Click the accept button. 1184 ASSERT_TRUE(content::ExecuteScript(contents, 1185 "$('tos-accept-button').click();")); 1186 1187 // Wait for the session to start. 1188 if (!IsSessionStarted()) { 1189 content::WindowedNotificationObserver(chrome::NOTIFICATION_SESSION_STARTED, 1190 base::Bind(IsSessionStarted)).Wait(); 1191 } 1192} 1193 1194INSTANTIATE_TEST_CASE_P(TermsOfServiceTestInstance, 1195 TermsOfServiceTest, testing::Bool()); 1196 1197} // namespace policy 1198