Extensions: Implement IsPrivilegeIncrease without the legacy GetMessages.
[chromium-blink-merge.git] / chrome / common / extensions / permissions / permission_set_unittest.cc
blob5612c76f5b8f35a6f40d8a748cb70f34c8d852f7
1 // Copyright (c) 2012 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.
5 #include "base/command_line.h"
6 #include "base/json/json_file_value_serializer.h"
7 #include "base/logging.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/common/chrome_paths.h"
12 #include "chrome/common/chrome_switches.h"
13 #include "chrome/common/extensions/extension_test_util.h"
14 #include "chrome/common/extensions/features/feature_channel.h"
15 #include "chrome/common/extensions/permissions/chrome_permission_message_provider.h"
16 #include "chrome/grit/generated_resources.h"
17 #include "components/version_info/version_info.h"
18 #include "extensions/common/error_utils.h"
19 #include "extensions/common/extension.h"
20 #include "extensions/common/extension_builder.h"
21 #include "extensions/common/permissions/permission_message_provider.h"
22 #include "extensions/common/permissions/permission_message_test_util.h"
23 #include "extensions/common/permissions/permission_message_util.h"
24 #include "extensions/common/permissions/permission_set.h"
25 #include "extensions/common/permissions/permissions_data.h"
26 #include "extensions/common/permissions/permissions_info.h"
27 #include "extensions/common/permissions/socket_permission.h"
28 #include "extensions/common/value_builder.h"
29 #include "extensions/strings/grit/extensions_strings.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31 #include "ui/base/l10n/l10n_util.h"
33 using extension_test_util::LoadManifest;
35 namespace extensions {
37 namespace {
39 static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
40 int schemes = URLPattern::SCHEME_ALL;
41 extent->AddPattern(URLPattern(schemes, pattern));
44 size_t IndexOf(const CoalescedPermissionMessages& warnings,
45 const std::string& warning) {
46 size_t i = 0;
47 for (const CoalescedPermissionMessage& msg : warnings) {
48 if (msg.message() == base::ASCIIToUTF16(warning))
49 return i;
50 ++i;
53 return warnings.size();
56 PermissionIDSet MakePermissionIDSet(APIPermission::ID id) {
57 PermissionIDSet set;
58 set.insert(id);
59 return set;
62 PermissionIDSet MakePermissionIDSet(APIPermission::ID id1,
63 APIPermission::ID id2) {
64 PermissionIDSet set;
65 set.insert(id1);
66 set.insert(id2);
67 return set;
70 PermissionIDSet MakePermissionIDSet(const APIPermissionSet& permissions) {
71 PermissionIDSet set;
72 for (const APIPermission* permission : permissions)
73 set.insert(permission->id());
74 return set;
77 std::string PermissionIDsToString(const PermissionIDSet& ids) {
78 std::vector<std::string> strs;
79 for (const PermissionID& id : ids)
80 strs.push_back(base::IntToString(id.id()));
81 return base::StringPrintf("[ %s ]", base::JoinString(strs, ", ").c_str());
84 std::string CoalescedPermissionIDsToString(
85 const CoalescedPermissionMessages& msgs) {
86 std::vector<std::string> strs;
87 for (const CoalescedPermissionMessage& msg : msgs)
88 strs.push_back(PermissionIDsToString(msg.permissions()));
89 return base::JoinString(strs, " ");
92 // Check that the given |permissions| produce a single warning message,
93 // identified by the set of |expected_ids|.
94 testing::AssertionResult PermissionSetProducesMessage(
95 const PermissionSet* permissions,
96 Manifest::Type extension_type,
97 const PermissionIDSet& expected_ids) {
98 const PermissionMessageProvider* provider = PermissionMessageProvider::Get();
100 CoalescedPermissionMessages msgs = provider->GetPermissionMessages(
101 provider->GetAllPermissionIDs(permissions, extension_type));
102 if (msgs.size() != 1) {
103 return testing::AssertionFailure()
104 << "Expected single permission message with IDs "
105 << PermissionIDsToString(expected_ids) << " but got " << msgs.size()
106 << " messages: " << CoalescedPermissionIDsToString(msgs);
108 if (!msgs.front().permissions().Equals(expected_ids)) {
109 return testing::AssertionFailure()
110 << "Expected permission IDs " << PermissionIDsToString(expected_ids)
111 << " but got " << PermissionIDsToString(msgs.front().permissions());
114 return testing::AssertionSuccess();
117 } // namespace
119 // Tests GetByID.
120 TEST(PermissionsTest, GetByID) {
121 PermissionsInfo* info = PermissionsInfo::GetInstance();
122 APIPermissionSet apis = info->GetAll();
123 for (APIPermissionSet::const_iterator i = apis.begin();
124 i != apis.end(); ++i) {
125 EXPECT_EQ(i->id(), i->info()->id());
129 // Tests that GetByName works with normal permission names and aliases.
130 TEST(PermissionsTest, GetByName) {
131 PermissionsInfo* info = PermissionsInfo::GetInstance();
132 EXPECT_EQ(APIPermission::kTab, info->GetByName("tabs")->id());
133 EXPECT_EQ(APIPermission::kManagement,
134 info->GetByName("management")->id());
135 EXPECT_FALSE(info->GetByName("alsdkfjasldkfj"));
138 TEST(PermissionsTest, GetAll) {
139 size_t count = 0;
140 PermissionsInfo* info = PermissionsInfo::GetInstance();
141 APIPermissionSet apis = info->GetAll();
142 for (APIPermissionSet::const_iterator api = apis.begin();
143 api != apis.end(); ++api) {
144 // Make sure only the valid permission IDs get returned.
145 EXPECT_NE(APIPermission::kInvalid, api->id());
146 EXPECT_NE(APIPermission::kUnknown, api->id());
147 count++;
149 EXPECT_EQ(count, info->get_permission_count());
152 TEST(PermissionsTest, GetAllByName) {
153 std::set<std::string> names;
154 names.insert("background");
155 names.insert("management");
157 // This is an alias of kTab
158 names.insert("windows");
160 // This unknown name should get dropped.
161 names.insert("sdlkfjasdlkfj");
163 APIPermissionSet expected;
164 expected.insert(APIPermission::kBackground);
165 expected.insert(APIPermission::kManagement);
166 expected.insert(APIPermission::kTab);
168 EXPECT_EQ(expected,
169 PermissionsInfo::GetInstance()->GetAllByName(names));
172 // Tests that the aliases are properly mapped.
173 TEST(PermissionsTest, Aliases) {
174 PermissionsInfo* info = PermissionsInfo::GetInstance();
175 // tabs: tabs, windows
176 std::string tabs_name = "tabs";
177 EXPECT_EQ(tabs_name, info->GetByID(APIPermission::kTab)->name());
178 EXPECT_EQ(APIPermission::kTab, info->GetByName("tabs")->id());
179 EXPECT_EQ(APIPermission::kTab, info->GetByName("windows")->id());
181 // unlimitedStorage: unlimitedStorage, unlimited_storage
182 std::string storage_name = "unlimitedStorage";
183 EXPECT_EQ(storage_name, info->GetByID(
184 APIPermission::kUnlimitedStorage)->name());
185 EXPECT_EQ(APIPermission::kUnlimitedStorage,
186 info->GetByName("unlimitedStorage")->id());
187 EXPECT_EQ(APIPermission::kUnlimitedStorage,
188 info->GetByName("unlimited_storage")->id());
191 TEST(PermissionsTest, EffectiveHostPermissions) {
192 scoped_refptr<Extension> extension;
193 scoped_refptr<const PermissionSet> permissions;
195 extension = LoadManifest("effective_host_permissions", "empty.json");
196 permissions = extension->permissions_data()->active_permissions();
197 EXPECT_EQ(0u,
198 extension->permissions_data()
199 ->GetEffectiveHostPermissions()
200 .patterns()
201 .size());
202 EXPECT_FALSE(
203 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com")));
204 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
206 extension = LoadManifest("effective_host_permissions", "one_host.json");
207 permissions = extension->permissions_data()->active_permissions();
208 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
209 GURL("http://www.google.com")));
210 EXPECT_FALSE(permissions->HasEffectiveAccessToURL(
211 GURL("https://www.google.com")));
212 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
214 extension = LoadManifest("effective_host_permissions",
215 "one_host_wildcard.json");
216 permissions = extension->permissions_data()->active_permissions();
217 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com")));
218 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
219 GURL("http://foo.google.com")));
220 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
222 extension = LoadManifest("effective_host_permissions", "two_hosts.json");
223 permissions = extension->permissions_data()->active_permissions();
224 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
225 GURL("http://www.google.com")));
226 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
227 GURL("http://www.reddit.com")));
228 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
230 extension = LoadManifest("effective_host_permissions",
231 "https_not_considered.json");
232 permissions = extension->permissions_data()->active_permissions();
233 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com")));
234 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("https://google.com")));
235 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
237 extension = LoadManifest("effective_host_permissions",
238 "two_content_scripts.json");
239 permissions = extension->permissions_data()->active_permissions();
240 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com")));
241 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
242 GURL("http://www.reddit.com")));
243 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
244 GURL("http://news.ycombinator.com")));
245 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
247 extension = LoadManifest("effective_host_permissions", "all_hosts.json");
248 permissions = extension->permissions_data()->active_permissions();
249 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://test/")));
250 EXPECT_FALSE(permissions->HasEffectiveAccessToURL(GURL("https://test/")));
251 EXPECT_TRUE(
252 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com")));
253 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
255 extension = LoadManifest("effective_host_permissions", "all_hosts2.json");
256 permissions = extension->permissions_data()->active_permissions();
257 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://test/")));
258 EXPECT_TRUE(
259 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com")));
260 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
262 extension = LoadManifest("effective_host_permissions", "all_hosts3.json");
263 permissions = extension->permissions_data()->active_permissions();
264 EXPECT_FALSE(permissions->HasEffectiveAccessToURL(GURL("http://test/")));
265 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("https://test/")));
266 EXPECT_TRUE(
267 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com")));
268 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
271 TEST(PermissionsTest, ExplicitAccessToOrigin) {
272 APIPermissionSet apis;
273 ManifestPermissionSet manifest_permissions;
274 URLPatternSet explicit_hosts;
275 URLPatternSet scriptable_hosts;
277 AddPattern(&explicit_hosts, "http://*.google.com/*");
278 // The explicit host paths should get set to /*.
279 AddPattern(&explicit_hosts, "http://www.example.com/a/particular/path/*");
281 scoped_refptr<PermissionSet> perm_set = new PermissionSet(
282 apis, manifest_permissions, explicit_hosts, scriptable_hosts);
283 ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin(
284 GURL("http://www.google.com/")));
285 ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin(
286 GURL("http://test.google.com/")));
287 ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin(
288 GURL("http://www.example.com")));
289 ASSERT_TRUE(perm_set->HasEffectiveAccessToURL(
290 GURL("http://www.example.com")));
291 ASSERT_FALSE(perm_set->HasExplicitAccessToOrigin(
292 GURL("http://test.example.com")));
295 TEST(PermissionsTest, CreateUnion) {
296 APIPermission* permission = NULL;
298 ManifestPermissionSet manifest_permissions;
299 APIPermissionSet apis1;
300 APIPermissionSet apis2;
301 APIPermissionSet expected_apis;
303 URLPatternSet explicit_hosts1;
304 URLPatternSet explicit_hosts2;
305 URLPatternSet expected_explicit_hosts;
307 URLPatternSet scriptable_hosts1;
308 URLPatternSet scriptable_hosts2;
309 URLPatternSet expected_scriptable_hosts;
311 URLPatternSet effective_hosts;
313 scoped_refptr<PermissionSet> set1;
314 scoped_refptr<PermissionSet> set2;
315 scoped_refptr<PermissionSet> union_set;
317 const APIPermissionInfo* permission_info =
318 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket);
319 permission = permission_info->CreateAPIPermission();
321 scoped_ptr<base::ListValue> value(new base::ListValue());
322 value->Append(new base::StringValue("tcp-connect:*.example.com:80"));
323 value->Append(new base::StringValue("udp-bind::8080"));
324 value->Append(new base::StringValue("udp-send-to::8888"));
325 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
328 // Union with an empty set.
329 apis1.insert(APIPermission::kTab);
330 apis1.insert(APIPermission::kBackground);
331 apis1.insert(permission->Clone());
332 expected_apis.insert(APIPermission::kTab);
333 expected_apis.insert(APIPermission::kBackground);
334 expected_apis.insert(permission);
336 AddPattern(&explicit_hosts1, "http://*.google.com/*");
337 AddPattern(&expected_explicit_hosts, "http://*.google.com/*");
338 AddPattern(&effective_hosts, "http://*.google.com/*");
340 set1 = new PermissionSet(apis1, manifest_permissions,
341 explicit_hosts1, scriptable_hosts1);
342 set2 = new PermissionSet(apis2, manifest_permissions,
343 explicit_hosts2, scriptable_hosts2);
344 union_set = PermissionSet::CreateUnion(set1.get(), set2.get());
345 EXPECT_TRUE(set1->Contains(*set2.get()));
346 EXPECT_TRUE(set1->Contains(*union_set.get()));
347 EXPECT_FALSE(set2->Contains(*set1.get()));
348 EXPECT_FALSE(set2->Contains(*union_set.get()));
349 EXPECT_TRUE(union_set->Contains(*set1.get()));
350 EXPECT_TRUE(union_set->Contains(*set2.get()));
352 EXPECT_FALSE(union_set->HasEffectiveFullAccess());
353 EXPECT_EQ(expected_apis, union_set->apis());
354 EXPECT_EQ(expected_explicit_hosts, union_set->explicit_hosts());
355 EXPECT_EQ(expected_scriptable_hosts, union_set->scriptable_hosts());
356 EXPECT_EQ(expected_explicit_hosts, union_set->effective_hosts());
358 // Now use a real second set.
359 apis2.insert(APIPermission::kTab);
360 apis2.insert(APIPermission::kProxy);
361 apis2.insert(APIPermission::kClipboardWrite);
362 apis2.insert(APIPermission::kPlugin);
364 permission = permission_info->CreateAPIPermission();
366 scoped_ptr<base::ListValue> value(new base::ListValue());
367 value->Append(new base::StringValue("tcp-connect:*.example.com:80"));
368 value->Append(new base::StringValue("udp-send-to::8899"));
369 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
371 apis2.insert(permission);
373 expected_apis.insert(APIPermission::kTab);
374 expected_apis.insert(APIPermission::kProxy);
375 expected_apis.insert(APIPermission::kClipboardWrite);
376 expected_apis.insert(APIPermission::kPlugin);
378 permission = permission_info->CreateAPIPermission();
380 scoped_ptr<base::ListValue> value(new base::ListValue());
381 value->Append(new base::StringValue("tcp-connect:*.example.com:80"));
382 value->Append(new base::StringValue("udp-bind::8080"));
383 value->Append(new base::StringValue("udp-send-to::8888"));
384 value->Append(new base::StringValue("udp-send-to::8899"));
385 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
387 // Insert a new permission socket permisssion which will replace the old one.
388 expected_apis.insert(permission);
390 AddPattern(&explicit_hosts2, "http://*.example.com/*");
391 AddPattern(&scriptable_hosts2, "http://*.google.com/*");
392 AddPattern(&expected_explicit_hosts, "http://*.example.com/*");
393 AddPattern(&expected_scriptable_hosts, "http://*.google.com/*");
395 URLPatternSet::CreateUnion(
396 explicit_hosts2, scriptable_hosts2, &effective_hosts);
398 set2 = new PermissionSet(apis2, manifest_permissions,
399 explicit_hosts2, scriptable_hosts2);
400 union_set = PermissionSet::CreateUnion(set1.get(), set2.get());
402 EXPECT_FALSE(set1->Contains(*set2.get()));
403 EXPECT_FALSE(set1->Contains(*union_set.get()));
404 EXPECT_FALSE(set2->Contains(*set1.get()));
405 EXPECT_FALSE(set2->Contains(*union_set.get()));
406 EXPECT_TRUE(union_set->Contains(*set1.get()));
407 EXPECT_TRUE(union_set->Contains(*set2.get()));
409 EXPECT_TRUE(union_set->HasEffectiveFullAccess());
410 EXPECT_TRUE(union_set->HasEffectiveAccessToAllHosts());
411 EXPECT_EQ(expected_apis, union_set->apis());
412 EXPECT_EQ(expected_explicit_hosts, union_set->explicit_hosts());
413 EXPECT_EQ(expected_scriptable_hosts, union_set->scriptable_hosts());
414 EXPECT_EQ(effective_hosts, union_set->effective_hosts());
417 TEST(PermissionsTest, CreateIntersection) {
418 APIPermission* permission = NULL;
420 ManifestPermissionSet manifest_permissions;
421 APIPermissionSet apis1;
422 APIPermissionSet apis2;
423 APIPermissionSet expected_apis;
425 URLPatternSet explicit_hosts1;
426 URLPatternSet explicit_hosts2;
427 URLPatternSet expected_explicit_hosts;
429 URLPatternSet scriptable_hosts1;
430 URLPatternSet scriptable_hosts2;
431 URLPatternSet expected_scriptable_hosts;
433 URLPatternSet effective_hosts;
435 scoped_refptr<PermissionSet> set1;
436 scoped_refptr<PermissionSet> set2;
437 scoped_refptr<PermissionSet> new_set;
439 const APIPermissionInfo* permission_info =
440 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket);
442 // Intersection with an empty set.
443 apis1.insert(APIPermission::kTab);
444 apis1.insert(APIPermission::kBackground);
445 permission = permission_info->CreateAPIPermission();
447 scoped_ptr<base::ListValue> value(new base::ListValue());
448 value->Append(new base::StringValue("tcp-connect:*.example.com:80"));
449 value->Append(new base::StringValue("udp-bind::8080"));
450 value->Append(new base::StringValue("udp-send-to::8888"));
451 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
453 apis1.insert(permission);
455 AddPattern(&explicit_hosts1, "http://*.google.com/*");
456 AddPattern(&scriptable_hosts1, "http://www.reddit.com/*");
458 set1 = new PermissionSet(apis1, manifest_permissions,
459 explicit_hosts1, scriptable_hosts1);
460 set2 = new PermissionSet(apis2, manifest_permissions,
461 explicit_hosts2, scriptable_hosts2);
462 new_set = PermissionSet::CreateIntersection(set1.get(), set2.get());
463 EXPECT_TRUE(set1->Contains(*new_set.get()));
464 EXPECT_TRUE(set2->Contains(*new_set.get()));
465 EXPECT_TRUE(set1->Contains(*set2.get()));
466 EXPECT_FALSE(set2->Contains(*set1.get()));
467 EXPECT_FALSE(new_set->Contains(*set1.get()));
468 EXPECT_TRUE(new_set->Contains(*set2.get()));
470 EXPECT_TRUE(new_set->IsEmpty());
471 EXPECT_FALSE(new_set->HasEffectiveFullAccess());
472 EXPECT_EQ(expected_apis, new_set->apis());
473 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts());
474 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts());
475 EXPECT_EQ(expected_explicit_hosts, new_set->effective_hosts());
477 // Now use a real second set.
478 apis2.insert(APIPermission::kTab);
479 apis2.insert(APIPermission::kProxy);
480 apis2.insert(APIPermission::kClipboardWrite);
481 apis2.insert(APIPermission::kPlugin);
482 permission = permission_info->CreateAPIPermission();
484 scoped_ptr<base::ListValue> value(new base::ListValue());
485 value->Append(new base::StringValue("udp-bind::8080"));
486 value->Append(new base::StringValue("udp-send-to::8888"));
487 value->Append(new base::StringValue("udp-send-to::8899"));
488 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
490 apis2.insert(permission);
492 expected_apis.insert(APIPermission::kTab);
493 permission = permission_info->CreateAPIPermission();
495 scoped_ptr<base::ListValue> value(new base::ListValue());
496 value->Append(new base::StringValue("udp-bind::8080"));
497 value->Append(new base::StringValue("udp-send-to::8888"));
498 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
500 expected_apis.insert(permission);
502 AddPattern(&explicit_hosts2, "http://*.example.com/*");
503 AddPattern(&explicit_hosts2, "http://*.google.com/*");
504 AddPattern(&scriptable_hosts2, "http://*.google.com/*");
505 AddPattern(&expected_explicit_hosts, "http://*.google.com/*");
507 effective_hosts.ClearPatterns();
508 AddPattern(&effective_hosts, "http://*.google.com/*");
510 set2 = new PermissionSet(apis2, manifest_permissions,
511 explicit_hosts2, scriptable_hosts2);
512 new_set = PermissionSet::CreateIntersection(set1.get(), set2.get());
514 EXPECT_TRUE(set1->Contains(*new_set.get()));
515 EXPECT_TRUE(set2->Contains(*new_set.get()));
516 EXPECT_FALSE(set1->Contains(*set2.get()));
517 EXPECT_FALSE(set2->Contains(*set1.get()));
518 EXPECT_FALSE(new_set->Contains(*set1.get()));
519 EXPECT_FALSE(new_set->Contains(*set2.get()));
521 EXPECT_FALSE(new_set->HasEffectiveFullAccess());
522 EXPECT_FALSE(new_set->HasEffectiveAccessToAllHosts());
523 EXPECT_EQ(expected_apis, new_set->apis());
524 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts());
525 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts());
526 EXPECT_EQ(effective_hosts, new_set->effective_hosts());
529 TEST(PermissionsTest, CreateDifference) {
530 APIPermission* permission = NULL;
532 ManifestPermissionSet manifest_permissions;
533 APIPermissionSet apis1;
534 APIPermissionSet apis2;
535 APIPermissionSet expected_apis;
537 URLPatternSet explicit_hosts1;
538 URLPatternSet explicit_hosts2;
539 URLPatternSet expected_explicit_hosts;
541 URLPatternSet scriptable_hosts1;
542 URLPatternSet scriptable_hosts2;
543 URLPatternSet expected_scriptable_hosts;
545 URLPatternSet effective_hosts;
547 scoped_refptr<PermissionSet> set1;
548 scoped_refptr<PermissionSet> set2;
549 scoped_refptr<PermissionSet> new_set;
551 const APIPermissionInfo* permission_info =
552 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket);
554 // Difference with an empty set.
555 apis1.insert(APIPermission::kTab);
556 apis1.insert(APIPermission::kBackground);
557 permission = permission_info->CreateAPIPermission();
559 scoped_ptr<base::ListValue> value(new base::ListValue());
560 value->Append(new base::StringValue("tcp-connect:*.example.com:80"));
561 value->Append(new base::StringValue("udp-bind::8080"));
562 value->Append(new base::StringValue("udp-send-to::8888"));
563 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
565 apis1.insert(permission);
567 AddPattern(&explicit_hosts1, "http://*.google.com/*");
568 AddPattern(&scriptable_hosts1, "http://www.reddit.com/*");
570 set1 = new PermissionSet(apis1, manifest_permissions,
571 explicit_hosts1, scriptable_hosts1);
572 set2 = new PermissionSet(apis2, manifest_permissions,
573 explicit_hosts2, scriptable_hosts2);
574 new_set = PermissionSet::CreateDifference(set1.get(), set2.get());
575 EXPECT_EQ(*set1.get(), *new_set.get());
577 // Now use a real second set.
578 apis2.insert(APIPermission::kTab);
579 apis2.insert(APIPermission::kProxy);
580 apis2.insert(APIPermission::kClipboardWrite);
581 apis2.insert(APIPermission::kPlugin);
582 permission = permission_info->CreateAPIPermission();
584 scoped_ptr<base::ListValue> value(new base::ListValue());
585 value->Append(new base::StringValue("tcp-connect:*.example.com:80"));
586 value->Append(new base::StringValue("udp-send-to::8899"));
587 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
589 apis2.insert(permission);
591 expected_apis.insert(APIPermission::kBackground);
592 permission = permission_info->CreateAPIPermission();
594 scoped_ptr<base::ListValue> value(new base::ListValue());
595 value->Append(new base::StringValue("udp-bind::8080"));
596 value->Append(new base::StringValue("udp-send-to::8888"));
597 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
599 expected_apis.insert(permission);
601 AddPattern(&explicit_hosts2, "http://*.example.com/*");
602 AddPattern(&explicit_hosts2, "http://*.google.com/*");
603 AddPattern(&scriptable_hosts2, "http://*.google.com/*");
604 AddPattern(&expected_scriptable_hosts, "http://www.reddit.com/*");
606 effective_hosts.ClearPatterns();
607 AddPattern(&effective_hosts, "http://www.reddit.com/*");
609 set2 = new PermissionSet(apis2, manifest_permissions,
610 explicit_hosts2, scriptable_hosts2);
611 new_set = PermissionSet::CreateDifference(set1.get(), set2.get());
613 EXPECT_TRUE(set1->Contains(*new_set.get()));
614 EXPECT_FALSE(set2->Contains(*new_set.get()));
616 EXPECT_FALSE(new_set->HasEffectiveFullAccess());
617 EXPECT_FALSE(new_set->HasEffectiveAccessToAllHosts());
618 EXPECT_EQ(expected_apis, new_set->apis());
619 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts());
620 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts());
621 EXPECT_EQ(effective_hosts, new_set->effective_hosts());
623 // |set3| = |set1| - |set2| --> |set3| intersect |set2| == empty_set
624 set1 = PermissionSet::CreateIntersection(new_set.get(), set2.get());
625 EXPECT_TRUE(set1->IsEmpty());
628 TEST(PermissionsTest, IsPrivilegeIncrease) {
629 const struct {
630 const char* base_name;
631 bool expect_increase;
632 } kTests[] = {
633 { "allhosts1", false }, // all -> all
634 { "allhosts2", false }, // all -> one
635 { "allhosts3", true }, // one -> all
636 { "hosts1", false }, // http://a,http://b -> http://a,http://b
637 { "hosts2", true }, // http://a,http://b -> https://a,http://*.b
638 { "hosts3", false }, // http://a,http://b -> http://a
639 { "hosts4", true }, // http://a -> http://a,http://b
640 { "hosts5", false }, // http://a,b,c -> http://a,b,c + https://a,b,c
641 { "hosts6", false }, // http://a.com -> http://a.com + http://a.co.uk
642 { "permissions1", false }, // tabs -> tabs
643 { "permissions2", true }, // tabs -> tabs,bookmarks
644 // TODO(treib): This is wrong, kAllHosts implies kTabs. crbug.com/512344
645 { "permissions3", true }, // http://*/* -> http://*/*,tabs
646 { "permissions5", true }, // bookmarks -> bookmarks,history
647 { "equivalent_warnings", false }, // tabs --> tabs, webNavigation
648 #if !defined(OS_CHROMEOS) // plugins aren't allowed in ChromeOS
649 { "permissions4", false }, // plugin -> plugin,tabs
650 { "plugin1", false }, // plugin -> plugin
651 { "plugin2", false }, // plugin -> none
652 { "plugin3", true }, // none -> plugin
653 #endif
654 { "storage", false }, // none -> storage
655 { "notifications", false }, // none -> notifications
656 { "platformapp1", false }, // host permissions for platform apps
657 { "platformapp2", true }, // API permissions for platform apps
658 { "media_galleries1", true }, // all -> read|all
659 { "media_galleries2", true }, // read|all -> read|delete|copyTo|all
660 { "media_galleries3", true }, // all -> read|delete|all
661 { "media_galleries4", false }, // read|all -> all
662 { "media_galleries5", false }, // read|copyTo|delete|all -> read|all
663 { "media_galleries6", false }, // read|all -> read|all
664 { "media_galleries7", true }, // read|delete|all -> read|copyTo|delete|all
665 { "sockets1", true }, // none -> tcp:*:*
666 { "sockets2", false }, // tcp:*:* -> tcp:*:*
667 { "sockets3", true }, // tcp:a.com:80 -> tcp:*:*
670 for (size_t i = 0; i < arraysize(kTests); ++i) {
671 scoped_refptr<Extension> old_extension(
672 LoadManifest("allow_silent_upgrade",
673 std::string(kTests[i].base_name) + "_old.json"));
674 scoped_refptr<Extension> new_extension(
675 LoadManifest("allow_silent_upgrade",
676 std::string(kTests[i].base_name) + "_new.json"));
678 EXPECT_TRUE(new_extension.get()) << kTests[i].base_name << "_new.json";
679 if (!new_extension.get())
680 continue;
682 scoped_refptr<const PermissionSet> old_p(
683 old_extension->permissions_data()->active_permissions());
684 scoped_refptr<const PermissionSet> new_p(
685 new_extension->permissions_data()->active_permissions());
686 Manifest::Type extension_type = old_extension->GetType();
688 bool increased = PermissionMessageProvider::Get()->IsPrivilegeIncrease(
689 old_p.get(), new_p.get(), extension_type);
690 EXPECT_EQ(kTests[i].expect_increase, increased) << kTests[i].base_name;
694 TEST(PermissionsTest, PermissionMessages) {
695 // Ensure that all permissions that needs to show install UI actually have
696 // strings associated with them.
697 APIPermissionSet skip;
699 // These are considered "nuisance" or "trivial" permissions that don't need
700 // a prompt.
701 skip.insert(APIPermission::kActiveTab);
702 skip.insert(APIPermission::kAlarms);
703 skip.insert(APIPermission::kAlphaEnabled);
704 skip.insert(APIPermission::kAlwaysOnTopWindows);
705 skip.insert(APIPermission::kAppView);
706 skip.insert(APIPermission::kAudio);
707 skip.insert(APIPermission::kAudioModem);
708 skip.insert(APIPermission::kBrowsingData);
709 skip.insert(APIPermission::kCastStreaming);
710 skip.insert(APIPermission::kCommandsAccessibility);
711 skip.insert(APIPermission::kContextMenus);
712 skip.insert(APIPermission::kCryptotokenPrivate);
713 skip.insert(APIPermission::kCopresencePrivate);
714 skip.insert(APIPermission::kDesktopCapturePrivate);
715 skip.insert(APIPermission::kDiagnostics);
716 skip.insert(APIPermission::kDns);
717 skip.insert(APIPermission::kDownloadsShelf);
718 skip.insert(APIPermission::kEmbeddedExtensionOptions);
719 skip.insert(APIPermission::kExtensionView);
720 skip.insert(APIPermission::kFontSettings);
721 skip.insert(APIPermission::kFullscreen);
722 skip.insert(APIPermission::kGcm);
723 skip.insert(APIPermission::kIdle);
724 skip.insert(APIPermission::kImeWindowEnabled);
725 skip.insert(APIPermission::kInlineInstallPrivate);
726 skip.insert(APIPermission::kIdltest);
727 skip.insert(APIPermission::kLogPrivate);
728 skip.insert(APIPermission::kNotifications);
729 skip.insert(APIPermission::kNotificationProvider);
730 skip.insert(APIPermission::kOverrideEscFullscreen);
731 skip.insert(APIPermission::kPointerLock);
732 skip.insert(APIPermission::kPower);
733 skip.insert(APIPermission::kPrinterProvider);
734 skip.insert(APIPermission::kSessions);
735 skip.insert(APIPermission::kStorage);
736 skip.insert(APIPermission::kSystemCpu);
737 skip.insert(APIPermission::kSystemDisplay);
738 skip.insert(APIPermission::kSystemMemory);
739 skip.insert(APIPermission::kSystemNetwork);
740 skip.insert(APIPermission::kSystemStorage);
741 skip.insert(APIPermission::kTts);
742 skip.insert(APIPermission::kUnlimitedStorage);
743 skip.insert(APIPermission::kWebcamPrivate);
744 skip.insert(APIPermission::kWebView);
745 skip.insert(APIPermission::kWindowShape);
747 // These permissions are restricted to extensions force-installed by policy
748 // and don't require a prompt, i.e. they're restricted to location 'policy'.
749 skip.insert(APIPermission::kEnterprisePlatformKeys);
751 // TODO(erikkay) add a string for this permission.
752 skip.insert(APIPermission::kBackground);
754 skip.insert(APIPermission::kClipboardWrite);
756 // The cookie permission does nothing unless you have associated host
757 // permissions.
758 skip.insert(APIPermission::kCookie);
760 // These are warned as part of host permission checks.
761 skip.insert(APIPermission::kDataReductionProxy);
762 skip.insert(APIPermission::kDeclarativeContent);
763 skip.insert(APIPermission::kPageCapture);
764 skip.insert(APIPermission::kProxy);
765 skip.insert(APIPermission::kTabCapture);
766 skip.insert(APIPermission::kWebRequest);
767 skip.insert(APIPermission::kWebRequestBlocking);
769 // This permission requires explicit user action (context menu handler)
770 // so we won't prompt for it for now.
771 skip.insert(APIPermission::kFileBrowserHandler);
773 // These permissions require explicit user action (configuration dialog)
774 // so we don't prompt for them at install time.
775 skip.insert(APIPermission::kMediaGalleries);
777 // If you've turned on the experimental command-line flag, we don't need
778 // to warn you further.
779 skip.insert(APIPermission::kExperimental);
781 // The Identity API has its own server-driven permission prompts.
782 skip.insert(APIPermission::kIdentity);
784 // These are private.
785 skip.insert(APIPermission::kAccessibilityPrivate);
786 skip.insert(APIPermission::kAutoTestPrivate);
787 skip.insert(APIPermission::kBookmarkManagerPrivate);
788 skip.insert(APIPermission::kBrailleDisplayPrivate);
789 skip.insert(APIPermission::kCast);
790 skip.insert(APIPermission::kCastStreaming);
791 skip.insert(APIPermission::kChromeosInfoPrivate);
792 skip.insert(APIPermission::kCloudPrintPrivate);
793 skip.insert(APIPermission::kCommandLinePrivate);
794 skip.insert(APIPermission::kDeveloperPrivate);
795 skip.insert(APIPermission::kDial);
796 skip.insert(APIPermission::kDownloadsInternal);
797 skip.insert(APIPermission::kEasyUnlockPrivate);
798 skip.insert(APIPermission::kEchoPrivate);
799 skip.insert(APIPermission::kEnterprisePlatformKeysPrivate);
800 skip.insert(APIPermission::kFeedbackPrivate);
801 skip.insert(APIPermission::kFileBrowserHandlerInternal);
802 skip.insert(APIPermission::kFileManagerPrivate);
803 skip.insert(APIPermission::kFirstRunPrivate);
804 skip.insert(APIPermission::kGcdPrivate);
805 skip.insert(APIPermission::kHotwordPrivate);
806 skip.insert(APIPermission::kIdentityPrivate);
807 skip.insert(APIPermission::kInputMethodPrivate);
808 skip.insert(APIPermission::kLanguageSettingsPrivate);
809 skip.insert(APIPermission::kMediaPlayerPrivate);
810 skip.insert(APIPermission::kMediaRouterPrivate);
811 skip.insert(APIPermission::kMetricsPrivate);
812 skip.insert(APIPermission::kPreferencesPrivate);
813 skip.insert(APIPermission::kPrincipalsPrivate);
814 skip.insert(APIPermission::kImageWriterPrivate);
815 skip.insert(APIPermission::kReadingListPrivate);
816 skip.insert(APIPermission::kRtcPrivate);
817 skip.insert(APIPermission::kStreamsPrivate);
818 skip.insert(APIPermission::kSystemPrivate);
819 skip.insert(APIPermission::kTabCaptureForTab);
820 skip.insert(APIPermission::kTerminalPrivate);
821 skip.insert(APIPermission::kVirtualKeyboardPrivate);
822 skip.insert(APIPermission::kWallpaperPrivate);
823 skip.insert(APIPermission::kWebrtcAudioPrivate);
824 skip.insert(APIPermission::kWebrtcDesktopCapturePrivate);
825 skip.insert(APIPermission::kWebrtcLoggingPrivate);
826 skip.insert(APIPermission::kWebstorePrivate);
827 skip.insert(APIPermission::kWebstoreWidgetPrivate);
829 // Warned as part of host permissions.
830 skip.insert(APIPermission::kDevtools);
832 // Platform apps.
833 skip.insert(APIPermission::kBrowser);
834 skip.insert(APIPermission::kHid);
835 skip.insert(APIPermission::kFileSystem);
836 skip.insert(APIPermission::kFileSystemProvider);
837 skip.insert(APIPermission::kFileSystemRequestFileSystem);
838 skip.insert(APIPermission::kFileSystemRetainEntries);
839 skip.insert(APIPermission::kFileSystemWrite);
840 skip.insert(APIPermission::kSocket);
841 skip.insert(APIPermission::kUsb);
842 skip.insert(APIPermission::kUsbDevice);
843 skip.insert(APIPermission::kLauncherSearchProvider);
845 // We already have a generic message for declaring externally_connectable.
846 skip.insert(APIPermission::kExternallyConnectableAllUrls);
848 PermissionsInfo* info = PermissionsInfo::GetInstance();
849 APIPermissionSet permissions = info->GetAll();
850 for (APIPermissionSet::const_iterator i = permissions.begin();
851 i != permissions.end(); ++i) {
852 const APIPermissionInfo* permission_info = i->info();
853 EXPECT_TRUE(permission_info != NULL);
855 if (skip.count(i->id())) {
856 EXPECT_EQ(PermissionMessage::kNone, permission_info->message_id())
857 << "unexpected message_id for " << permission_info->name();
858 } else {
859 EXPECT_NE(PermissionMessage::kNone, permission_info->message_id())
860 << "missing message_id for " << permission_info->name();
865 TEST(PermissionsTest, FileSystemPermissionMessages) {
866 APIPermissionSet api_permissions;
867 api_permissions.insert(APIPermission::kFileSystemWrite);
868 api_permissions.insert(APIPermission::kFileSystemDirectory);
869 scoped_refptr<PermissionSet> permissions(
870 new PermissionSet(api_permissions, ManifestPermissionSet(),
871 URLPatternSet(), URLPatternSet()));
872 EXPECT_TRUE(PermissionSetProducesMessage(
873 permissions.get(), Manifest::TYPE_PLATFORM_APP,
874 MakePermissionIDSet(api_permissions)));
877 // The file system permissions have a special-case hack to show a warning for
878 // write and directory at the same time.
879 // TODO(sammc): Remove this. See http://crbug.com/284849.
880 TEST(PermissionsTest, FileSystemImplicitPermissions) {
881 APIPermissionSet apis;
882 apis.insert(APIPermission::kFileSystemWrite);
883 apis.AddImpliedPermissions();
885 EXPECT_EQ(apis.find(APIPermission::kFileSystemWrite)->id(),
886 APIPermission::kFileSystemWrite);
887 EXPECT_EQ(apis.size(), 1u);
889 apis.erase(APIPermission::kFileSystemWrite);
890 apis.insert(APIPermission::kFileSystemDirectory);
891 apis.AddImpliedPermissions();
893 EXPECT_EQ(apis.find(APIPermission::kFileSystemDirectory)->id(),
894 APIPermission::kFileSystemDirectory);
895 EXPECT_EQ(apis.size(), 1u);
897 apis.insert(APIPermission::kFileSystemWrite);
898 apis.AddImpliedPermissions();
900 EXPECT_EQ(apis.find(APIPermission::kFileSystemWrite)->id(),
901 APIPermission::kFileSystemWrite);
902 EXPECT_EQ(apis.find(APIPermission::kFileSystemDirectory)->id(),
903 APIPermission::kFileSystemDirectory);
904 EXPECT_EQ(apis.find(APIPermission::kFileSystemWriteDirectory)->id(),
905 APIPermission::kFileSystemWriteDirectory);
906 EXPECT_EQ(apis.size(), 3u);
909 TEST(PermissionsTest, HiddenFileSystemPermissionMessages) {
910 APIPermissionSet api_permissions;
911 api_permissions.insert(APIPermission::kFileSystemWrite);
912 api_permissions.insert(APIPermission::kFileSystemDirectory);
913 api_permissions.insert(APIPermission::kFileSystemWriteDirectory);
914 scoped_refptr<PermissionSet> permissions(
915 new PermissionSet(api_permissions, ManifestPermissionSet(),
916 URLPatternSet(), URLPatternSet()));
917 EXPECT_TRUE(PermissionSetProducesMessage(
918 permissions.get(), Manifest::TYPE_PLATFORM_APP,
919 MakePermissionIDSet(api_permissions)));
922 TEST(PermissionsTest, SuppressedPermissionMessages) {
924 // Tabs warning suppresses favicon warning.
925 APIPermissionSet api_permissions;
926 api_permissions.insert(APIPermission::kTab);
927 URLPatternSet hosts;
928 hosts.AddPattern(URLPattern(URLPattern::SCHEME_CHROMEUI,
929 "chrome://favicon/"));
930 scoped_refptr<PermissionSet> permissions(
931 new PermissionSet(api_permissions, ManifestPermissionSet(),
932 hosts, URLPatternSet()));
933 EXPECT_TRUE(PermissionSetProducesMessage(
934 permissions.get(), Manifest::TYPE_EXTENSION,
935 MakePermissionIDSet(APIPermission::kTab, APIPermission::kFavicon)));
938 // History warning suppresses favicon warning.
939 APIPermissionSet api_permissions;
940 api_permissions.insert(APIPermission::kHistory);
941 URLPatternSet hosts;
942 hosts.AddPattern(URLPattern(URLPattern::SCHEME_CHROMEUI,
943 "chrome://favicon/"));
944 scoped_refptr<PermissionSet> permissions(
945 new PermissionSet(api_permissions, ManifestPermissionSet(),
946 hosts, URLPatternSet()));
947 EXPECT_TRUE(PermissionSetProducesMessage(
948 permissions.get(), Manifest::TYPE_EXTENSION,
949 MakePermissionIDSet(APIPermission::kHistory, APIPermission::kFavicon)));
952 // All sites warning suppresses tabs warning.
953 APIPermissionSet api_permissions;
954 api_permissions.insert(APIPermission::kTab);
955 URLPatternSet hosts;
956 hosts.AddPattern(URLPattern(URLPattern::SCHEME_CHROMEUI, "*://*/*"));
957 scoped_refptr<PermissionSet> permissions(new PermissionSet(
958 api_permissions, ManifestPermissionSet(), hosts, URLPatternSet()));
959 EXPECT_TRUE(PermissionSetProducesMessage(
960 permissions.get(), Manifest::TYPE_EXTENSION,
961 MakePermissionIDSet(APIPermission::kHostsAll, APIPermission::kTab)));
964 // All sites warning suppresses topSites warning.
965 APIPermissionSet api_permissions;
966 api_permissions.insert(APIPermission::kTopSites);
967 URLPatternSet hosts;
968 hosts.AddPattern(URLPattern(URLPattern::SCHEME_CHROMEUI, "*://*/*"));
969 scoped_refptr<PermissionSet> permissions(new PermissionSet(
970 api_permissions, ManifestPermissionSet(), hosts, URLPatternSet()));
971 EXPECT_TRUE(PermissionSetProducesMessage(
972 permissions.get(), Manifest::TYPE_EXTENSION,
973 MakePermissionIDSet(APIPermission::kHostsAll,
974 APIPermission::kTopSites)));
977 // All sites warning suppresses declarativeWebRequest warning.
978 APIPermissionSet api_permissions;
979 api_permissions.insert(APIPermission::kDeclarativeWebRequest);
980 URLPatternSet hosts;
981 hosts.AddPattern(URLPattern(URLPattern::SCHEME_CHROMEUI, "*://*/*"));
982 scoped_refptr<PermissionSet> permissions(new PermissionSet(
983 api_permissions, ManifestPermissionSet(), hosts, URLPatternSet()));
984 EXPECT_TRUE(PermissionSetProducesMessage(
985 permissions.get(), Manifest::TYPE_EXTENSION,
986 MakePermissionIDSet(APIPermission::kHostsAll)));
989 // BrowsingHistory warning suppresses all history read/write warnings.
990 APIPermissionSet api_permissions;
991 api_permissions.insert(APIPermission::kHistory);
992 api_permissions.insert(APIPermission::kTab);
993 api_permissions.insert(APIPermission::kTopSites);
994 api_permissions.insert(APIPermission::kProcesses);
995 api_permissions.insert(APIPermission::kWebNavigation);
996 scoped_refptr<PermissionSet> permissions(
997 new PermissionSet(api_permissions, ManifestPermissionSet(),
998 URLPatternSet(), URLPatternSet()));
999 EXPECT_TRUE(PermissionSetProducesMessage(
1000 permissions.get(), Manifest::TYPE_EXTENSION,
1001 MakePermissionIDSet(api_permissions)));
1004 // Tabs warning suppresses all read-only history warnings.
1005 APIPermissionSet api_permissions;
1006 api_permissions.insert(APIPermission::kTab);
1007 api_permissions.insert(APIPermission::kTopSites);
1008 api_permissions.insert(APIPermission::kProcesses);
1009 api_permissions.insert(APIPermission::kWebNavigation);
1010 scoped_refptr<PermissionSet> permissions(
1011 new PermissionSet(api_permissions, ManifestPermissionSet(),
1012 URLPatternSet(), URLPatternSet()));
1013 EXPECT_TRUE(PermissionSetProducesMessage(
1014 permissions.get(), Manifest::TYPE_EXTENSION,
1015 MakePermissionIDSet(api_permissions)));
1019 TEST(PermissionsTest, AccessToDevicesMessages) {
1021 APIPermissionSet api_permissions;
1022 api_permissions.insert(APIPermission::kSerial);
1023 scoped_refptr<PermissionSet> permissions(
1024 new PermissionSet(api_permissions,
1025 ManifestPermissionSet(),
1026 URLPatternSet(),
1027 URLPatternSet()));
1028 VerifyOnePermissionMessage(
1029 permissions.get(), Manifest::TYPE_EXTENSION,
1030 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_SERIAL));
1033 // Testing that multiple permissions will show the one message.
1034 APIPermissionSet api_permissions;
1035 api_permissions.insert(APIPermission::kSerial);
1036 api_permissions.insert(APIPermission::kSerial);
1037 scoped_refptr<PermissionSet> permissions(
1038 new PermissionSet(api_permissions,
1039 ManifestPermissionSet(),
1040 URLPatternSet(),
1041 URLPatternSet()));
1042 VerifyOnePermissionMessage(
1043 permissions.get(), Manifest::TYPE_EXTENSION,
1044 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_SERIAL));
1047 scoped_refptr<Extension> extension =
1048 LoadManifest("permissions", "access_to_devices_bluetooth.json");
1049 PermissionSet* set = const_cast<PermissionSet*>(
1050 extension->permissions_data()->active_permissions().get());
1051 VerifyOnePermissionMessage(
1052 set, extension->GetType(),
1053 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_BLUETOOTH));
1055 // Test Bluetooth and Serial
1056 set->apis_.insert(APIPermission::kSerial);
1057 VerifyOnePermissionMessage(
1058 set, extension->GetType(),
1059 l10n_util::GetStringUTF16(
1060 IDS_EXTENSION_PROMPT_WARNING_BLUETOOTH_SERIAL));
1064 TEST(PermissionsTest, MergedFileSystemPermissionComparison) {
1065 APIPermissionSet write_api_permissions;
1066 write_api_permissions.insert(APIPermission::kFileSystemWrite);
1067 scoped_refptr<PermissionSet> write_permissions(
1068 new PermissionSet(write_api_permissions, ManifestPermissionSet(),
1069 URLPatternSet(), URLPatternSet()));
1071 APIPermissionSet directory_api_permissions;
1072 directory_api_permissions.insert(APIPermission::kFileSystemDirectory);
1073 scoped_refptr<PermissionSet> directory_permissions(
1074 new PermissionSet(directory_api_permissions, ManifestPermissionSet(),
1075 URLPatternSet(), URLPatternSet()));
1077 APIPermissionSet write_directory_api_permissions;
1078 write_directory_api_permissions.insert(
1079 APIPermission::kFileSystemWriteDirectory);
1080 scoped_refptr<PermissionSet> write_directory_permissions(
1081 new PermissionSet(write_directory_api_permissions,
1082 ManifestPermissionSet(),
1083 URLPatternSet(),
1084 URLPatternSet()));
1086 const PermissionMessageProvider* provider = PermissionMessageProvider::Get();
1087 EXPECT_FALSE(provider->IsPrivilegeIncrease(write_directory_permissions.get(),
1088 write_permissions.get(),
1089 Manifest::TYPE_PLATFORM_APP));
1090 EXPECT_FALSE(provider->IsPrivilegeIncrease(write_directory_permissions.get(),
1091 directory_permissions.get(),
1092 Manifest::TYPE_PLATFORM_APP));
1093 EXPECT_TRUE(provider->IsPrivilegeIncrease(write_permissions.get(),
1094 directory_permissions.get(),
1095 Manifest::TYPE_PLATFORM_APP));
1096 EXPECT_TRUE(provider->IsPrivilegeIncrease(write_permissions.get(),
1097 write_directory_permissions.get(),
1098 Manifest::TYPE_PLATFORM_APP));
1099 EXPECT_FALSE(provider->IsPrivilegeIncrease(directory_permissions.get(),
1100 write_permissions.get(),
1101 Manifest::TYPE_PLATFORM_APP));
1102 EXPECT_TRUE(provider->IsPrivilegeIncrease(directory_permissions.get(),
1103 write_directory_permissions.get(),
1104 Manifest::TYPE_PLATFORM_APP));
1107 TEST(PermissionsTest, GetWarningMessages_ManyHosts) {
1108 scoped_refptr<Extension> extension;
1109 extension = LoadManifest("permissions", "many-hosts.json");
1110 EXPECT_TRUE(VerifyOnePermissionMessage(
1111 extension->permissions_data(),
1112 "Read and change your data on encrypted.google.com and www.google.com"));
1115 TEST(PermissionsTest, GetWarningMessages_Plugins) {
1116 scoped_refptr<Extension> extension;
1117 extension = LoadManifest("permissions", "plugins.json");
1118 // We don't parse the plugins key on Chrome OS, so it should not ask for any
1119 // permissions.
1120 #if defined(OS_CHROMEOS)
1121 EXPECT_TRUE(VerifyNoPermissionMessages(extension->permissions_data()));
1122 #else
1123 EXPECT_TRUE(VerifyOnePermissionMessage(
1124 extension->permissions_data(),
1125 "Read and change all your data on your computer and the websites you "
1126 "visit"));
1127 #endif
1130 TEST(PermissionsTest, GetWarningMessages_AudioVideo) {
1131 const std::string kAudio("Use your microphone");
1132 const std::string kVideo("Use your camera");
1133 const std::string kBoth("Use your microphone and camera");
1135 // Both audio and video present.
1136 scoped_refptr<Extension> extension =
1137 LoadManifest("permissions", "audio-video.json");
1138 const PermissionMessageProvider* provider = PermissionMessageProvider::Get();
1139 PermissionSet* set = const_cast<PermissionSet*>(
1140 extension->permissions_data()->active_permissions().get());
1141 EXPECT_FALSE(VerifyHasPermissionMessage(set, extension->GetType(), kAudio));
1142 EXPECT_FALSE(VerifyHasPermissionMessage(set, extension->GetType(), kVideo));
1143 EXPECT_TRUE(VerifyHasPermissionMessage(set, extension->GetType(), kBoth));
1144 CoalescedPermissionMessages warnings = provider->GetPermissionMessages(
1145 provider->GetAllPermissionIDs(set, extension->GetType()));
1146 size_t combined_index = IndexOf(warnings, kBoth);
1147 size_t combined_size = warnings.size();
1149 // Just audio present.
1150 set->apis_.erase(APIPermission::kVideoCapture);
1151 EXPECT_TRUE(VerifyHasPermissionMessage(set, extension->GetType(), kAudio));
1152 EXPECT_FALSE(VerifyHasPermissionMessage(set, extension->GetType(), kVideo));
1153 EXPECT_FALSE(VerifyHasPermissionMessage(set, extension->GetType(), kBoth));
1154 CoalescedPermissionMessages warnings2 = provider->GetPermissionMessages(
1155 provider->GetAllPermissionIDs(set, extension->GetType()));
1156 EXPECT_EQ(combined_size, warnings2.size());
1157 EXPECT_EQ(combined_index, IndexOf(warnings2, kAudio));
1159 // Just video present.
1160 set->apis_.erase(APIPermission::kAudioCapture);
1161 set->apis_.insert(APIPermission::kVideoCapture);
1162 EXPECT_FALSE(VerifyHasPermissionMessage(set, extension->GetType(), kAudio));
1163 EXPECT_TRUE(VerifyHasPermissionMessage(set, extension->GetType(), kVideo));
1164 EXPECT_FALSE(VerifyHasPermissionMessage(set, extension->GetType(), kBoth));
1165 CoalescedPermissionMessages warnings3 = provider->GetPermissionMessages(
1166 provider->GetAllPermissionIDs(set, extension->GetType()));
1167 EXPECT_EQ(combined_size, warnings3.size());
1168 EXPECT_EQ(combined_index, IndexOf(warnings3, kVideo));
1171 TEST(PermissionsTest, GetWarningMessages_CombinedSessions) {
1173 APIPermissionSet api_permissions;
1174 api_permissions.insert(APIPermission::kTab);
1175 api_permissions.insert(APIPermission::kTopSites);
1176 api_permissions.insert(APIPermission::kProcesses);
1177 api_permissions.insert(APIPermission::kWebNavigation);
1178 api_permissions.insert(APIPermission::kSessions);
1179 scoped_refptr<PermissionSet> permissions(
1180 new PermissionSet(api_permissions, ManifestPermissionSet(),
1181 URLPatternSet(), URLPatternSet()));
1182 EXPECT_TRUE(VerifyOnePermissionMessage(
1183 permissions.get(), Manifest::TYPE_EXTENSION,
1184 l10n_util::GetStringUTF16(
1185 IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ_AND_SESSIONS)));
1188 APIPermissionSet api_permissions;
1189 api_permissions.insert(APIPermission::kHistory);
1190 api_permissions.insert(APIPermission::kTab);
1191 api_permissions.insert(APIPermission::kTopSites);
1192 api_permissions.insert(APIPermission::kProcesses);
1193 api_permissions.insert(APIPermission::kWebNavigation);
1194 api_permissions.insert(APIPermission::kSessions);
1195 scoped_refptr<PermissionSet> permissions(
1196 new PermissionSet(api_permissions, ManifestPermissionSet(),
1197 URLPatternSet(), URLPatternSet()));
1198 EXPECT_TRUE(VerifyOnePermissionMessage(
1199 permissions.get(), Manifest::TYPE_EXTENSION,
1200 l10n_util::GetStringUTF16(
1201 IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE_AND_SESSIONS)));
1205 TEST(PermissionsTest, GetWarningMessages_DeclarativeWebRequest) {
1206 // Test that if the declarativeWebRequest permission is present
1207 // in combination with all hosts permission, then only the warning
1208 // for host permissions is shown, because that covers the use of
1209 // declarativeWebRequest.
1211 // Until Declarative Web Request is in stable, let's make sure it is enabled
1212 // on the current channel.
1213 ScopedCurrentChannel sc(version_info::Channel::CANARY);
1215 // First verify that declarativeWebRequest produces a message when host
1216 // permissions do not cover all hosts.
1217 scoped_refptr<Extension> extension =
1218 LoadManifest("permissions", "web_request_not_all_host_permissions.json");
1219 const PermissionSet* set =
1220 extension->permissions_data()->active_permissions().get();
1221 EXPECT_TRUE(VerifyHasPermissionMessage(set, extension->GetType(),
1222 "Block parts of web pages"));
1223 EXPECT_FALSE(VerifyHasPermissionMessage(
1224 set, extension->GetType(),
1225 "Read and change all your data on the websites you visit"));
1227 // Now verify that declarativeWebRequest does not produce a message when host
1228 // permissions do cover all hosts.
1229 extension =
1230 LoadManifest("permissions", "web_request_all_host_permissions.json");
1231 set = extension->permissions_data()->active_permissions().get();
1232 EXPECT_FALSE(VerifyHasPermissionMessage(set, extension->GetType(),
1233 "Block parts of web pages"));
1234 EXPECT_TRUE(VerifyHasPermissionMessage(
1235 set, extension->GetType(),
1236 "Read and change all your data on the websites you visit"));
1239 TEST(PermissionsTest, GetWarningMessages_Serial) {
1240 scoped_refptr<Extension> extension =
1241 LoadManifest("permissions", "serial.json");
1243 EXPECT_TRUE(extension->is_platform_app());
1244 EXPECT_TRUE(
1245 extension->permissions_data()->HasAPIPermission(APIPermission::kSerial));
1246 EXPECT_TRUE(VerifyOnePermissionMessage(extension->permissions_data(),
1247 "Access your serial devices"));
1250 TEST(PermissionsTest, GetWarningMessages_Socket_AnyHost) {
1251 ScopedCurrentChannel channel(version_info::Channel::DEV);
1253 scoped_refptr<Extension> extension =
1254 LoadManifest("permissions", "socket_any_host.json");
1255 EXPECT_TRUE(extension->is_platform_app());
1256 EXPECT_TRUE(
1257 extension->permissions_data()->HasAPIPermission(APIPermission::kSocket));
1258 EXPECT_TRUE(VerifyOnePermissionMessage(
1259 extension->permissions_data(),
1260 "Exchange data with any device on the local network or internet"));
1263 TEST(PermissionsTest, GetWarningMessages_Socket_OneDomainTwoHostnames) {
1264 ScopedCurrentChannel channel(version_info::Channel::DEV);
1266 scoped_refptr<Extension> extension =
1267 LoadManifest("permissions", "socket_one_domain_two_hostnames.json");
1268 EXPECT_TRUE(extension->is_platform_app());
1269 EXPECT_TRUE(
1270 extension->permissions_data()->HasAPIPermission(APIPermission::kSocket));
1272 // Verify the warnings, including support for unicode characters, the fact
1273 // that domain host warnings come before specific host warnings, and the fact
1274 // that domains and hostnames are in alphabetical order regardless of the
1275 // order in the manifest file.
1276 EXPECT_TRUE(VerifyTwoPermissionMessages(
1277 extension->permissions_data(),
1278 "Exchange data with any device in the domain example.org",
1279 "Exchange data with the devices named: "
1280 "b\xC3\xA5r.example.com foo.example.com",
1281 // "\xC3\xA5" = UTF-8 for lowercase A with ring above
1282 true));
1285 TEST(PermissionsTest, GetWarningMessages_Socket_TwoDomainsOneHostname) {
1286 ScopedCurrentChannel channel(version_info::Channel::DEV);
1288 scoped_refptr<Extension> extension =
1289 LoadManifest("permissions", "socket_two_domains_one_hostname.json");
1290 EXPECT_TRUE(extension->is_platform_app());
1291 EXPECT_TRUE(
1292 extension->permissions_data()->HasAPIPermission(APIPermission::kSocket));
1294 // Verify the warnings, including the fact that domain host warnings come
1295 // before specific host warnings and the fact that domains and hostnames are
1296 // in alphabetical order regardless of the order in the manifest file.
1297 EXPECT_TRUE(VerifyTwoPermissionMessages(
1298 extension->permissions_data(),
1299 "Exchange data with any device in the domains: "
1300 "example.com foo.example.org",
1301 "Exchange data with the device named bar.example.org", true));
1304 // Since platform apps always use isolated storage, they can't (silently)
1305 // access user data on other domains, so there's no need to prompt about host
1306 // permissions. See crbug.com/255229.
1307 TEST(PermissionsTest, GetWarningMessages_PlatformAppHosts) {
1308 scoped_refptr<Extension> extension;
1310 extension = LoadManifest("permissions", "platform_app_hosts.json");
1311 EXPECT_TRUE(extension->is_platform_app());
1312 EXPECT_TRUE(VerifyNoPermissionMessages(extension->permissions_data()));
1314 extension = LoadManifest("permissions", "platform_app_all_urls.json");
1315 EXPECT_TRUE(extension->is_platform_app());
1316 EXPECT_TRUE(VerifyNoPermissionMessages(extension->permissions_data()));
1319 testing::AssertionResult ShowsAllHostsWarning(const std::string& pattern) {
1320 scoped_refptr<Extension> extension =
1321 ExtensionBuilder()
1322 .SetManifest(DictionaryBuilder()
1323 .Set("name", "TLDWildCardTest")
1324 .Set("version", "0.1.0")
1325 .Set("permissions", ListBuilder().Append(pattern))
1326 .Build())
1327 .Build();
1329 return VerifyHasPermissionMessage(
1330 extension->permissions_data(),
1331 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS));
1334 TEST(PermissionsTest, GetWarningMessages_TLDWildcardTreatedAsAllHosts) {
1335 EXPECT_TRUE(ShowsAllHostsWarning("http://*.com/*")); // most popular.
1336 EXPECT_TRUE(ShowsAllHostsWarning("http://*.org/*")); // sanity check.
1337 EXPECT_TRUE(ShowsAllHostsWarning("http://*.co.uk/*")); // eTLD.
1338 EXPECT_TRUE(ShowsAllHostsWarning("http://*.de/*")); // foreign country tld.
1340 // We should still show the normal permissions (i.e., "Can access your data on
1341 // *.rdcronin.com") for things that are not TLDs.
1342 EXPECT_FALSE(ShowsAllHostsWarning("http://*.rdcronin.com/*"));
1344 // Pseudo-TLDs, like appspot.com, should not show all hosts.
1345 EXPECT_FALSE(ShowsAllHostsWarning("http://*.appspot.com/*"));
1347 // Non-TLDs should be likewise exempt.
1348 EXPECT_FALSE(ShowsAllHostsWarning("http://*.notarealtld/*"));
1350 // Our internal checks use "foo", so let's make sure we're not messing
1351 // something up with it.
1352 EXPECT_FALSE(ShowsAllHostsWarning("http://*.foo.com"));
1353 EXPECT_FALSE(ShowsAllHostsWarning("http://foo.com"));
1354 // This will fail if foo becomes a recognized TLD. Which could be soon.
1355 // Update as needed.
1356 EXPECT_FALSE(ShowsAllHostsWarning("http://*.foo"));
1359 TEST(PermissionsTest, GetDistinctHosts) {
1360 URLPatternSet explicit_hosts;
1361 std::set<std::string> expected;
1362 expected.insert("www.foo.com");
1363 expected.insert("www.bar.com");
1364 expected.insert("www.baz.com");
1367 SCOPED_TRACE("no dupes");
1369 // Simple list with no dupes.
1370 explicit_hosts.AddPattern(
1371 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path"));
1372 explicit_hosts.AddPattern(
1373 URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/path"));
1374 explicit_hosts.AddPattern(
1375 URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path"));
1376 EXPECT_EQ(expected,
1377 permission_message_util::GetDistinctHosts(
1378 explicit_hosts, true, true));
1382 SCOPED_TRACE("two dupes");
1384 // Add some dupes.
1385 explicit_hosts.AddPattern(
1386 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path"));
1387 explicit_hosts.AddPattern(
1388 URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path"));
1389 EXPECT_EQ(expected,
1390 permission_message_util::GetDistinctHosts(
1391 explicit_hosts, true, true));
1395 SCOPED_TRACE("schemes differ");
1397 // Add a pattern that differs only by scheme. This should be filtered out.
1398 explicit_hosts.AddPattern(
1399 URLPattern(URLPattern::SCHEME_HTTPS, "https://www.bar.com/path"));
1400 EXPECT_EQ(expected,
1401 permission_message_util::GetDistinctHosts(
1402 explicit_hosts, true, true));
1406 SCOPED_TRACE("paths differ");
1408 // Add some dupes by path.
1409 explicit_hosts.AddPattern(
1410 URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/pathypath"));
1411 EXPECT_EQ(expected,
1412 permission_message_util::GetDistinctHosts(
1413 explicit_hosts, true, true));
1417 SCOPED_TRACE("subdomains differ");
1419 // We don't do anything special for subdomains.
1420 explicit_hosts.AddPattern(
1421 URLPattern(URLPattern::SCHEME_HTTP, "http://monkey.www.bar.com/path"));
1422 explicit_hosts.AddPattern(
1423 URLPattern(URLPattern::SCHEME_HTTP, "http://bar.com/path"));
1425 expected.insert("monkey.www.bar.com");
1426 expected.insert("bar.com");
1428 EXPECT_EQ(expected,
1429 permission_message_util::GetDistinctHosts(
1430 explicit_hosts, true, true));
1434 SCOPED_TRACE("RCDs differ");
1436 // Now test for RCD uniquing.
1437 explicit_hosts.AddPattern(
1438 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path"));
1439 explicit_hosts.AddPattern(
1440 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
1441 explicit_hosts.AddPattern(
1442 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.de/path"));
1443 explicit_hosts.AddPattern(
1444 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca.us/path"));
1445 explicit_hosts.AddPattern(
1446 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path"));
1447 explicit_hosts.AddPattern(
1448 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com.my/path"));
1450 // This is an unknown RCD, which shouldn't be uniqued out.
1451 explicit_hosts.AddPattern(
1452 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path"));
1453 // But it should only occur once.
1454 explicit_hosts.AddPattern(
1455 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path"));
1457 expected.insert("www.foo.xyzzy");
1459 EXPECT_EQ(expected,
1460 permission_message_util::GetDistinctHosts(
1461 explicit_hosts, true, true));
1465 SCOPED_TRACE("wildcards");
1467 explicit_hosts.AddPattern(
1468 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*"));
1470 expected.insert("*.google.com");
1472 EXPECT_EQ(expected,
1473 permission_message_util::GetDistinctHosts(
1474 explicit_hosts, true, true));
1478 SCOPED_TRACE("scriptable hosts");
1480 APIPermissionSet empty_perms;
1481 explicit_hosts.ClearPatterns();
1482 URLPatternSet scriptable_hosts;
1483 expected.clear();
1485 explicit_hosts.AddPattern(
1486 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*"));
1487 scriptable_hosts.AddPattern(
1488 URLPattern(URLPattern::SCHEME_HTTP, "http://*.example.com/*"));
1490 expected.insert("*.google.com");
1491 expected.insert("*.example.com");
1493 scoped_refptr<PermissionSet> perm_set(new PermissionSet(
1494 empty_perms, ManifestPermissionSet(),
1495 explicit_hosts, scriptable_hosts));
1496 EXPECT_EQ(expected,
1497 permission_message_util::GetDistinctHosts(
1498 perm_set->effective_hosts(), true, true));
1502 // We don't display warnings for file URLs because they are off by default.
1503 SCOPED_TRACE("file urls");
1505 explicit_hosts.ClearPatterns();
1506 expected.clear();
1508 explicit_hosts.AddPattern(
1509 URLPattern(URLPattern::SCHEME_FILE, "file:///*"));
1511 EXPECT_EQ(expected,
1512 permission_message_util::GetDistinctHosts(
1513 explicit_hosts, true, true));
1517 TEST(PermissionsTest, GetDistinctHosts_ComIsBestRcd) {
1518 URLPatternSet explicit_hosts;
1519 explicit_hosts.AddPattern(
1520 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path"));
1521 explicit_hosts.AddPattern(
1522 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path"));
1523 explicit_hosts.AddPattern(
1524 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
1525 explicit_hosts.AddPattern(
1526 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path"));
1527 explicit_hosts.AddPattern(
1528 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path"));
1529 explicit_hosts.AddPattern(
1530 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path"));
1532 std::set<std::string> expected;
1533 expected.insert("www.foo.com");
1534 EXPECT_EQ(expected,
1535 permission_message_util::GetDistinctHosts(
1536 explicit_hosts, true, true));
1539 TEST(PermissionsTest, GetDistinctHosts_NetIs2ndBestRcd) {
1540 URLPatternSet explicit_hosts;
1541 explicit_hosts.AddPattern(
1542 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path"));
1543 explicit_hosts.AddPattern(
1544 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path"));
1545 explicit_hosts.AddPattern(
1546 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
1547 explicit_hosts.AddPattern(
1548 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path"));
1549 explicit_hosts.AddPattern(
1550 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path"));
1551 // No http://www.foo.com/path
1553 std::set<std::string> expected;
1554 expected.insert("www.foo.net");
1555 EXPECT_EQ(expected,
1556 permission_message_util::GetDistinctHosts(
1557 explicit_hosts, true, true));
1560 TEST(PermissionsTest, GetDistinctHosts_OrgIs3rdBestRcd) {
1561 URLPatternSet explicit_hosts;
1562 explicit_hosts.AddPattern(
1563 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path"));
1564 explicit_hosts.AddPattern(
1565 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path"));
1566 explicit_hosts.AddPattern(
1567 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
1568 // No http://www.foo.net/path
1569 explicit_hosts.AddPattern(
1570 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path"));
1571 // No http://www.foo.com/path
1573 std::set<std::string> expected;
1574 expected.insert("www.foo.org");
1575 EXPECT_EQ(expected,
1576 permission_message_util::GetDistinctHosts(
1577 explicit_hosts, true, true));
1580 TEST(PermissionsTest, GetDistinctHosts_FirstInListIs4thBestRcd) {
1581 URLPatternSet explicit_hosts;
1582 explicit_hosts.AddPattern(
1583 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path"));
1584 // No http://www.foo.org/path
1585 explicit_hosts.AddPattern(
1586 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
1587 // No http://www.foo.net/path
1588 explicit_hosts.AddPattern(
1589 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path"));
1590 // No http://www.foo.com/path
1592 std::set<std::string> expected;
1593 expected.insert("www.foo.ca");
1594 EXPECT_EQ(expected,
1595 permission_message_util::GetDistinctHosts(
1596 explicit_hosts, true, true));
1599 TEST(PermissionsTest, IsHostPrivilegeIncrease) {
1600 Manifest::Type type = Manifest::TYPE_EXTENSION;
1601 const PermissionMessageProvider* provider = PermissionMessageProvider::Get();
1602 ManifestPermissionSet empty_manifest_permissions;
1603 URLPatternSet elist1;
1604 URLPatternSet elist2;
1605 URLPatternSet slist1;
1606 URLPatternSet slist2;
1607 scoped_refptr<PermissionSet> set1;
1608 scoped_refptr<PermissionSet> set2;
1609 APIPermissionSet empty_perms;
1610 elist1.AddPattern(
1611 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path"));
1612 elist1.AddPattern(
1613 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path"));
1615 // Test that the host order does not matter.
1616 elist2.AddPattern(
1617 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path"));
1618 elist2.AddPattern(
1619 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path"));
1621 set1 = new PermissionSet(empty_perms, empty_manifest_permissions,
1622 elist1, slist1);
1623 set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
1624 elist2, slist2);
1626 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1.get(), set2.get(), type));
1627 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2.get(), set1.get(), type));
1629 // Test that paths are ignored.
1630 elist2.ClearPatterns();
1631 elist2.AddPattern(
1632 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/*"));
1633 set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
1634 elist2, slist2);
1635 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1.get(), set2.get(), type));
1636 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2.get(), set1.get(), type));
1638 // Test that RCDs are ignored.
1639 elist2.ClearPatterns();
1640 elist2.AddPattern(
1641 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/*"));
1642 set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
1643 elist2, slist2);
1644 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1.get(), set2.get(), type));
1645 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2.get(), set1.get(), type));
1647 // Test that subdomain wildcards are handled properly.
1648 elist2.ClearPatterns();
1649 elist2.AddPattern(
1650 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com.hk/*"));
1651 set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
1652 elist2, slist2);
1653 EXPECT_TRUE(provider->IsPrivilegeIncrease(set1.get(), set2.get(), type));
1654 // TODO(jstritar): Does not match subdomains properly. http://crbug.com/65337
1655 // EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type));
1657 // Test that different domains count as different hosts.
1658 elist2.ClearPatterns();
1659 elist2.AddPattern(
1660 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path"));
1661 elist2.AddPattern(
1662 URLPattern(URLPattern::SCHEME_HTTP, "http://www.example.org/path"));
1663 set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
1664 elist2, slist2);
1665 EXPECT_TRUE(provider->IsPrivilegeIncrease(set1.get(), set2.get(), type));
1666 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2.get(), set1.get(), type));
1668 // Test that different subdomains count as different hosts.
1669 elist2.ClearPatterns();
1670 elist2.AddPattern(
1671 URLPattern(URLPattern::SCHEME_HTTP, "http://mail.google.com/*"));
1672 set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
1673 elist2, slist2);
1674 EXPECT_TRUE(provider->IsPrivilegeIncrease(set1.get(), set2.get(), type));
1675 EXPECT_TRUE(provider->IsPrivilegeIncrease(set2.get(), set1.get(), type));
1677 // Test that platform apps do not have host permissions increases.
1678 type = Manifest::TYPE_PLATFORM_APP;
1679 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1.get(), set2.get(), type));
1680 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2.get(), set1.get(), type));
1683 TEST(PermissionsTest, GetAPIsAsStrings) {
1684 APIPermissionSet apis;
1685 URLPatternSet empty_set;
1687 apis.insert(APIPermission::kProxy);
1688 apis.insert(APIPermission::kBackground);
1689 apis.insert(APIPermission::kNotifications);
1690 apis.insert(APIPermission::kTab);
1692 scoped_refptr<PermissionSet> perm_set = new PermissionSet(
1693 apis, ManifestPermissionSet(), empty_set, empty_set);
1694 std::set<std::string> api_names = perm_set->GetAPIsAsStrings();
1696 // The result is correct if it has the same number of elements
1697 // and we can convert it back to the id set.
1698 EXPECT_EQ(4u, api_names.size());
1699 EXPECT_EQ(apis,
1700 PermissionsInfo::GetInstance()->GetAllByName(api_names));
1703 TEST(PermissionsTest, IsEmpty) {
1704 APIPermissionSet empty_apis;
1705 URLPatternSet empty_extent;
1707 scoped_refptr<PermissionSet> empty = new PermissionSet();
1708 EXPECT_TRUE(empty->IsEmpty());
1709 scoped_refptr<PermissionSet> perm_set;
1711 perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(),
1712 empty_extent, empty_extent);
1713 EXPECT_TRUE(perm_set->IsEmpty());
1715 APIPermissionSet non_empty_apis;
1716 non_empty_apis.insert(APIPermission::kBackground);
1717 perm_set = new PermissionSet(non_empty_apis, ManifestPermissionSet(),
1718 empty_extent, empty_extent);
1719 EXPECT_FALSE(perm_set->IsEmpty());
1721 // Try non standard host
1722 URLPatternSet non_empty_extent;
1723 AddPattern(&non_empty_extent, "http://www.google.com/*");
1725 perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(),
1726 non_empty_extent, empty_extent);
1727 EXPECT_FALSE(perm_set->IsEmpty());
1729 perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(),
1730 empty_extent, non_empty_extent);
1731 EXPECT_FALSE(perm_set->IsEmpty());
1734 TEST(PermissionsTest, ImpliedPermissions) {
1735 URLPatternSet empty_extent;
1736 APIPermissionSet apis;
1737 apis.insert(APIPermission::kFileBrowserHandler);
1738 EXPECT_EQ(1U, apis.size());
1740 scoped_refptr<PermissionSet> perm_set;
1741 perm_set = new PermissionSet(apis, ManifestPermissionSet(),
1742 empty_extent, empty_extent);
1743 EXPECT_EQ(2U, perm_set->apis().size());
1746 TEST(PermissionsTest, SyncFileSystemPermission) {
1747 scoped_refptr<Extension> extension = LoadManifest(
1748 "permissions", "sync_file_system.json");
1749 APIPermissionSet apis;
1750 apis.insert(APIPermission::kSyncFileSystem);
1751 EXPECT_TRUE(extension->is_platform_app());
1752 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
1753 APIPermission::kSyncFileSystem));
1754 EXPECT_TRUE(
1755 VerifyOnePermissionMessage(extension->permissions_data(),
1756 "Store data in your Google Drive account"));
1759 // Make sure that we don't crash when we're trying to show the permissions
1760 // even though chrome://thumb (and everything that's not chrome://favicon with
1761 // a chrome:// scheme) is not a valid permission.
1762 // More details here: crbug/246314.
1763 TEST(PermissionsTest, ChromeURLs) {
1764 URLPatternSet allowed_hosts;
1765 allowed_hosts.AddPattern(
1766 URLPattern(URLPattern::SCHEME_ALL, "http://www.google.com/"));
1767 allowed_hosts.AddPattern(
1768 URLPattern(URLPattern::SCHEME_ALL, "chrome://favicon/"));
1769 allowed_hosts.AddPattern(
1770 URLPattern(URLPattern::SCHEME_ALL, "chrome://thumb/"));
1771 scoped_refptr<PermissionSet> permissions(
1772 new PermissionSet(APIPermissionSet(), ManifestPermissionSet(),
1773 allowed_hosts, URLPatternSet()));
1774 PermissionMessageProvider::Get()->GetPermissionMessages(
1775 PermissionMessageProvider::Get()->GetAllPermissionIDs(
1776 permissions.get(), Manifest::TYPE_EXTENSION));
1779 TEST(PermissionsTest, IsPrivilegeIncrease_DeclarativeWebRequest) {
1780 scoped_refptr<Extension> extension(
1781 LoadManifest("permissions", "permissions_all_urls.json"));
1782 scoped_refptr<const PermissionSet> permissions(
1783 extension->permissions_data()->active_permissions());
1785 scoped_refptr<Extension> extension_dwr(
1786 LoadManifest("permissions", "web_request_all_host_permissions.json"));
1787 scoped_refptr<const PermissionSet> permissions_dwr(
1788 extension_dwr->permissions_data()->active_permissions());
1790 EXPECT_FALSE(PermissionMessageProvider::Get()->
1791 IsPrivilegeIncrease(permissions.get(),
1792 permissions_dwr.get(),
1793 extension->GetType()));
1796 } // namespace extensions