1 // Copyright 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 "chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.h"
6
7 #include <memory>
8 #include <string>
9 #include <utility>
10
11 #include "base/files/file_path.h"
12 #include "base/logging.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/strings/string16.h"
15 #include "base/values.h"
16 #include "chromeos/login/login_state/scoped_test_public_session_login_state.h"
17 #include "extensions/common/extension.h"
18 #include "extensions/common/manifest.h"
19 #include "extensions/common/manifest_constants.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace chromeos {
23
24 namespace {
25
26 const char kWhitelistedId[] = "cbkkbcmdlboombapidmoeolnmdacpkch";
27 const char kBogusId[] = "bogus";
28
CreateExtensionFromValues(const std::string & id,extensions::Manifest::Location location,base::DictionaryValue * values,int flags)29 scoped_refptr<const extensions::Extension> CreateExtensionFromValues(
30 const std::string& id,
31 extensions::Manifest::Location location,
32 base::DictionaryValue* values,
33 int flags) {
34 values->SetString(extensions::manifest_keys::kName, "test");
35 values->SetString(extensions::manifest_keys::kVersion, "0.1");
36 values->SetInteger(extensions::manifest_keys::kManifestVersion, 2);
37 std::string error;
38 return extensions::Extension::Create(base::FilePath(),
39 location,
40 *values,
41 flags,
42 id,
43 &error);
44 }
45
CreateRegularExtension(const std::string & id)46 scoped_refptr<const extensions::Extension> CreateRegularExtension(
47 const std::string& id) {
48 base::DictionaryValue values;
49 return CreateExtensionFromValues(id,
50 extensions::Manifest::INTERNAL,
51 &values,
52 extensions::Extension::NO_FLAGS);
53 }
54
CreateExternalComponentExtension()55 scoped_refptr<const extensions::Extension> CreateExternalComponentExtension() {
56 base::DictionaryValue values;
57 return CreateExtensionFromValues(std::string(),
58 extensions::Manifest::EXTERNAL_COMPONENT,
59 &values,
60 extensions::Extension::NO_FLAGS);
61 }
62
CreateComponentExtension()63 scoped_refptr<const extensions::Extension> CreateComponentExtension() {
64 base::DictionaryValue values;
65 return CreateExtensionFromValues(std::string(),
66 extensions::Manifest::COMPONENT, &values,
67 extensions::Extension::NO_FLAGS);
68 }
69
CreateHostedApp()70 scoped_refptr<const extensions::Extension> CreateHostedApp() {
71 base::DictionaryValue values;
72 values.Set(extensions::manifest_keys::kApp,
73 std::make_unique<base::DictionaryValue>());
74 values.Set(extensions::manifest_keys::kWebURLs,
75 std::make_unique<base::ListValue>());
76 return CreateExtensionFromValues(std::string(),
77 extensions::Manifest::INTERNAL,
78 &values,
79 extensions::Extension::NO_FLAGS);
80 }
81
CreatePlatformAppWithExtraValues(const base::DictionaryValue * extra_values,extensions::Manifest::Location location,int flags)82 scoped_refptr<const extensions::Extension> CreatePlatformAppWithExtraValues(
83 const base::DictionaryValue* extra_values,
84 extensions::Manifest::Location location,
85 int flags) {
86 base::DictionaryValue values;
87 values.SetString("app.background.page", "background.html");
88 values.MergeDictionary(extra_values);
89 return CreateExtensionFromValues(std::string(), location, &values, flags);
90 }
91
CreatePlatformApp()92 scoped_refptr<const extensions::Extension> CreatePlatformApp() {
93 base::DictionaryValue values;
94 return CreatePlatformAppWithExtraValues(&values,
95 extensions::Manifest::INTERNAL,
96 extensions::Extension::NO_FLAGS);
97 }
98
99 } // namespace
100
TEST(DeviceLocalAccountManagementPolicyProviderTest,PublicSession)101 TEST(DeviceLocalAccountManagementPolicyProviderTest, PublicSession) {
102 DeviceLocalAccountManagementPolicyProvider
103 provider(policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION);
104 // Set the login state to a public session.
105 ScopedTestPublicSessionLoginState login_state;
106
107 // Verify that if an extension's location has been whitelisted for use in
108 // public sessions, the extension can be installed.
109 scoped_refptr<const extensions::Extension> extension =
110 CreateExternalComponentExtension();
111 ASSERT_TRUE(extension.get());
112 base::string16 error;
113 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
114 EXPECT_EQ(base::string16(), error);
115 error.clear();
116
117 extension = CreateComponentExtension();
118 ASSERT_TRUE(extension.get());
119 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
120 EXPECT_EQ(base::string16(), error);
121 error.clear();
122
123 // Verify that if an extension's type has been whitelisted for use in
124 // device-local accounts, the extension can be installed.
125 extension = CreateHostedApp();
126 ASSERT_TRUE(extension.get());
127 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
128 EXPECT_EQ(base::string16(), error);
129 error.clear();
130
131 // Verify that if an extension's ID has been explicitly whitelisted for use in
132 // device-local accounts, the extension can be installed.
133 extension = CreateRegularExtension(kWhitelistedId);
134 ASSERT_TRUE(extension.get());
135 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
136 EXPECT_EQ(base::string16(), error);
137 error.clear();
138
139 // Verify that if neither the location, type nor the ID of an extension have
140 // been whitelisted for use in public sessions, the extension cannot be
141 // installed.
142 extension = CreateRegularExtension(std::string());
143 ASSERT_TRUE(extension.get());
144 EXPECT_FALSE(provider.UserMayLoad(extension.get(), &error));
145 EXPECT_NE(base::string16(), error);
146 error.clear();
147
148 // Verify that a minimal platform app can be installed from location
149 // EXTERNAL_POLICY.
150 {
151 base::DictionaryValue values;
152 extension = CreatePlatformAppWithExtraValues(
153 &values,
154 extensions::Manifest::EXTERNAL_POLICY,
155 extensions::Extension::NO_FLAGS);
156 ASSERT_TRUE(extension);
157
158 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
159 EXPECT_EQ(base::string16(), error);
160 error.clear();
161 }
162
163 // Verify that a minimal platform app can be installed from location
164 // EXTERNAL_POLICY_DOWNLOAD.
165 {
166 base::DictionaryValue values;
167 extension = CreatePlatformAppWithExtraValues(
168 &values,
169 extensions::Manifest::EXTERNAL_POLICY_DOWNLOAD,
170 extensions::Extension::NO_FLAGS);
171 ASSERT_TRUE(extension);
172
173 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
174 EXPECT_EQ(base::string16(), error);
175 error.clear();
176 }
177
178 // Verify that a minimal platform app cannot be installed from location
179 // UNPACKED.
180 {
181 base::DictionaryValue values;
182 extension = CreatePlatformAppWithExtraValues(
183 &values,
184 extensions::Manifest::UNPACKED,
185 extensions::Extension::NO_FLAGS);
186 ASSERT_TRUE(extension);
187
188 EXPECT_FALSE(provider.UserMayLoad(extension.get(), &error));
189 EXPECT_NE(base::string16(), error);
190 error.clear();
191 }
192
193 // Verify that a platform app with all safe manifest entries can be installed.
194 {
195 base::DictionaryValue values;
196 values.SetString(extensions::manifest_keys::kDescription, "something");
197 values.SetString(extensions::manifest_keys::kShortName, "something else");
198 auto permissions = std::make_unique<base::ListValue>();
199 permissions->AppendString("alarms");
200 permissions->AppendString("background");
201 values.Set(extensions::manifest_keys::kPermissions, std::move(permissions));
202 auto optional_permissions = std::make_unique<base::ListValue>();
203 optional_permissions->AppendString("alarms");
204 optional_permissions->AppendString("background");
205 values.Set(extensions::manifest_keys::kOptionalPermissions,
206 std::move(optional_permissions));
207 extension = CreatePlatformAppWithExtraValues(
208 &values,
209 extensions::Manifest::EXTERNAL_POLICY,
210 extensions::Extension::NO_FLAGS);
211 ASSERT_TRUE(extension);
212
213 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
214 EXPECT_EQ(base::string16(), error);
215 error.clear();
216 }
217
218 // Verify that a platform app with an unknown manifest entry cannot be
219 // installed.
220 {
221 base::DictionaryValue values;
222 values.SetString("not_whitelisted", "something");
223 extension = CreatePlatformAppWithExtraValues(
224 &values,
225 extensions::Manifest::EXTERNAL_POLICY,
226 extensions::Extension::NO_FLAGS);
227 ASSERT_TRUE(extension);
228
229 EXPECT_FALSE(provider.UserMayLoad(extension.get(), &error));
230 EXPECT_NE(base::string16(), error);
231 error.clear();
232 }
233
234 // Verify that a platform app with an unsafe manifest entry cannot be
235 // installed. Since the program logic is based entirely on whitelists, there
236 // is no significant advantage in testing all unsafe manifest entries
237 // individually.
238 {
239 base::DictionaryValue values;
240 values.Set("chrome_settings_overrides",
241 std::make_unique<base::DictionaryValue>());
242 extension = CreatePlatformAppWithExtraValues(
243 &values,
244 extensions::Manifest::EXTERNAL_POLICY,
245 extensions::Extension::NO_FLAGS);
246 ASSERT_TRUE(extension);
247
248 EXPECT_FALSE(provider.UserMayLoad(extension.get(), &error));
249 EXPECT_NE(base::string16(), error);
250 error.clear();
251 }
252
253 // Verify that a platform app with an unknown manifest entry under "app"
254 // cannot be installed.
255 {
256 base::DictionaryValue values;
257 values.SetString("app.not_whitelisted2", "something2");
258 extension = CreatePlatformAppWithExtraValues(
259 &values,
260 extensions::Manifest::EXTERNAL_POLICY,
261 extensions::Extension::NO_FLAGS);
262 ASSERT_TRUE(extension);
263
264 EXPECT_FALSE(provider.UserMayLoad(extension.get(), &error));
265 EXPECT_NE(base::string16(), error);
266 error.clear();
267 }
268
269 // Verify that a platform app with a safe manifest entry under "app" can be
270 // installed.
271 {
272 base::DictionaryValue values;
273 values.SetString("app.content_security_policy", "something2");
274 extension = CreatePlatformAppWithExtraValues(
275 &values,
276 extensions::Manifest::EXTERNAL_POLICY,
277 extensions::Extension::NO_FLAGS);
278 ASSERT_TRUE(extension);
279
280 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
281 EXPECT_EQ(base::string16(), error);
282 error.clear();
283 }
284
285 // Verify that a hosted app with a safe manifest entry under "app" can be
286 // installed.
287 {
288 base::DictionaryValue values;
289 values.Set(extensions::manifest_keys::kApp,
290 std::make_unique<base::DictionaryValue>());
291 values.Set(extensions::manifest_keys::kWebURLs,
292 std::make_unique<base::ListValue>());
293 values.SetString("app.content_security_policy", "something2");
294 extension = CreateExtensionFromValues(
295 std::string(),
296 extensions::Manifest::EXTERNAL_POLICY,
297 &values,
298 extensions::Extension::NO_FLAGS);
299 ASSERT_TRUE(extension);
300
301 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
302 EXPECT_EQ(base::string16(), error);
303 error.clear();
304 }
305
306 // Verify that a theme with a safe manifest entry under "app" cannot be
307 // installed.
308 {
309 base::DictionaryValue values;
310 values.Set("theme", std::make_unique<base::DictionaryValue>());
311 values.SetString("app.content_security_policy", "something2");
312 extension = CreateExtensionFromValues(
313 std::string(),
314 extensions::Manifest::EXTERNAL_POLICY,
315 &values,
316 extensions::Extension::NO_FLAGS);
317 ASSERT_TRUE(extension);
318
319 EXPECT_FALSE(provider.UserMayLoad(extension.get(), &error));
320 EXPECT_NE(base::string16(), error);
321 error.clear();
322 }
323
324 // Verify that a platform app with an unknown permission entry cannot be
325 // installed.
326 {
327 auto permissions = std::make_unique<base::ListValue>();
328 permissions->AppendString("not_whitelisted_permission");
329 base::DictionaryValue values;
330 values.Set(extensions::manifest_keys::kPermissions, std::move(permissions));
331
332 extension = CreatePlatformAppWithExtraValues(
333 &values,
334 extensions::Manifest::EXTERNAL_POLICY,
335 extensions::Extension::NO_FLAGS);
336 ASSERT_TRUE(extension);
337
338 EXPECT_FALSE(provider.UserMayLoad(extension.get(), &error));
339 EXPECT_NE(base::string16(), error);
340 error.clear();
341 }
342
343 // Verify that a platform app with an unsafe permission entry cannot be
344 // installed. Since the program logic is based entirely on whitelists, there
345 // is no significant advantage in testing all unsafe permissions individually.
346 {
347 auto permissions = std::make_unique<base::ListValue>();
348 permissions->AppendString("experimental");
349 base::DictionaryValue values;
350 values.Set(extensions::manifest_keys::kPermissions, std::move(permissions));
351
352 extension = CreatePlatformAppWithExtraValues(
353 &values,
354 extensions::Manifest::EXTERNAL_POLICY,
355 extensions::Extension::NO_FLAGS);
356 ASSERT_TRUE(extension);
357
358 EXPECT_FALSE(provider.UserMayLoad(extension.get(), &error));
359 EXPECT_NE(base::string16(), error);
360 error.clear();
361 }
362
363 // Verify that a platform app with an unsafe optional permission entry cannot
364 // be installed.
365 {
366 auto permissions = std::make_unique<base::ListValue>();
367 permissions->AppendString("experimental");
368 base::DictionaryValue values;
369 values.Set(extensions::manifest_keys::kOptionalPermissions,
370 std::move(permissions));
371
372 extension = CreatePlatformAppWithExtraValues(
373 &values,
374 extensions::Manifest::EXTERNAL_POLICY,
375 extensions::Extension::NO_FLAGS);
376 ASSERT_TRUE(extension);
377
378 EXPECT_FALSE(provider.UserMayLoad(extension.get(), &error));
379 EXPECT_NE(base::string16(), error);
380 error.clear();
381 }
382
383 // Verify that a platform app with an url_handlers manifest entry and which is
384 // not installed through the web store cannot be installed.
385 {
386 auto matches = std::make_unique<base::ListValue>();
387 matches->AppendString("https://example.com/*");
388 base::DictionaryValue values;
389 values.Set("url_handlers.example_com.matches", std::move(matches));
390 values.SetString("url_handlers.example_com.title", "example title");
391
392 extension = CreatePlatformAppWithExtraValues(
393 &values,
394 extensions::Manifest::EXTERNAL_POLICY,
395 extensions::Extension::NO_FLAGS);
396 ASSERT_TRUE(extension);
397
398 EXPECT_FALSE(provider.UserMayLoad(extension.get(), &error));
399 EXPECT_NE(base::string16(), error);
400 error.clear();
401 }
402
403 // Verify that a platform app with a url_handlers manifest entry and which is
404 // installed through the web store can be installed.
405 {
406 auto matches = std::make_unique<base::ListValue>();
407 matches->AppendString("https://example.com/*");
408 base::DictionaryValue values;
409 values.Set("url_handlers.example_com.matches", std::move(matches));
410 values.SetString("url_handlers.example_com.title", "example title");
411
412 extension = CreatePlatformAppWithExtraValues(
413 &values,
414 extensions::Manifest::EXTERNAL_POLICY,
415 extensions::Extension::FROM_WEBSTORE);
416 ASSERT_TRUE(extension);
417
418 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
419 EXPECT_EQ(base::string16(), error);
420 error.clear();
421 }
422
423 // Verify that a platform app with remote URL permissions can be installed.
424 {
425 auto permissions = std::make_unique<base::ListValue>();
426 permissions->AppendString("https://example.com/");
427 permissions->AppendString("http://example.com/");
428 permissions->AppendString("ftp://example.com/");
429 base::DictionaryValue values;
430 values.Set(extensions::manifest_keys::kPermissions, std::move(permissions));
431
432 extension = CreatePlatformAppWithExtraValues(
433 &values,
434 extensions::Manifest::EXTERNAL_POLICY,
435 extensions::Extension::NO_FLAGS);
436 ASSERT_TRUE(extension);
437
438 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
439 EXPECT_EQ(base::string16(), error);
440 error.clear();
441 }
442
443 // Verify that an extension with remote URL permissions cannot be installed.
444 {
445 auto permissions = std::make_unique<base::ListValue>();
446 permissions->AppendString("https://example.com/");
447 permissions->AppendString("http://example.com/");
448 permissions->AppendString("ftp://example.com/");
449 base::DictionaryValue values;
450 values.Set(extensions::manifest_keys::kPermissions, std::move(permissions));
451
452 extension = CreateExtensionFromValues(
453 std::string(),
454 extensions::Manifest::EXTERNAL_POLICY,
455 &values,
456 extensions::Extension::NO_FLAGS);
457 ASSERT_TRUE(extension);
458
459 EXPECT_FALSE(provider.UserMayLoad(extension.get(), &error));
460 EXPECT_NE(base::string16(), error);
461 error.clear();
462 }
463
464 // Verify that a platform app with a local URL permission cannot be installed.
465 {
466 auto permissions = std::make_unique<base::ListValue>();
467 permissions->AppendString("file:///some/where");
468 base::DictionaryValue values;
469 values.Set(extensions::manifest_keys::kPermissions, std::move(permissions));
470
471 extension = CreatePlatformAppWithExtraValues(
472 &values,
473 extensions::Manifest::EXTERNAL_POLICY,
474 extensions::Extension::NO_FLAGS);
475 ASSERT_TRUE(extension);
476
477 EXPECT_FALSE(provider.UserMayLoad(extension.get(), &error));
478 EXPECT_NE(base::string16(), error);
479 error.clear();
480 }
481
482 // Verify that a platform app with socket dictionary permission can be
483 // installed.
484 {
485 auto socket = std::make_unique<base::DictionaryValue>();
486 auto tcp_list = std::make_unique<base::ListValue>();
487 tcp_list->AppendString("tcp-connect");
488 socket->Set("socket", std::move(tcp_list));
489 auto permissions = std::make_unique<base::ListValue>();
490 permissions->Append(std::move(socket));
491 base::DictionaryValue values;
492 values.Set(extensions::manifest_keys::kPermissions, std::move(permissions));
493
494 extension = CreatePlatformAppWithExtraValues(
495 &values,
496 extensions::Manifest::EXTERNAL_POLICY,
497 extensions::Extension::NO_FLAGS);
498 ASSERT_TRUE(extension);
499
500 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
501 EXPECT_EQ(base::string16(), error);
502 error.clear();
503 }
504
505 // Verify that a platform app with unknown dictionary permission cannot be
506 // installed.
507 {
508 auto socket = std::make_unique<base::DictionaryValue>();
509 auto tcp_list = std::make_unique<base::ListValue>();
510 tcp_list->AppendString("unknown_value");
511 socket->Set("unknown_key", std::move(tcp_list));
512 auto permissions = std::make_unique<base::ListValue>();
513 permissions->Append(std::move(socket));
514 base::DictionaryValue values;
515 values.Set(extensions::manifest_keys::kPermissions, std::move(permissions));
516
517 extension = CreatePlatformAppWithExtraValues(
518 &values,
519 extensions::Manifest::EXTERNAL_POLICY,
520 extensions::Extension::NO_FLAGS);
521 ASSERT_TRUE(extension);
522
523 EXPECT_FALSE(provider.UserMayLoad(extension.get(), &error));
524 EXPECT_NE(base::string16(), error);
525 error.clear();
526 }
527
528 // Verify that an extension can be installed.
529 {
530 base::DictionaryValue values;
531 extension = CreateExtensionFromValues(
532 std::string(),
533 extensions::Manifest::EXTERNAL_POLICY,
534 &values,
535 extensions::Extension::NO_FLAGS);
536 ASSERT_TRUE(extension);
537
538 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
539 EXPECT_EQ(base::string16(), error);
540 error.clear();
541 }
542
543 // Verify that a shared_module can be installed.
544 {
545 base::DictionaryValue values;
546 values.Set("export.whitelist", std::make_unique<base::ListValue>());
547 extension = CreateExtensionFromValues(
548 std::string(),
549 extensions::Manifest::EXTERNAL_POLICY,
550 &values,
551 extensions::Extension::NO_FLAGS);
552 ASSERT_TRUE(extension);
553
554 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
555 EXPECT_EQ(base::string16(), error);
556 error.clear();
557 }
558
559 // Verify that a theme can be installed.
560 {
561 base::DictionaryValue values;
562 values.Set("theme", std::make_unique<base::DictionaryValue>());
563 extension = CreateExtensionFromValues(
564 std::string(),
565 extensions::Manifest::EXTERNAL_POLICY,
566 &values,
567 extensions::Extension::NO_FLAGS);
568 ASSERT_TRUE(extension);
569
570 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
571 EXPECT_EQ(base::string16(), error);
572 error.clear();
573 }
574
575 // Verify that a legacy_packaged_app cannot be installed and that it cannot
576 // have an "app" manifest entry.
577 {
578 base::DictionaryValue values;
579 values.SetString("app.launch.local_path", "something");
580 extension = CreateExtensionFromValues(
581 std::string(),
582 extensions::Manifest::EXTERNAL_POLICY,
583 &values,
584 extensions::Extension::NO_FLAGS);
585 ASSERT_TRUE(extension);
586
587 EXPECT_FALSE(provider.UserMayLoad(extension.get(), &error));
588 EXPECT_NE(base::string16(), error);
589 error.clear();
590 }
591 }
592
TEST(DeviceLocalAccountManagementPolicyProviderTest,KioskAppSessions)593 TEST(DeviceLocalAccountManagementPolicyProviderTest, KioskAppSessions) {
594 std::vector<policy::DeviceLocalAccount::Type> types = {
595 policy::DeviceLocalAccount::TYPE_KIOSK_APP,
596 policy::DeviceLocalAccount::TYPE_WEB_KIOSK_APP};
597
598 for (auto type : types) {
599 LOG(INFO) << "Testing device local account type = "<< static_cast<int>(type);
600 DeviceLocalAccountManagementPolicyProvider provider(type);
601
602 // Verify that a platform app can be installed.
603 scoped_refptr<const extensions::Extension> extension = CreatePlatformApp();
604 ASSERT_TRUE(extension.get());
605 base::string16 error;
606 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
607 EXPECT_EQ(base::string16(), error);
608 error.clear();
609
610 // Verify that an extension whose location has been whitelisted for use in
611 // other types of device-local accounts cannot be installed in a single-app
612 // kiosk session.
613 extension = CreateExternalComponentExtension();
614 ASSERT_TRUE(extension.get());
615 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
616 EXPECT_EQ(base::string16(), error);
617 error.clear();
618
619 extension = CreateComponentExtension();
620 ASSERT_TRUE(extension.get());
621 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
622 EXPECT_EQ(base::string16(), error);
623 error.clear();
624
625 // Verify that an extension whose type has been whitelisted for use in other
626 // types of device-local accounts cannot be installed in a single-app kiosk
627 // session.
628 extension = CreateHostedApp();
629 ASSERT_TRUE(extension.get());
630 EXPECT_FALSE(provider.UserMayLoad(extension.get(), &error));
631 EXPECT_NE(base::string16(), error);
632 error.clear();
633
634 // Verify that an extension whose ID has been whitelisted for use in other
635 // types of device-local accounts cannot be installed in a single-app kiosk
636 // session.
637 extension = CreateRegularExtension(kWhitelistedId);
638 ASSERT_TRUE(extension.get());
639 EXPECT_TRUE(provider.UserMayLoad(extension.get(), &error));
640 EXPECT_EQ(base::string16(), error);
641 error.clear();
642 }
643 }
644
TEST(DeviceLocalAccountManagementPolicyProviderTest,IsWhitelisted)645 TEST(DeviceLocalAccountManagementPolicyProviderTest, IsWhitelisted) {
646 // Whitelisted extension, Chrome Remote Desktop.
647 EXPECT_TRUE(DeviceLocalAccountManagementPolicyProvider::IsWhitelisted(
648 kWhitelistedId));
649
650 // Bogus extension ID (never true).
651 EXPECT_FALSE(DeviceLocalAccountManagementPolicyProvider::IsWhitelisted(
652 kBogusId));
653 }
654
655 } // namespace chromeos
656