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

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

Issue 24261010: Allow explicitly whitelisted apps/extensions in public sessions (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments addressed. Created 7 years, 3 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 #include <utility>
7 8
8 #include "base/basictypes.h" 9 #include "base/basictypes.h"
9 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
10 #include "base/callback.h" 12 #include "base/callback.h"
11 #include "base/command_line.h" 13 #include "base/command_line.h"
12 #include "base/file_util.h" 14 #include "base/file_util.h"
13 #include "base/files/file_path.h" 15 #include "base/files/file_path.h"
14 #include "base/json/json_reader.h" 16 #include "base/json/json_reader.h"
15 #include "base/memory/scoped_ptr.h" 17 #include "base/memory/scoped_ptr.h"
16 #include "base/message_loop/message_loop.h" 18 #include "base/message_loop/message_loop.h"
17 #include "base/path_service.h" 19 #include "base/path_service.h"
18 #include "base/run_loop.h" 20 #include "base/run_loop.h"
19 #include "base/strings/string_util.h" 21 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h"
20 #include "base/strings/utf_string_conversions.h" 23 #include "base/strings/utf_string_conversions.h"
21 #include "base/values.h" 24 #include "base/values.h"
22 #include "chrome/browser/browser_process.h" 25 #include "chrome/browser/browser_process.h"
23 #include "chrome/browser/chrome_notification_types.h" 26 #include "chrome/browser/chrome_notification_types.h"
24 #include "chrome/browser/chromeos/login/existing_user_controller.h" 27 #include "chrome/browser/chromeos/login/existing_user_controller.h"
25 #include "chrome/browser/chromeos/login/login_display_host.h" 28 #include "chrome/browser/chromeos/login/login_display_host.h"
26 #include "chrome/browser/chromeos/login/login_display_host_impl.h" 29 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
27 #include "chrome/browser/chromeos/login/mock_login_status_consumer.h" 30 #include "chrome/browser/chromeos/login/mock_login_status_consumer.h"
28 #include "chrome/browser/chromeos/login/screens/wizard_screen.h" 31 #include "chrome/browser/chromeos/login/screens/wizard_screen.h"
29 #include "chrome/browser/chromeos/login/user.h" 32 #include "chrome/browser/chromeos/login/user.h"
30 #include "chrome/browser/chromeos/login/user_manager.h" 33 #include "chrome/browser/chromeos/login/user_manager.h"
31 #include "chrome/browser/chromeos/login/webui_login_view.h" 34 #include "chrome/browser/chromeos/login/webui_login_view.h"
32 #include "chrome/browser/chromeos/login/wizard_controller.h" 35 #include "chrome/browser/chromeos/login/wizard_controller.h"
33 #include "chrome/browser/chromeos/policy/device_local_account.h" 36 #include "chrome/browser/chromeos/policy/device_local_account.h"
34 #include "chrome/browser/chromeos/policy/device_policy_builder.h" 37 #include "chrome/browser/chromeos/policy/device_policy_builder.h"
35 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" 38 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
39 #include "chrome/browser/extensions/extension_service.h"
40 #include "chrome/browser/extensions/extension_system.h"
36 #include "chrome/browser/lifetime/application_lifetime.h" 41 #include "chrome/browser/lifetime/application_lifetime.h"
37 #include "chrome/browser/policy/cloud/cloud_policy_constants.h" 42 #include "chrome/browser/policy/cloud/cloud_policy_constants.h"
38 #include "chrome/browser/policy/cloud/policy_builder.h" 43 #include "chrome/browser/policy/cloud/policy_builder.h"
39 #include "chrome/browser/policy/policy_service.h" 44 #include "chrome/browser/policy/policy_service.h"
40 #include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h" 45 #include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h"
41 #include "chrome/browser/policy/test/local_policy_test_server.h" 46 #include "chrome/browser/policy/test/local_policy_test_server.h"
42 #include "chrome/browser/prefs/session_startup_pref.h" 47 #include "chrome/browser/prefs/session_startup_pref.h"
43 #include "chrome/browser/profiles/profile.h" 48 #include "chrome/browser/profiles/profile.h"
44 #include "chrome/browser/profiles/profile_manager.h" 49 #include "chrome/browser/profiles/profile_manager.h"
45 #include "chrome/browser/ui/browser.h" 50 #include "chrome/browser/ui/browser.h"
46 #include "chrome/browser/ui/browser_commands.h" 51 #include "chrome/browser/ui/browser_commands.h"
47 #include "chrome/browser/ui/browser_finder.h" 52 #include "chrome/browser/ui/browser_finder.h"
48 #include "chrome/browser/ui/browser_list.h" 53 #include "chrome/browser/ui/browser_list.h"
49 #include "chrome/browser/ui/browser_window.h" 54 #include "chrome/browser/ui/browser_window.h"
50 #include "chrome/browser/ui/host_desktop.h" 55 #include "chrome/browser/ui/host_desktop.h"
51 #include "chrome/browser/ui/tabs/tab_strip_model.h" 56 #include "chrome/browser/ui/tabs/tab_strip_model.h"
52 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" 57 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
53 #include "chrome/common/chrome_paths.h" 58 #include "chrome/common/chrome_paths.h"
54 #include "chrome/common/chrome_switches.h" 59 #include "chrome/common/chrome_switches.h"
60 #include "chrome/common/extensions/extension.h"
55 #include "chromeos/chromeos_switches.h" 61 #include "chromeos/chromeos_switches.h"
56 #include "chromeos/dbus/cryptohome_client.h" 62 #include "chromeos/dbus/cryptohome_client.h"
57 #include "chromeos/dbus/dbus_method_call_status.h" 63 #include "chromeos/dbus/dbus_method_call_status.h"
58 #include "chromeos/dbus/fake_cryptohome_client.h" 64 #include "chromeos/dbus/fake_cryptohome_client.h"
59 #include "chromeos/dbus/fake_session_manager_client.h" 65 #include "chromeos/dbus/fake_session_manager_client.h"
60 #include "chromeos/dbus/session_manager_client.h" 66 #include "chromeos/dbus/session_manager_client.h"
67 #include "content/public/browser/notification_details.h"
61 #include "content/public/browser/web_contents.h" 68 #include "content/public/browser/web_contents.h"
62 #include "content/public/browser/web_ui.h" 69 #include "content/public/browser/web_ui.h"
63 #include "content/public/test/browser_test_utils.h" 70 #include "content/public/test/browser_test_utils.h"
64 #include "content/public/test/test_utils.h" 71 #include "content/public/test/test_utils.h"
65 #include "crypto/rsa_private_key.h" 72 #include "crypto/rsa_private_key.h"
66 #include "grit/chromium_strings.h" 73 #include "grit/chromium_strings.h"
67 #include "grit/generated_resources.h" 74 #include "grit/generated_resources.h"
75 #include "net/http/http_status_code.h"
68 #include "net/test/embedded_test_server/embedded_test_server.h" 76 #include "net/test/embedded_test_server/embedded_test_server.h"
77 #include "net/test/embedded_test_server/http_request.h"
78 #include "net/test/embedded_test_server/http_response.h"
69 #include "testing/gmock/include/gmock/gmock.h" 79 #include "testing/gmock/include/gmock/gmock.h"
70 #include "third_party/cros_system_api/dbus/service_constants.h" 80 #include "third_party/cros_system_api/dbus/service_constants.h"
71 #include "ui/base/l10n/l10n_util.h" 81 #include "ui/base/l10n/l10n_util.h"
72 #include "url/gurl.h" 82 #include "url/gurl.h"
73 83
74 namespace em = enterprise_management; 84 namespace em = enterprise_management;
75 85
76 using testing::InvokeWithoutArgs; 86 using testing::InvokeWithoutArgs;
77 using testing::Return; 87 using testing::Return;
78 using testing::_; 88 using testing::_;
79 89
80 namespace policy { 90 namespace policy {
81 91
82 namespace { 92 namespace {
83 93
84 const char kDomain[] = "example.com"; 94 const char kDomain[] = "example.com";
85 const char kAccountId1[] = "dla1@example.com"; 95 const char kAccountId1[] = "dla1@example.com";
86 const char kAccountId2[] = "dla2@example.com"; 96 const char kAccountId2[] = "dla2@example.com";
87 const char kDisplayName[] = "display name"; 97 const char kDisplayName[] = "display name";
88 const char* kStartupURLs[] = { 98 const char* kStartupURLs[] = {
89 "chrome://policy", 99 "chrome://policy",
90 "chrome://about", 100 "chrome://about",
91 }; 101 };
92 const char kExistentTermsOfServicePath[] = "chromeos/enterprise/tos.txt"; 102 const char kExistentTermsOfServicePath[] = "chromeos/enterprise/tos.txt";
93 const char kNonexistentTermsOfServicePath[] = "chromeos/enterprise/tos404.txt"; 103 const char kNonexistentTermsOfServicePath[] = "chromeos/enterprise/tos404.txt";
104 const char kRelativeUpdateURL[] = "/service/update2/crx";
105 const char kUpdateManifestHeader[] =
106 "<?xml version='1.0' encoding='UTF-8'?>\n"
107 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>\n";
108 const char kUpdateManifestTemplate[] =
109 " <app appid='%s'>\n"
110 " <updatecheck codebase='%s' version='%s' />\n"
111 " </app>\n";
112 const char kUpdateManifestFooter[] =
113 "</gupdate>\n";
114 const char kHostedAppID[] = "kbmnembihfiondgfjekmnmcbddelicoi";
115 const char kHostedAppCRXPath[] = "extensions/hosted_app.crx";
116 const char kHostedAppVersion[] = "0.1";
117 const char kGoodExtensionID[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
118 const char kGoodExtensionPath[] = "extensions/good.crx";
119 const char kGoodExtensionVersion[] = "1.0";
120
121 // Helper that serves extension update manifests to Chrome. The helper registers
122 // itself with the |test_server|, serving update manifests for all extensions in
123 // |extension_map| at |relative_update_url|.
124 // The CRX files for these extensions must be served by the same |test_server|.
125 // For each extension, the |extension_map| should contain the path to the CRX
126 // file (relative to the directory from which the |test_server| serves files)
127 // and its version.
128 class TestingUpdateManifestProvider {
129 public:
130 typedef std::map<std::string, std::pair<std::string, std::string> >
131 ExtensionMap;
132
133 TestingUpdateManifestProvider(
134 net::test_server::EmbeddedTestServer* test_server,
135 const std::string& relative_update_url,
136 const ExtensionMap& extension_map);
137 ~TestingUpdateManifestProvider();
138
139 scoped_ptr<net::test_server::HttpResponse> HandleRequest(
140 const net::test_server::HttpRequest& request);
141
142 private:
143 net::test_server::EmbeddedTestServer* test_server_; // Not owned.
144 const std::string relative_update_url_;
145 const ExtensionMap extension_map_;
146
147 DISALLOW_COPY_AND_ASSIGN(TestingUpdateManifestProvider);
148 };
149
150 class ExtensionInstallSuccessObserver
151 : public content::WindowedNotificationObserver {
152 public:
153 explicit ExtensionInstallSuccessObserver(const std::string& id);
154 ~ExtensionInstallSuccessObserver();
155
156 private:
157 bool CheckNotification();
158
159 const std::string id_;
160
161 DISALLOW_COPY_AND_ASSIGN(ExtensionInstallSuccessObserver);
162 };
163
164 class ExtensionInstallFailureObserver
165 : public content::WindowedNotificationObserver {
166 public:
167 explicit ExtensionInstallFailureObserver(const std::string& id);
168 ~ExtensionInstallFailureObserver();
169
170 private:
171 bool CheckNotification();
172
173 const string16 id_;
174
175 DISALLOW_COPY_AND_ASSIGN(ExtensionInstallFailureObserver);
176 };
177
178 ExtensionInstallSuccessObserver::ExtensionInstallSuccessObserver(
179 const std::string& id)
180 : content::WindowedNotificationObserver(
181 chrome::NOTIFICATION_EXTENSION_INSTALLED,
182 base::Bind(&ExtensionInstallSuccessObserver::CheckNotification,
183 base::Unretained(this))),
184 id_(id) {
185 }
186
187 ExtensionInstallSuccessObserver::~ExtensionInstallSuccessObserver() {
188 }
189
190 bool ExtensionInstallSuccessObserver::CheckNotification() {
191 return content::Details<const extensions::InstalledExtensionInfo>(
192 details())->extension->id() == id_;
193 }
194
195 ExtensionInstallFailureObserver::ExtensionInstallFailureObserver(
196 const std::string& id)
197 : content::WindowedNotificationObserver(
198 chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR,
199 base::Bind(&ExtensionInstallFailureObserver::CheckNotification,
200 base::Unretained(this))),
201 id_(UTF8ToUTF16(id)) {
202 }
203
204 ExtensionInstallFailureObserver::~ExtensionInstallFailureObserver() {
205 }
206
207 bool ExtensionInstallFailureObserver::CheckNotification() {
208 return content::Details<const string16>(details())->find(id_) !=
209 string16::npos;
210 }
211
212 TestingUpdateManifestProvider::TestingUpdateManifestProvider(
Mattias Nissler (ping if slow) 2013/09/25 12:04:08 Definition order doesn't match declaration order.
bartfab (slow) 2013/09/26 12:39:13 Done.
213 net::test_server::EmbeddedTestServer* test_server,
214 const std::string& relative_update_url,
215 const ExtensionMap& extension_map)
Mattias Nissler (ping if slow) 2013/09/25 12:04:08 Instead of passing in the map, can we just make an
bartfab (slow) 2013/09/26 12:39:13 Done.
216 : test_server_(test_server),
217 relative_update_url_(relative_update_url),
218 extension_map_(extension_map) {
219 test_server_->RegisterRequestHandler(
Mattias Nissler (ping if slow) 2013/09/25 12:04:08 I'd just leave this to the user.
bartfab (slow) 2013/09/26 12:39:13 Done.
220 base::Bind(&TestingUpdateManifestProvider::HandleRequest,
221 base::Unretained(this)));
222 }
223
224 TestingUpdateManifestProvider::~TestingUpdateManifestProvider() {
225 }
226
227 scoped_ptr<net::test_server::HttpResponse>
228 TestingUpdateManifestProvider::HandleRequest(
229 const net::test_server::HttpRequest& request) {
230 if (request.relative_url.find(relative_update_url_) != 0)
231 return scoped_ptr<net::test_server::HttpResponse>();
232
233 std::string content = kUpdateManifestHeader;
234 size_t id_pos = 0;
235 while ((id_pos = request.relative_url.find("id%3D", id_pos)) !=
236 std::string::npos) {
237 id_pos += 5;
238 const std::string id = request.relative_url.substr(id_pos, 32);
239 id_pos += 32;
240 ExtensionMap::const_iterator entry = extension_map_.find(id);
241 if (entry != extension_map_.end()) {
242 content += base::StringPrintf(
243 kUpdateManifestTemplate,
244 id.c_str(),
245 test_server_->GetURL(std::string("/") + entry->second.first)
246 .spec().c_str(),
247 entry->second.second.c_str());
248 }
249 }
250 content += kUpdateManifestFooter;
251 scoped_ptr<net::test_server::BasicHttpResponse>
252 http_response(new net::test_server::BasicHttpResponse);
253 http_response->set_code(net::HTTP_OK);
254 http_response->set_content(content);
255 http_response->set_content_type("text/xml");
256 return http_response.PassAs<net::test_server::HttpResponse>();
257 }
94 258
95 } // namespace 259 } // namespace
96 260
97 class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest { 261 class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest {
98 protected: 262 protected:
99 DeviceLocalAccountTest() 263 DeviceLocalAccountTest()
100 : user_id_1_(GenerateDeviceLocalAccountUserId( 264 : user_id_1_(GenerateDeviceLocalAccountUserId(
101 kAccountId1, DeviceLocalAccount::TYPE_PUBLIC_SESSION)), 265 kAccountId1, DeviceLocalAccount::TYPE_PUBLIC_SESSION)),
102 user_id_2_(GenerateDeviceLocalAccountUserId( 266 user_id_2_(GenerateDeviceLocalAccountUserId(
103 kAccountId2, DeviceLocalAccount::TYPE_PUBLIC_SESSION)) {} 267 kAccountId2, DeviceLocalAccount::TYPE_PUBLIC_SESSION)) {}
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 BrowserWindow* browser_window = browser->window(); 578 BrowserWindow* browser_window = browser->window();
415 ASSERT_TRUE(browser_window); 579 ASSERT_TRUE(browser_window);
416 chrome::EndKeepAlive(); 580 chrome::EndKeepAlive();
417 581
418 // Verify that an attempt to enter fullscreen mode is denied. 582 // Verify that an attempt to enter fullscreen mode is denied.
419 EXPECT_FALSE(browser_window->IsFullscreen()); 583 EXPECT_FALSE(browser_window->IsFullscreen());
420 chrome::ToggleFullscreenMode(browser); 584 chrome::ToggleFullscreenMode(browser);
421 EXPECT_FALSE(browser_window->IsFullscreen()); 585 EXPECT_FALSE(browser_window->IsFullscreen());
422 } 586 }
423 587
588 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, ExtensionWhitelist) {
589 // Make it possible to force-install a hosted app and an extension.
590 TestingUpdateManifestProvider::ExtensionMap extension_map;
591 extension_map[kHostedAppID] =
592 std::pair<std::string, std::string>(kHostedAppCRXPath,
593 kHostedAppVersion);
594 extension_map[kGoodExtensionID] =
595 std::pair<std::string, std::string>(kGoodExtensionPath,
596 kGoodExtensionVersion);
597 TestingUpdateManifestProvider testing_update_manifest_provider(
598 embedded_test_server(),
599 kRelativeUpdateURL,
600 extension_map);
601 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
602
603 // Specify policy to force-install the hosted app and the extension.
604 em::StringList* forcelist = device_local_account_policy_.payload()
605 .mutable_extensioninstallforcelist()->mutable_value();
606 forcelist->add_entries(base::StringPrintf(
607 "%s;%s",
608 kHostedAppID,
609 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str()));
610 forcelist->add_entries(base::StringPrintf(
611 "%s;%s",
612 kGoodExtensionID,
613 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str()));
614
615 UploadAndInstallDeviceLocalAccountPolicy();
616 AddPublicSessionToDevicePolicy(kAccountId1);
617
618 // This observes the display name becoming available as this indicates
619 // device-local account policy is fully loaded, which is a prerequisite for
620 // successful login.
621 content::WindowedNotificationObserver(
622 chrome::NOTIFICATION_USER_LIST_CHANGED,
623 base::Bind(&DisplayNameMatches, user_id_1_, kDisplayName)).Wait();
624
625 // Wait for the login UI to be ready.
626 chromeos::LoginDisplayHostImpl* host =
627 reinterpret_cast<chromeos::LoginDisplayHostImpl*>(
628 chromeos::LoginDisplayHostImpl::default_host());
629 ASSERT_TRUE(host);
630 chromeos::OobeUI* oobe_ui = host->GetOobeUI();
631 ASSERT_TRUE(oobe_ui);
632 base::RunLoop run_loop;
633 const bool oobe_ui_ready = oobe_ui->IsJSReady(run_loop.QuitClosure());
634 if (!oobe_ui_ready)
635 run_loop.Run();
636
637 // Ensure that the browser stays alive, even though no windows are opened
638 // during session start.
639 chrome::StartKeepAlive();
640
641 // Start listening for app/extension installation results.
642 ExtensionInstallSuccessObserver hosted_app_observer(kHostedAppID);
643 ExtensionInstallFailureObserver extension_observer(kGoodExtensionID);
644
645 // Start login into the device-local account.
646 host->StartSignInScreen();
647 chromeos::ExistingUserController* controller =
648 chromeos::ExistingUserController::current_controller();
649 ASSERT_TRUE(controller);
650 controller->LoginAsPublicAccount(user_id_1_);
651
652 // Wait for the hosted app installation to succeed and the extension
653 // installation to fail.
654 hosted_app_observer.Wait();
655 extension_observer.Wait();
656
657 // Verify that the hosted app was installed.
658 Profile* profile = ProfileManager::GetDefaultProfile();
659 ASSERT_TRUE(profile);
660 ExtensionService* extension_service =
661 extensions::ExtensionSystem::Get(profile)->extension_service();
662 EXPECT_TRUE(extension_service->GetExtensionById(kHostedAppID, true));
663
664 // Verify that the extension was not installed.
665 EXPECT_FALSE(extension_service->GetExtensionById(kGoodExtensionID, true));
666 }
667
424 class TermsOfServiceTest : public DeviceLocalAccountTest, 668 class TermsOfServiceTest : public DeviceLocalAccountTest,
425 public testing::WithParamInterface<bool> { 669 public testing::WithParamInterface<bool> {
426 }; 670 };
427 671
428 IN_PROC_BROWSER_TEST_P(TermsOfServiceTest, TermsOfServiceScreen) { 672 IN_PROC_BROWSER_TEST_P(TermsOfServiceTest, TermsOfServiceScreen) {
429 // Specify Terms of Service URL. 673 // Specify Terms of Service URL.
430 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 674 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
431 device_local_account_policy_.payload().mutable_termsofserviceurl()->set_value( 675 device_local_account_policy_.payload().mutable_termsofserviceurl()->set_value(
432 embedded_test_server()->GetURL( 676 embedded_test_server()->GetURL(
433 std::string("/") + 677 std::string("/") +
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 if (!IsSessionStarted()) { 819 if (!IsSessionStarted()) {
576 content::WindowedNotificationObserver(chrome::NOTIFICATION_SESSION_STARTED, 820 content::WindowedNotificationObserver(chrome::NOTIFICATION_SESSION_STARTED,
577 base::Bind(IsSessionStarted)).Wait(); 821 base::Bind(IsSessionStarted)).Wait();
578 } 822 }
579 } 823 }
580 824
581 INSTANTIATE_TEST_CASE_P(TermsOfServiceTestInstance, 825 INSTANTIATE_TEST_CASE_P(TermsOfServiceTestInstance,
582 TermsOfServiceTest, testing::Bool()); 826 TermsOfServiceTest, testing::Bool());
583 827
584 } // namespace policy 828 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698