Suppress tabs permission warning if there is already a browsingHistory warning.
[chromium-blink-merge.git] / chrome / common / extensions / permissions / permission_set_unittest.cc
blob86eb86513184de2b2d9e9c2a01bc5994cb06be48
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/path_service.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/common/chrome_paths.h"
11 #include "chrome/common/chrome_switches.h"
12 #include "chrome/common/extensions/extension_test_util.h"
13 #include "chrome/common/extensions/features/feature_channel.h"
14 #include "chrome/common/extensions/permissions/chrome_permission_message_provider.h"
15 #include "extensions/common/error_utils.h"
16 #include "extensions/common/extension.h"
17 #include "extensions/common/extension_builder.h"
18 #include "extensions/common/permissions/permission_message_provider.h"
19 #include "extensions/common/permissions/permission_message_util.h"
20 #include "extensions/common/permissions/permission_set.h"
21 #include "extensions/common/permissions/permissions_data.h"
22 #include "extensions/common/permissions/permissions_info.h"
23 #include "extensions/common/permissions/socket_permission.h"
24 #include "extensions/common/value_builder.h"
25 #include "grit/generated_resources.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "ui/base/l10n/l10n_util.h"
29 using extension_test_util::LoadManifest;
31 namespace extensions {
33 namespace {
35 static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
36 int schemes = URLPattern::SCHEME_ALL;
37 extent->AddPattern(URLPattern(schemes, pattern));
40 size_t IndexOf(const std::vector<base::string16>& warnings,
41 const std::string& warning) {
42 for (size_t i = 0; i < warnings.size(); ++i) {
43 if (warnings[i] == base::ASCIIToUTF16(warning))
44 return i;
47 return warnings.size();
50 bool Contains(const std::vector<base::string16>& warnings,
51 const std::string& warning) {
52 return IndexOf(warnings, warning) != warnings.size();
55 } // namespace
57 // Tests GetByID.
58 TEST(PermissionsTest, GetByID) {
59 PermissionsInfo* info = PermissionsInfo::GetInstance();
60 APIPermissionSet apis = info->GetAll();
61 for (APIPermissionSet::const_iterator i = apis.begin();
62 i != apis.end(); ++i) {
63 EXPECT_EQ(i->id(), i->info()->id());
67 // Tests that GetByName works with normal permission names and aliases.
68 TEST(PermissionsTest, GetByName) {
69 PermissionsInfo* info = PermissionsInfo::GetInstance();
70 EXPECT_EQ(APIPermission::kTab, info->GetByName("tabs")->id());
71 EXPECT_EQ(APIPermission::kManagement,
72 info->GetByName("management")->id());
73 EXPECT_FALSE(info->GetByName("alsdkfjasldkfj"));
76 TEST(PermissionsTest, GetAll) {
77 size_t count = 0;
78 PermissionsInfo* info = PermissionsInfo::GetInstance();
79 APIPermissionSet apis = info->GetAll();
80 for (APIPermissionSet::const_iterator api = apis.begin();
81 api != apis.end(); ++api) {
82 // Make sure only the valid permission IDs get returned.
83 EXPECT_NE(APIPermission::kInvalid, api->id());
84 EXPECT_NE(APIPermission::kUnknown, api->id());
85 count++;
87 EXPECT_EQ(count, info->get_permission_count());
90 TEST(PermissionsTest, GetAllByName) {
91 std::set<std::string> names;
92 names.insert("background");
93 names.insert("management");
95 // This is an alias of kTab
96 names.insert("windows");
98 // This unknown name should get dropped.
99 names.insert("sdlkfjasdlkfj");
101 APIPermissionSet expected;
102 expected.insert(APIPermission::kBackground);
103 expected.insert(APIPermission::kManagement);
104 expected.insert(APIPermission::kTab);
106 EXPECT_EQ(expected,
107 PermissionsInfo::GetInstance()->GetAllByName(names));
110 // Tests that the aliases are properly mapped.
111 TEST(PermissionsTest, Aliases) {
112 PermissionsInfo* info = PermissionsInfo::GetInstance();
113 // tabs: tabs, windows
114 std::string tabs_name = "tabs";
115 EXPECT_EQ(tabs_name, info->GetByID(APIPermission::kTab)->name());
116 EXPECT_EQ(APIPermission::kTab, info->GetByName("tabs")->id());
117 EXPECT_EQ(APIPermission::kTab, info->GetByName("windows")->id());
119 // unlimitedStorage: unlimitedStorage, unlimited_storage
120 std::string storage_name = "unlimitedStorage";
121 EXPECT_EQ(storage_name, info->GetByID(
122 APIPermission::kUnlimitedStorage)->name());
123 EXPECT_EQ(APIPermission::kUnlimitedStorage,
124 info->GetByName("unlimitedStorage")->id());
125 EXPECT_EQ(APIPermission::kUnlimitedStorage,
126 info->GetByName("unlimited_storage")->id());
129 TEST(PermissionsTest, EffectiveHostPermissions) {
130 scoped_refptr<Extension> extension;
131 scoped_refptr<const PermissionSet> permissions;
133 extension = LoadManifest("effective_host_permissions", "empty.json");
134 permissions = extension->GetActivePermissions();
135 EXPECT_EQ(0u,
136 PermissionsData::GetEffectiveHostPermissions(extension.get())
137 .patterns().size());
138 EXPECT_FALSE(
139 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com")));
140 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
142 extension = LoadManifest("effective_host_permissions", "one_host.json");
143 permissions = extension->GetActivePermissions();
144 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
145 GURL("http://www.google.com")));
146 EXPECT_FALSE(permissions->HasEffectiveAccessToURL(
147 GURL("https://www.google.com")));
148 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
150 extension = LoadManifest("effective_host_permissions",
151 "one_host_wildcard.json");
152 permissions = extension->GetActivePermissions();
153 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com")));
154 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
155 GURL("http://foo.google.com")));
156 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
158 extension = LoadManifest("effective_host_permissions", "two_hosts.json");
159 permissions = extension->GetActivePermissions();
160 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
161 GURL("http://www.google.com")));
162 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
163 GURL("http://www.reddit.com")));
164 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
166 extension = LoadManifest("effective_host_permissions",
167 "https_not_considered.json");
168 permissions = extension->GetActivePermissions();
169 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com")));
170 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("https://google.com")));
171 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
173 extension = LoadManifest("effective_host_permissions",
174 "two_content_scripts.json");
175 permissions = extension->GetActivePermissions();
176 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com")));
177 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
178 GURL("http://www.reddit.com")));
179 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
180 GURL("http://news.ycombinator.com")));
181 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
183 extension = LoadManifest("effective_host_permissions", "all_hosts.json");
184 permissions = extension->GetActivePermissions();
185 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://test/")));
186 EXPECT_FALSE(permissions->HasEffectiveAccessToURL(GURL("https://test/")));
187 EXPECT_TRUE(
188 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com")));
189 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
191 extension = LoadManifest("effective_host_permissions", "all_hosts2.json");
192 permissions = extension->GetActivePermissions();
193 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://test/")));
194 EXPECT_TRUE(
195 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com")));
196 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
198 extension = LoadManifest("effective_host_permissions", "all_hosts3.json");
199 permissions = extension->GetActivePermissions();
200 EXPECT_FALSE(permissions->HasEffectiveAccessToURL(GURL("http://test/")));
201 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("https://test/")));
202 EXPECT_TRUE(
203 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com")));
204 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
207 TEST(PermissionsTest, ExplicitAccessToOrigin) {
208 APIPermissionSet apis;
209 ManifestPermissionSet manifest_permissions;
210 URLPatternSet explicit_hosts;
211 URLPatternSet scriptable_hosts;
213 AddPattern(&explicit_hosts, "http://*.google.com/*");
214 // The explicit host paths should get set to /*.
215 AddPattern(&explicit_hosts, "http://www.example.com/a/particular/path/*");
217 scoped_refptr<PermissionSet> perm_set = new PermissionSet(
218 apis, manifest_permissions, explicit_hosts, scriptable_hosts);
219 ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin(
220 GURL("http://www.google.com/")));
221 ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin(
222 GURL("http://test.google.com/")));
223 ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin(
224 GURL("http://www.example.com")));
225 ASSERT_TRUE(perm_set->HasEffectiveAccessToURL(
226 GURL("http://www.example.com")));
227 ASSERT_FALSE(perm_set->HasExplicitAccessToOrigin(
228 GURL("http://test.example.com")));
231 TEST(PermissionsTest, CreateUnion) {
232 APIPermission* permission = NULL;
234 ManifestPermissionSet manifest_permissions;
235 APIPermissionSet apis1;
236 APIPermissionSet apis2;
237 APIPermissionSet expected_apis;
239 URLPatternSet explicit_hosts1;
240 URLPatternSet explicit_hosts2;
241 URLPatternSet expected_explicit_hosts;
243 URLPatternSet scriptable_hosts1;
244 URLPatternSet scriptable_hosts2;
245 URLPatternSet expected_scriptable_hosts;
247 URLPatternSet effective_hosts;
249 scoped_refptr<PermissionSet> set1;
250 scoped_refptr<PermissionSet> set2;
251 scoped_refptr<PermissionSet> union_set;
253 const APIPermissionInfo* permission_info =
254 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket);
255 permission = permission_info->CreateAPIPermission();
257 scoped_ptr<base::ListValue> value(new base::ListValue());
258 value->Append(
259 base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
260 value->Append(base::Value::CreateStringValue("udp-bind::8080"));
261 value->Append(base::Value::CreateStringValue("udp-send-to::8888"));
262 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
265 // Union with an empty set.
266 apis1.insert(APIPermission::kTab);
267 apis1.insert(APIPermission::kBackground);
268 apis1.insert(permission->Clone());
269 expected_apis.insert(APIPermission::kTab);
270 expected_apis.insert(APIPermission::kBackground);
271 expected_apis.insert(permission);
273 AddPattern(&explicit_hosts1, "http://*.google.com/*");
274 AddPattern(&expected_explicit_hosts, "http://*.google.com/*");
275 AddPattern(&effective_hosts, "http://*.google.com/*");
277 set1 = new PermissionSet(apis1, manifest_permissions,
278 explicit_hosts1, scriptable_hosts1);
279 set2 = new PermissionSet(apis2, manifest_permissions,
280 explicit_hosts2, scriptable_hosts2);
281 union_set = PermissionSet::CreateUnion(set1.get(), set2.get());
282 EXPECT_TRUE(set1->Contains(*set2.get()));
283 EXPECT_TRUE(set1->Contains(*union_set.get()));
284 EXPECT_FALSE(set2->Contains(*set1.get()));
285 EXPECT_FALSE(set2->Contains(*union_set.get()));
286 EXPECT_TRUE(union_set->Contains(*set1.get()));
287 EXPECT_TRUE(union_set->Contains(*set2.get()));
289 EXPECT_FALSE(union_set->HasEffectiveFullAccess());
290 EXPECT_EQ(expected_apis, union_set->apis());
291 EXPECT_EQ(expected_explicit_hosts, union_set->explicit_hosts());
292 EXPECT_EQ(expected_scriptable_hosts, union_set->scriptable_hosts());
293 EXPECT_EQ(expected_explicit_hosts, union_set->effective_hosts());
295 // Now use a real second set.
296 apis2.insert(APIPermission::kTab);
297 apis2.insert(APIPermission::kProxy);
298 apis2.insert(APIPermission::kClipboardWrite);
299 apis2.insert(APIPermission::kPlugin);
301 permission = permission_info->CreateAPIPermission();
303 scoped_ptr<base::ListValue> value(new base::ListValue());
304 value->Append(
305 base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
306 value->Append(base::Value::CreateStringValue("udp-send-to::8899"));
307 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
309 apis2.insert(permission);
311 expected_apis.insert(APIPermission::kTab);
312 expected_apis.insert(APIPermission::kProxy);
313 expected_apis.insert(APIPermission::kClipboardWrite);
314 expected_apis.insert(APIPermission::kPlugin);
316 permission = permission_info->CreateAPIPermission();
318 scoped_ptr<base::ListValue> value(new base::ListValue());
319 value->Append(
320 base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
321 value->Append(base::Value::CreateStringValue("udp-bind::8080"));
322 value->Append(base::Value::CreateStringValue("udp-send-to::8888"));
323 value->Append(base::Value::CreateStringValue("udp-send-to::8899"));
324 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
326 // Insert a new permission socket permisssion which will replace the old one.
327 expected_apis.insert(permission);
329 AddPattern(&explicit_hosts2, "http://*.example.com/*");
330 AddPattern(&scriptable_hosts2, "http://*.google.com/*");
331 AddPattern(&expected_explicit_hosts, "http://*.example.com/*");
332 AddPattern(&expected_scriptable_hosts, "http://*.google.com/*");
334 URLPatternSet::CreateUnion(
335 explicit_hosts2, scriptable_hosts2, &effective_hosts);
337 set2 = new PermissionSet(apis2, manifest_permissions,
338 explicit_hosts2, scriptable_hosts2);
339 union_set = PermissionSet::CreateUnion(set1.get(), set2.get());
341 EXPECT_FALSE(set1->Contains(*set2.get()));
342 EXPECT_FALSE(set1->Contains(*union_set.get()));
343 EXPECT_FALSE(set2->Contains(*set1.get()));
344 EXPECT_FALSE(set2->Contains(*union_set.get()));
345 EXPECT_TRUE(union_set->Contains(*set1.get()));
346 EXPECT_TRUE(union_set->Contains(*set2.get()));
348 EXPECT_TRUE(union_set->HasEffectiveFullAccess());
349 EXPECT_TRUE(union_set->HasEffectiveAccessToAllHosts());
350 EXPECT_EQ(expected_apis, union_set->apis());
351 EXPECT_EQ(expected_explicit_hosts, union_set->explicit_hosts());
352 EXPECT_EQ(expected_scriptable_hosts, union_set->scriptable_hosts());
353 EXPECT_EQ(effective_hosts, union_set->effective_hosts());
356 TEST(PermissionsTest, CreateIntersection) {
357 APIPermission* permission = NULL;
359 ManifestPermissionSet manifest_permissions;
360 APIPermissionSet apis1;
361 APIPermissionSet apis2;
362 APIPermissionSet expected_apis;
364 URLPatternSet explicit_hosts1;
365 URLPatternSet explicit_hosts2;
366 URLPatternSet expected_explicit_hosts;
368 URLPatternSet scriptable_hosts1;
369 URLPatternSet scriptable_hosts2;
370 URLPatternSet expected_scriptable_hosts;
372 URLPatternSet effective_hosts;
374 scoped_refptr<PermissionSet> set1;
375 scoped_refptr<PermissionSet> set2;
376 scoped_refptr<PermissionSet> new_set;
378 const APIPermissionInfo* permission_info =
379 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket);
381 // Intersection with an empty set.
382 apis1.insert(APIPermission::kTab);
383 apis1.insert(APIPermission::kBackground);
384 permission = permission_info->CreateAPIPermission();
386 scoped_ptr<base::ListValue> value(new base::ListValue());
387 value->Append(
388 base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
389 value->Append(base::Value::CreateStringValue("udp-bind::8080"));
390 value->Append(base::Value::CreateStringValue("udp-send-to::8888"));
391 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
393 apis1.insert(permission);
395 AddPattern(&explicit_hosts1, "http://*.google.com/*");
396 AddPattern(&scriptable_hosts1, "http://www.reddit.com/*");
398 set1 = new PermissionSet(apis1, manifest_permissions,
399 explicit_hosts1, scriptable_hosts1);
400 set2 = new PermissionSet(apis2, manifest_permissions,
401 explicit_hosts2, scriptable_hosts2);
402 new_set = PermissionSet::CreateIntersection(set1.get(), set2.get());
403 EXPECT_TRUE(set1->Contains(*new_set.get()));
404 EXPECT_TRUE(set2->Contains(*new_set.get()));
405 EXPECT_TRUE(set1->Contains(*set2.get()));
406 EXPECT_FALSE(set2->Contains(*set1.get()));
407 EXPECT_FALSE(new_set->Contains(*set1.get()));
408 EXPECT_TRUE(new_set->Contains(*set2.get()));
410 EXPECT_TRUE(new_set->IsEmpty());
411 EXPECT_FALSE(new_set->HasEffectiveFullAccess());
412 EXPECT_EQ(expected_apis, new_set->apis());
413 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts());
414 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts());
415 EXPECT_EQ(expected_explicit_hosts, new_set->effective_hosts());
417 // Now use a real second set.
418 apis2.insert(APIPermission::kTab);
419 apis2.insert(APIPermission::kProxy);
420 apis2.insert(APIPermission::kClipboardWrite);
421 apis2.insert(APIPermission::kPlugin);
422 permission = permission_info->CreateAPIPermission();
424 scoped_ptr<base::ListValue> value(new base::ListValue());
425 value->Append(base::Value::CreateStringValue("udp-bind::8080"));
426 value->Append(base::Value::CreateStringValue("udp-send-to::8888"));
427 value->Append(base::Value::CreateStringValue("udp-send-to::8899"));
428 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
430 apis2.insert(permission);
432 expected_apis.insert(APIPermission::kTab);
433 permission = permission_info->CreateAPIPermission();
435 scoped_ptr<base::ListValue> value(new base::ListValue());
436 value->Append(base::Value::CreateStringValue("udp-bind::8080"));
437 value->Append(base::Value::CreateStringValue("udp-send-to::8888"));
438 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
440 expected_apis.insert(permission);
442 AddPattern(&explicit_hosts2, "http://*.example.com/*");
443 AddPattern(&explicit_hosts2, "http://*.google.com/*");
444 AddPattern(&scriptable_hosts2, "http://*.google.com/*");
445 AddPattern(&expected_explicit_hosts, "http://*.google.com/*");
447 effective_hosts.ClearPatterns();
448 AddPattern(&effective_hosts, "http://*.google.com/*");
450 set2 = new PermissionSet(apis2, manifest_permissions,
451 explicit_hosts2, scriptable_hosts2);
452 new_set = PermissionSet::CreateIntersection(set1.get(), set2.get());
454 EXPECT_TRUE(set1->Contains(*new_set.get()));
455 EXPECT_TRUE(set2->Contains(*new_set.get()));
456 EXPECT_FALSE(set1->Contains(*set2.get()));
457 EXPECT_FALSE(set2->Contains(*set1.get()));
458 EXPECT_FALSE(new_set->Contains(*set1.get()));
459 EXPECT_FALSE(new_set->Contains(*set2.get()));
461 EXPECT_FALSE(new_set->HasEffectiveFullAccess());
462 EXPECT_FALSE(new_set->HasEffectiveAccessToAllHosts());
463 EXPECT_EQ(expected_apis, new_set->apis());
464 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts());
465 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts());
466 EXPECT_EQ(effective_hosts, new_set->effective_hosts());
469 TEST(PermissionsTest, CreateDifference) {
470 APIPermission* permission = NULL;
472 ManifestPermissionSet manifest_permissions;
473 APIPermissionSet apis1;
474 APIPermissionSet apis2;
475 APIPermissionSet expected_apis;
477 URLPatternSet explicit_hosts1;
478 URLPatternSet explicit_hosts2;
479 URLPatternSet expected_explicit_hosts;
481 URLPatternSet scriptable_hosts1;
482 URLPatternSet scriptable_hosts2;
483 URLPatternSet expected_scriptable_hosts;
485 URLPatternSet effective_hosts;
487 scoped_refptr<PermissionSet> set1;
488 scoped_refptr<PermissionSet> set2;
489 scoped_refptr<PermissionSet> new_set;
491 const APIPermissionInfo* permission_info =
492 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket);
494 // Difference with an empty set.
495 apis1.insert(APIPermission::kTab);
496 apis1.insert(APIPermission::kBackground);
497 permission = permission_info->CreateAPIPermission();
499 scoped_ptr<base::ListValue> value(new base::ListValue());
500 value->Append(
501 base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
502 value->Append(base::Value::CreateStringValue("udp-bind::8080"));
503 value->Append(base::Value::CreateStringValue("udp-send-to::8888"));
504 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
506 apis1.insert(permission);
508 AddPattern(&explicit_hosts1, "http://*.google.com/*");
509 AddPattern(&scriptable_hosts1, "http://www.reddit.com/*");
511 set1 = new PermissionSet(apis1, manifest_permissions,
512 explicit_hosts1, scriptable_hosts1);
513 set2 = new PermissionSet(apis2, manifest_permissions,
514 explicit_hosts2, scriptable_hosts2);
515 new_set = PermissionSet::CreateDifference(set1.get(), set2.get());
516 EXPECT_EQ(*set1.get(), *new_set.get());
518 // Now use a real second set.
519 apis2.insert(APIPermission::kTab);
520 apis2.insert(APIPermission::kProxy);
521 apis2.insert(APIPermission::kClipboardWrite);
522 apis2.insert(APIPermission::kPlugin);
523 permission = permission_info->CreateAPIPermission();
525 scoped_ptr<base::ListValue> value(new base::ListValue());
526 value->Append(
527 base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
528 value->Append(base::Value::CreateStringValue("udp-send-to::8899"));
529 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
531 apis2.insert(permission);
533 expected_apis.insert(APIPermission::kBackground);
534 permission = permission_info->CreateAPIPermission();
536 scoped_ptr<base::ListValue> value(new base::ListValue());
537 value->Append(base::Value::CreateStringValue("udp-bind::8080"));
538 value->Append(base::Value::CreateStringValue("udp-send-to::8888"));
539 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
541 expected_apis.insert(permission);
543 AddPattern(&explicit_hosts2, "http://*.example.com/*");
544 AddPattern(&explicit_hosts2, "http://*.google.com/*");
545 AddPattern(&scriptable_hosts2, "http://*.google.com/*");
546 AddPattern(&expected_scriptable_hosts, "http://www.reddit.com/*");
548 effective_hosts.ClearPatterns();
549 AddPattern(&effective_hosts, "http://www.reddit.com/*");
551 set2 = new PermissionSet(apis2, manifest_permissions,
552 explicit_hosts2, scriptable_hosts2);
553 new_set = PermissionSet::CreateDifference(set1.get(), set2.get());
555 EXPECT_TRUE(set1->Contains(*new_set.get()));
556 EXPECT_FALSE(set2->Contains(*new_set.get()));
558 EXPECT_FALSE(new_set->HasEffectiveFullAccess());
559 EXPECT_FALSE(new_set->HasEffectiveAccessToAllHosts());
560 EXPECT_EQ(expected_apis, new_set->apis());
561 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts());
562 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts());
563 EXPECT_EQ(effective_hosts, new_set->effective_hosts());
565 // |set3| = |set1| - |set2| --> |set3| intersect |set2| == empty_set
566 set1 = PermissionSet::CreateIntersection(new_set.get(), set2.get());
567 EXPECT_TRUE(set1->IsEmpty());
570 TEST(PermissionsTest, IsPrivilegeIncrease) {
571 const struct {
572 const char* base_name;
573 bool expect_increase;
574 } kTests[] = {
575 { "allhosts1", false }, // all -> all
576 { "allhosts2", false }, // all -> one
577 { "allhosts3", true }, // one -> all
578 { "hosts1", false }, // http://a,http://b -> http://a,http://b
579 { "hosts2", true }, // http://a,http://b -> https://a,http://*.b
580 { "hosts3", false }, // http://a,http://b -> http://a
581 { "hosts4", true }, // http://a -> http://a,http://b
582 { "hosts5", false }, // http://a,b,c -> http://a,b,c + https://a,b,c
583 { "hosts6", false }, // http://a.com -> http://a.com + http://a.co.uk
584 { "permissions1", false }, // tabs -> tabs
585 { "permissions2", true }, // tabs -> tabs,bookmarks
586 { "permissions3", true }, // http://a -> http://a,tabs
587 { "permissions5", true }, // bookmarks -> bookmarks,history
588 { "equivalent_warnings", false }, // tabs --> tabs, webNavigation
589 #if !defined(OS_CHROMEOS) // plugins aren't allowed in ChromeOS
590 { "permissions4", false }, // plugin -> plugin,tabs
591 { "plugin1", false }, // plugin -> plugin
592 { "plugin2", false }, // plugin -> none
593 { "plugin3", true }, // none -> plugin
594 #endif
595 { "storage", false }, // none -> storage
596 { "notifications", false }, // none -> notifications
597 { "platformapp1", false }, // host permissions for platform apps
598 { "platformapp2", true }, // API permissions for platform apps
599 { "media_galleries1", true }, // all -> read|all
600 { "media_galleries2", true }, // read|all -> read|delete|copyTo|all
601 { "media_galleries3", true }, // all -> read|delete|all
602 { "media_galleries4", false }, // read|all -> all
603 { "media_galleries5", false }, // read|copyTo|delete|all -> read|all
604 { "media_galleries6", false }, // read|all -> read|all
605 { "media_galleries7", true }, // read|delete|all -> read|copyTo|delete|all
606 { "sockets1", true }, // none -> tcp:*:*
607 { "sockets2", false }, // tcp:*:* -> tcp:*:*
608 { "sockets3", true }, // tcp:a.com:80 -> tcp:*:*
611 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTests); ++i) {
612 scoped_refptr<Extension> old_extension(
613 LoadManifest("allow_silent_upgrade",
614 std::string(kTests[i].base_name) + "_old.json"));
615 scoped_refptr<Extension> new_extension(
616 LoadManifest("allow_silent_upgrade",
617 std::string(kTests[i].base_name) + "_new.json"));
619 EXPECT_TRUE(new_extension.get()) << kTests[i].base_name << "_new.json";
620 if (!new_extension.get())
621 continue;
623 scoped_refptr<const PermissionSet> old_p(
624 old_extension->GetActivePermissions());
625 scoped_refptr<const PermissionSet> new_p(
626 new_extension->GetActivePermissions());
627 Manifest::Type extension_type = old_extension->GetType();
629 bool increased = PermissionMessageProvider::Get()->IsPrivilegeIncrease(
630 old_p.get(), new_p.get(), extension_type);
631 EXPECT_EQ(kTests[i].expect_increase, increased) << kTests[i].base_name;
635 TEST(PermissionsTest, PermissionMessages) {
636 // Ensure that all permissions that needs to show install UI actually have
637 // strings associated with them.
638 APIPermissionSet skip;
640 // These are considered "nuisance" or "trivial" permissions that don't need
641 // a prompt.
642 skip.insert(APIPermission::kActiveTab);
643 skip.insert(APIPermission::kAdView);
644 skip.insert(APIPermission::kAlarms);
645 skip.insert(APIPermission::kAlwaysOnTopWindows);
646 skip.insert(APIPermission::kAudio);
647 skip.insert(APIPermission::kBrowsingData);
648 skip.insert(APIPermission::kCastStreaming);
649 skip.insert(APIPermission::kContextMenus);
650 skip.insert(APIPermission::kDiagnostics);
651 skip.insert(APIPermission::kDns);
652 skip.insert(APIPermission::kDownloadsShelf);
653 skip.insert(APIPermission::kFontSettings);
654 skip.insert(APIPermission::kFullscreen);
655 skip.insert(APIPermission::kGcm);
656 skip.insert(APIPermission::kIdle);
657 skip.insert(APIPermission::kIdltest);
658 skip.insert(APIPermission::kLogPrivate);
659 skip.insert(APIPermission::kNotification);
660 skip.insert(APIPermission::kOverrideEscFullscreen);
661 skip.insert(APIPermission::kPointerLock);
662 skip.insert(APIPermission::kPower);
663 skip.insert(APIPermission::kPushMessaging);
664 skip.insert(APIPermission::kSessions);
665 skip.insert(APIPermission::kStorage);
666 skip.insert(APIPermission::kSystemCpu);
667 skip.insert(APIPermission::kSystemDisplay);
668 skip.insert(APIPermission::kSystemMemory);
669 skip.insert(APIPermission::kSystemNetwork);
670 skip.insert(APIPermission::kSystemStorage);
671 skip.insert(APIPermission::kTts);
672 skip.insert(APIPermission::kUnlimitedStorage);
673 skip.insert(APIPermission::kWebcamPrivate);
674 skip.insert(APIPermission::kWebView);
675 skip.insert(APIPermission::kWindowShape);
677 // TODO(erikkay) add a string for this permission.
678 skip.insert(APIPermission::kBackground);
680 skip.insert(APIPermission::kClipboardWrite);
682 // The cookie permission does nothing unless you have associated host
683 // permissions.
684 skip.insert(APIPermission::kCookie);
686 // These are warned as part of host permission checks.
687 skip.insert(APIPermission::kDeclarativeContent);
688 skip.insert(APIPermission::kPageCapture);
689 skip.insert(APIPermission::kProxy);
690 skip.insert(APIPermission::kTabCapture);
691 skip.insert(APIPermission::kWebRequest);
692 skip.insert(APIPermission::kWebRequestBlocking);
694 // This permission requires explicit user action (context menu handler)
695 // so we won't prompt for it for now.
696 skip.insert(APIPermission::kFileBrowserHandler);
698 // These permissions require explicit user action (configuration dialog)
699 // so we don't prompt for them at install time.
700 skip.insert(APIPermission::kMediaGalleries);
702 // If you've turned on the experimental command-line flag, we don't need
703 // to warn you further.
704 skip.insert(APIPermission::kExperimental);
706 // The Identity API has its own server-driven permission prompts.
707 skip.insert(APIPermission::kIdentity);
709 // These are private.
710 skip.insert(APIPermission::kAccessibilityPrivate);
711 skip.insert(APIPermission::kAutoTestPrivate);
712 skip.insert(APIPermission::kBookmarkManagerPrivate);
713 skip.insert(APIPermission::kBrailleDisplayPrivate);
714 skip.insert(APIPermission::kCast);
715 skip.insert(APIPermission::kCastStreaming);
716 skip.insert(APIPermission::kChromeosInfoPrivate);
717 skip.insert(APIPermission::kCloudPrintPrivate);
718 skip.insert(APIPermission::kCommandLinePrivate);
719 skip.insert(APIPermission::kDeveloperPrivate);
720 skip.insert(APIPermission::kDial);
721 skip.insert(APIPermission::kDownloadsInternal);
722 skip.insert(APIPermission::kEchoPrivate);
723 skip.insert(APIPermission::kEnterprisePlatformKeysPrivate);
724 skip.insert(APIPermission::kFeedbackPrivate);
725 skip.insert(APIPermission::kFileBrowserHandlerInternal);
726 skip.insert(APIPermission::kFileBrowserPrivate);
727 skip.insert(APIPermission::kFirstRunPrivate);
728 skip.insert(APIPermission::kHotwordPrivate);
729 skip.insert(APIPermission::kIdentityPrivate);
730 skip.insert(APIPermission::kInfobars);
731 skip.insert(APIPermission::kInputMethodPrivate);
732 skip.insert(APIPermission::kMediaGalleriesPrivate);
733 skip.insert(APIPermission::kMediaPlayerPrivate);
734 skip.insert(APIPermission::kMetricsPrivate);
735 skip.insert(APIPermission::kMDns);
736 skip.insert(APIPermission::kPreferencesPrivate);
737 skip.insert(APIPermission::kPrincipalsPrivate);
738 skip.insert(APIPermission::kImageWriterPrivate);
739 skip.insert(APIPermission::kReadingListPrivate);
740 skip.insert(APIPermission::kRtcPrivate);
741 skip.insert(APIPermission::kStreamsPrivate);
742 skip.insert(APIPermission::kSystemPrivate);
743 skip.insert(APIPermission::kTabCaptureForTab);
744 skip.insert(APIPermission::kTerminalPrivate);
745 skip.insert(APIPermission::kVirtualKeyboardPrivate);
746 skip.insert(APIPermission::kWallpaperPrivate);
747 skip.insert(APIPermission::kWebrtcAudioPrivate);
748 skip.insert(APIPermission::kWebrtcLoggingPrivate);
749 skip.insert(APIPermission::kWebstorePrivate);
751 // Warned as part of host permissions.
752 skip.insert(APIPermission::kDevtools);
754 // Platform apps.
755 skip.insert(APIPermission::kFileSystem);
756 skip.insert(APIPermission::kFileSystemProvider);
757 skip.insert(APIPermission::kFileSystemRetainEntries);
758 skip.insert(APIPermission::kSocket);
759 skip.insert(APIPermission::kUsbDevice);
761 PermissionsInfo* info = PermissionsInfo::GetInstance();
762 APIPermissionSet permissions = info->GetAll();
763 for (APIPermissionSet::const_iterator i = permissions.begin();
764 i != permissions.end(); ++i) {
765 const APIPermissionInfo* permission_info = i->info();
766 EXPECT_TRUE(permission_info != NULL);
768 if (skip.count(i->id())) {
769 EXPECT_EQ(PermissionMessage::kNone, permission_info->message_id())
770 << "unexpected message_id for " << permission_info->name();
771 } else {
772 EXPECT_NE(PermissionMessage::kNone, permission_info->message_id())
773 << "missing message_id for " << permission_info->name();
778 TEST(PermissionsTest, FileSystemPermissionMessages) {
779 APIPermissionSet api_permissions;
780 api_permissions.insert(APIPermission::kFileSystemWrite);
781 api_permissions.insert(APIPermission::kFileSystemDirectory);
782 scoped_refptr<PermissionSet> permissions(
783 new PermissionSet(api_permissions, ManifestPermissionSet(),
784 URLPatternSet(), URLPatternSet()));
785 PermissionMessages messages =
786 PermissionMessageProvider::Get()->GetPermissionMessages(
787 permissions, Manifest::TYPE_PLATFORM_APP);
788 ASSERT_EQ(2u, messages.size());
789 std::sort(messages.begin(), messages.end());
790 std::set<PermissionMessage::ID> ids;
791 for (PermissionMessages::const_iterator it = messages.begin();
792 it != messages.end(); ++it) {
793 ids.insert(it->id());
795 EXPECT_TRUE(ContainsKey(ids, PermissionMessage::kFileSystemDirectory));
796 EXPECT_TRUE(ContainsKey(ids, PermissionMessage::kFileSystemWrite));
799 TEST(PermissionsTest, HiddenFileSystemPermissionMessages) {
800 APIPermissionSet api_permissions;
801 api_permissions.insert(APIPermission::kFileSystemWrite);
802 api_permissions.insert(APIPermission::kFileSystemDirectory);
803 api_permissions.insert(APIPermission::kFileSystemWriteDirectory);
804 scoped_refptr<PermissionSet> permissions(
805 new PermissionSet(api_permissions, ManifestPermissionSet(),
806 URLPatternSet(), URLPatternSet()));
807 PermissionMessages messages =
808 PermissionMessageProvider::Get()->GetPermissionMessages(
809 permissions, Manifest::TYPE_PLATFORM_APP);
810 ASSERT_EQ(1u, messages.size());
811 EXPECT_EQ(PermissionMessage::kFileSystemWriteDirectory, messages[0].id());
814 TEST(PermissionsTest, SuppressedPermissionMessages) {
815 APIPermissionSet api_permissions;
816 api_permissions.insert(APIPermission::kTab);
817 api_permissions.insert(APIPermission::kHistory);
818 scoped_refptr<PermissionSet> permissions(
819 new PermissionSet(api_permissions, ManifestPermissionSet(),
820 URLPatternSet(), URLPatternSet()));
821 PermissionMessages messages =
822 PermissionMessageProvider::Get()->GetPermissionMessages(
823 permissions, Manifest::TYPE_EXTENSION);
824 EXPECT_EQ(1u, messages.size());
825 EXPECT_EQ(PermissionMessage::kBrowsingHistory, messages[0].id());
828 TEST(PermissionsTest, MergedFileSystemPermissionComparison) {
829 APIPermissionSet write_api_permissions;
830 write_api_permissions.insert(APIPermission::kFileSystemWrite);
831 scoped_refptr<PermissionSet> write_permissions(
832 new PermissionSet(write_api_permissions, ManifestPermissionSet(),
833 URLPatternSet(), URLPatternSet()));
835 APIPermissionSet directory_api_permissions;
836 directory_api_permissions.insert(APIPermission::kFileSystemDirectory);
837 scoped_refptr<PermissionSet> directory_permissions(
838 new PermissionSet(directory_api_permissions, ManifestPermissionSet(),
839 URLPatternSet(), URLPatternSet()));
841 APIPermissionSet write_directory_api_permissions;
842 write_directory_api_permissions.insert(
843 APIPermission::kFileSystemWriteDirectory);
844 scoped_refptr<PermissionSet> write_directory_permissions(
845 new PermissionSet(write_directory_api_permissions,
846 ManifestPermissionSet(),
847 URLPatternSet(),
848 URLPatternSet()));
850 const PermissionMessageProvider* provider = PermissionMessageProvider::Get();
851 EXPECT_FALSE(provider->IsPrivilegeIncrease(write_directory_permissions,
852 write_permissions,
853 Manifest::TYPE_PLATFORM_APP));
854 EXPECT_FALSE(provider->IsPrivilegeIncrease(write_directory_permissions,
855 directory_permissions,
856 Manifest::TYPE_PLATFORM_APP));
857 EXPECT_TRUE(provider->IsPrivilegeIncrease(write_permissions,
858 directory_permissions,
859 Manifest::TYPE_PLATFORM_APP));
860 EXPECT_TRUE(provider->IsPrivilegeIncrease(write_permissions,
861 write_directory_permissions,
862 Manifest::TYPE_PLATFORM_APP));
863 EXPECT_TRUE(provider->IsPrivilegeIncrease(directory_permissions,
864 write_permissions,
865 Manifest::TYPE_PLATFORM_APP));
866 EXPECT_TRUE(provider->IsPrivilegeIncrease(directory_permissions,
867 write_directory_permissions,
868 Manifest::TYPE_PLATFORM_APP));
871 TEST(PermissionsTest, GetWarningMessages_ManyHosts) {
872 scoped_refptr<Extension> extension;
874 extension = LoadManifest("permissions", "many-hosts.json");
875 std::vector<base::string16> warnings =
876 PermissionsData::GetPermissionMessageStrings(extension.get());
877 ASSERT_EQ(1u, warnings.size());
878 EXPECT_EQ("Access your data on encrypted.google.com and www.google.com",
879 base::UTF16ToUTF8(warnings[0]));
882 TEST(PermissionsTest, GetWarningMessages_Plugins) {
883 scoped_refptr<Extension> extension;
884 scoped_refptr<PermissionSet> permissions;
886 extension = LoadManifest("permissions", "plugins.json");
887 std::vector<base::string16> warnings =
888 PermissionsData::GetPermissionMessageStrings(extension.get());
889 // We don't parse the plugins key on Chrome OS, so it should not ask for any
890 // permissions.
891 #if defined(OS_CHROMEOS)
892 ASSERT_EQ(0u, warnings.size());
893 #else
894 ASSERT_EQ(1u, warnings.size());
895 EXPECT_EQ("Access all data on your computer and the websites you visit",
896 base::UTF16ToUTF8(warnings[0]));
897 #endif
900 TEST(PermissionsTest, GetWarningMessages_AudioVideo) {
901 // Both audio and video present.
902 scoped_refptr<Extension> extension =
903 LoadManifest("permissions", "audio-video.json");
904 const PermissionMessageProvider* provider = PermissionMessageProvider::Get();
905 PermissionSet* set =
906 const_cast<PermissionSet*>(
907 extension->GetActivePermissions().get());
908 std::vector<base::string16> warnings =
909 provider->GetWarningMessages(set, extension->GetType());
910 EXPECT_FALSE(Contains(warnings, "Use your microphone"));
911 EXPECT_FALSE(Contains(warnings, "Use your camera"));
912 EXPECT_TRUE(Contains(warnings, "Use your microphone and camera"));
913 size_t combined_index = IndexOf(warnings, "Use your microphone and camera");
914 size_t combined_size = warnings.size();
916 // Just audio present.
917 set->apis_.erase(APIPermission::kVideoCapture);
918 warnings = provider->GetWarningMessages(set, extension->GetType());
919 EXPECT_EQ(combined_size, warnings.size());
920 EXPECT_EQ(combined_index, IndexOf(warnings, "Use your microphone"));
921 EXPECT_FALSE(Contains(warnings, "Use your camera"));
922 EXPECT_FALSE(Contains(warnings, "Use your microphone and camera"));
924 // Just video present.
925 set->apis_.erase(APIPermission::kAudioCapture);
926 set->apis_.insert(APIPermission::kVideoCapture);
927 warnings = provider->GetWarningMessages(set, extension->GetType());
928 EXPECT_EQ(combined_size, warnings.size());
929 EXPECT_FALSE(Contains(warnings, "Use your microphone"));
930 EXPECT_FALSE(Contains(warnings, "Use your microphone and camera"));
931 EXPECT_TRUE(Contains(warnings, "Use your camera"));
934 TEST(PermissionsTest, GetWarningMessages_DeclarativeWebRequest) {
935 // Test that if the declarativeWebRequest permission is present
936 // in combination with all hosts permission, then only the warning
937 // for host permissions is shown, because that covers the use of
938 // declarativeWebRequest.
940 // Until Declarative Web Request is in stable, let's make sure it is enabled
941 // on the current channel.
942 ScopedCurrentChannel sc(chrome::VersionInfo::CHANNEL_CANARY);
944 // First verify that declarativeWebRequest produces a message when host
945 // permissions do not cover all hosts.
946 scoped_refptr<Extension> extension =
947 LoadManifest("permissions", "web_request_not_all_host_permissions.json");
948 const PermissionMessageProvider* provider = PermissionMessageProvider::Get();
949 const PermissionSet* set = extension->GetActivePermissions().get();
950 std::vector<base::string16> warnings =
951 provider->GetWarningMessages(set, extension->GetType());
952 EXPECT_TRUE(Contains(warnings, "Block parts of web pages"));
953 EXPECT_FALSE(Contains(warnings, "Access your data on all websites"));
955 // Now verify that declarativeWebRequest does not produce a message when host
956 // permissions do cover all hosts.
957 extension =
958 LoadManifest("permissions", "web_request_all_host_permissions.json");
959 set = extension->GetActivePermissions().get();
960 warnings = provider->GetWarningMessages(set, extension->GetType());
961 EXPECT_FALSE(Contains(warnings, "Block parts of web pages"));
962 EXPECT_TRUE(Contains(warnings, "Access your data on all websites"));
965 TEST(PermissionsTest, GetWarningMessages_Serial) {
966 scoped_refptr<Extension> extension =
967 LoadManifest("permissions", "serial.json");
969 EXPECT_TRUE(extension->is_platform_app());
970 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSerial));
971 std::vector<base::string16> warnings =
972 PermissionsData::GetPermissionMessageStrings(extension.get());
973 EXPECT_TRUE(
974 Contains(warnings, "Use serial devices attached to your computer"));
975 ASSERT_EQ(1u, warnings.size());
978 TEST(PermissionsTest, GetWarningMessages_Socket_AnyHost) {
979 ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV);
981 scoped_refptr<Extension> extension =
982 LoadManifest("permissions", "socket_any_host.json");
983 EXPECT_TRUE(extension->is_platform_app());
984 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket));
985 std::vector<base::string16> warnings =
986 PermissionsData::GetPermissionMessageStrings(extension.get());
987 EXPECT_EQ(1u, warnings.size());
988 EXPECT_TRUE(Contains(warnings, "Exchange data with any computer "
989 "on the local network or internet"));
992 TEST(PermissionsTest, GetWarningMessages_Socket_OneDomainTwoHostnames) {
993 ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV);
995 scoped_refptr<Extension> extension =
996 LoadManifest("permissions", "socket_one_domain_two_hostnames.json");
997 EXPECT_TRUE(extension->is_platform_app());
998 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket));
999 std::vector<base::string16> warnings =
1000 PermissionsData::GetPermissionMessageStrings(extension.get());
1002 // Verify the warnings, including support for unicode characters, the fact
1003 // that domain host warnings come before specific host warnings, and the fact
1004 // that domains and hostnames are in alphabetical order regardless of the
1005 // order in the manifest file.
1006 EXPECT_EQ(2u, warnings.size());
1007 if (warnings.size() > 0)
1008 EXPECT_EQ(warnings[0],
1009 base::UTF8ToUTF16("Exchange data with any computer in the domain "
1010 "example.org"));
1011 if (warnings.size() > 1)
1012 EXPECT_EQ(warnings[1],
1013 base::UTF8ToUTF16("Exchange data with the computers named: "
1014 "b\xC3\xA5r.example.com foo.example.com"));
1015 // "\xC3\xA5" = UTF-8 for lowercase A with ring above
1018 TEST(PermissionsTest, GetWarningMessages_Socket_TwoDomainsOneHostname) {
1019 ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV);
1021 scoped_refptr<Extension> extension =
1022 LoadManifest("permissions", "socket_two_domains_one_hostname.json");
1023 EXPECT_TRUE(extension->is_platform_app());
1024 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket));
1025 std::vector<base::string16> warnings =
1026 PermissionsData::GetPermissionMessageStrings(extension.get());
1028 // Verify the warnings, including the fact that domain host warnings come
1029 // before specific host warnings and the fact that domains and hostnames are
1030 // in alphabetical order regardless of the order in the manifest file.
1031 EXPECT_EQ(2u, warnings.size());
1032 if (warnings.size() > 0)
1033 EXPECT_EQ(warnings[0],
1034 base::UTF8ToUTF16("Exchange data with any computer in the "
1035 "domains: example.com foo.example.org"));
1036 if (warnings.size() > 1)
1037 EXPECT_EQ(warnings[1],
1038 base::UTF8ToUTF16("Exchange data with the computer named "
1039 "bar.example.org"));
1042 TEST(PermissionsTest, GetWarningMessages_PlatformApppHosts) {
1043 scoped_refptr<Extension> extension;
1045 extension = LoadManifest("permissions", "platform_app_hosts.json");
1046 EXPECT_TRUE(extension->is_platform_app());
1047 std::vector<base::string16> warnings =
1048 PermissionsData::GetPermissionMessageStrings(extension.get());
1049 ASSERT_EQ(0u, warnings.size());
1051 extension = LoadManifest("permissions", "platform_app_all_urls.json");
1052 EXPECT_TRUE(extension->is_platform_app());
1053 warnings = PermissionsData::GetPermissionMessageStrings(extension.get());
1054 ASSERT_EQ(0u, warnings.size());
1057 bool ShowsAllHostsWarning(const std::string& pattern) {
1058 scoped_refptr<Extension> extension =
1059 ExtensionBuilder()
1060 .SetManifest(DictionaryBuilder()
1061 .Set("name", "TLDWildCardTest")
1062 .Set("version", "0.1.0")
1063 .Set("permissions", ListBuilder().Append(pattern))
1064 .Build())
1065 .Build();
1067 std::vector<base::string16> warnings =
1068 PermissionsData::GetPermissionMessageStrings(extension);
1070 if (warnings.empty())
1071 return false;
1073 if (warnings[0] !=
1074 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS)) {
1075 return false;
1078 return true;
1081 TEST(PermissionsTest, GetWarningMessages_TLDWildcardTreatedAsAllHosts) {
1082 EXPECT_TRUE(ShowsAllHostsWarning("http://*.com/*")); // most popular.
1083 EXPECT_TRUE(ShowsAllHostsWarning("http://*.org/*")); // sanity check.
1084 EXPECT_TRUE(ShowsAllHostsWarning("http://*.co.uk/*")); // eTLD.
1085 EXPECT_TRUE(ShowsAllHostsWarning("http://*.de/*")); // foreign country tld.
1087 // We should still show the normal permissions (i.e., "Can access your data on
1088 // *.rdcronin.com") for things that are not TLDs.
1089 EXPECT_FALSE(ShowsAllHostsWarning("http://*.rdcronin.com/*"));
1091 // Pseudo-TLDs, like appspot.com, should not show all hosts.
1092 EXPECT_FALSE(ShowsAllHostsWarning("http://*.appspot.com/*"));
1094 // Non-TLDs should be likewise exempt.
1095 EXPECT_FALSE(ShowsAllHostsWarning("http://*.notarealtld/*"));
1097 // Our internal checks use "foo", so let's make sure we're not messing
1098 // something up with it.
1099 EXPECT_FALSE(ShowsAllHostsWarning("http://*.foo.com"));
1100 EXPECT_FALSE(ShowsAllHostsWarning("http://foo.com"));
1101 // This will fail if foo becomes a recognized TLD. Which could be soon.
1102 // Update as needed.
1103 EXPECT_FALSE(ShowsAllHostsWarning("http://*.foo"));
1106 TEST(PermissionsTest, GetDistinctHosts) {
1107 URLPatternSet explicit_hosts;
1108 std::set<std::string> expected;
1109 expected.insert("www.foo.com");
1110 expected.insert("www.bar.com");
1111 expected.insert("www.baz.com");
1114 SCOPED_TRACE("no dupes");
1116 // Simple list with no dupes.
1117 explicit_hosts.AddPattern(
1118 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path"));
1119 explicit_hosts.AddPattern(
1120 URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/path"));
1121 explicit_hosts.AddPattern(
1122 URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path"));
1123 EXPECT_EQ(expected,
1124 permission_message_util::GetDistinctHosts(
1125 explicit_hosts, true, true));
1129 SCOPED_TRACE("two dupes");
1131 // Add some dupes.
1132 explicit_hosts.AddPattern(
1133 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path"));
1134 explicit_hosts.AddPattern(
1135 URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path"));
1136 EXPECT_EQ(expected,
1137 permission_message_util::GetDistinctHosts(
1138 explicit_hosts, true, true));
1142 SCOPED_TRACE("schemes differ");
1144 // Add a pattern that differs only by scheme. This should be filtered out.
1145 explicit_hosts.AddPattern(
1146 URLPattern(URLPattern::SCHEME_HTTPS, "https://www.bar.com/path"));
1147 EXPECT_EQ(expected,
1148 permission_message_util::GetDistinctHosts(
1149 explicit_hosts, true, true));
1153 SCOPED_TRACE("paths differ");
1155 // Add some dupes by path.
1156 explicit_hosts.AddPattern(
1157 URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/pathypath"));
1158 EXPECT_EQ(expected,
1159 permission_message_util::GetDistinctHosts(
1160 explicit_hosts, true, true));
1164 SCOPED_TRACE("subdomains differ");
1166 // We don't do anything special for subdomains.
1167 explicit_hosts.AddPattern(
1168 URLPattern(URLPattern::SCHEME_HTTP, "http://monkey.www.bar.com/path"));
1169 explicit_hosts.AddPattern(
1170 URLPattern(URLPattern::SCHEME_HTTP, "http://bar.com/path"));
1172 expected.insert("monkey.www.bar.com");
1173 expected.insert("bar.com");
1175 EXPECT_EQ(expected,
1176 permission_message_util::GetDistinctHosts(
1177 explicit_hosts, true, true));
1181 SCOPED_TRACE("RCDs differ");
1183 // Now test for RCD uniquing.
1184 explicit_hosts.AddPattern(
1185 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path"));
1186 explicit_hosts.AddPattern(
1187 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
1188 explicit_hosts.AddPattern(
1189 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.de/path"));
1190 explicit_hosts.AddPattern(
1191 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca.us/path"));
1192 explicit_hosts.AddPattern(
1193 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path"));
1194 explicit_hosts.AddPattern(
1195 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com.my/path"));
1197 // This is an unknown RCD, which shouldn't be uniqued out.
1198 explicit_hosts.AddPattern(
1199 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path"));
1200 // But it should only occur once.
1201 explicit_hosts.AddPattern(
1202 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path"));
1204 expected.insert("www.foo.xyzzy");
1206 EXPECT_EQ(expected,
1207 permission_message_util::GetDistinctHosts(
1208 explicit_hosts, true, true));
1212 SCOPED_TRACE("wildcards");
1214 explicit_hosts.AddPattern(
1215 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*"));
1217 expected.insert("*.google.com");
1219 EXPECT_EQ(expected,
1220 permission_message_util::GetDistinctHosts(
1221 explicit_hosts, true, true));
1225 SCOPED_TRACE("scriptable hosts");
1227 APIPermissionSet empty_perms;
1228 explicit_hosts.ClearPatterns();
1229 URLPatternSet scriptable_hosts;
1230 expected.clear();
1232 explicit_hosts.AddPattern(
1233 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*"));
1234 scriptable_hosts.AddPattern(
1235 URLPattern(URLPattern::SCHEME_HTTP, "http://*.example.com/*"));
1237 expected.insert("*.google.com");
1238 expected.insert("*.example.com");
1240 scoped_refptr<PermissionSet> perm_set(new PermissionSet(
1241 empty_perms, ManifestPermissionSet(),
1242 explicit_hosts, scriptable_hosts));
1243 EXPECT_EQ(expected,
1244 permission_message_util::GetDistinctHosts(
1245 perm_set->effective_hosts(), true, true));
1249 // We don't display warnings for file URLs because they are off by default.
1250 SCOPED_TRACE("file urls");
1252 explicit_hosts.ClearPatterns();
1253 expected.clear();
1255 explicit_hosts.AddPattern(
1256 URLPattern(URLPattern::SCHEME_FILE, "file:///*"));
1258 EXPECT_EQ(expected,
1259 permission_message_util::GetDistinctHosts(
1260 explicit_hosts, true, true));
1264 TEST(PermissionsTest, GetDistinctHosts_ComIsBestRcd) {
1265 URLPatternSet explicit_hosts;
1266 explicit_hosts.AddPattern(
1267 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path"));
1268 explicit_hosts.AddPattern(
1269 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path"));
1270 explicit_hosts.AddPattern(
1271 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
1272 explicit_hosts.AddPattern(
1273 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path"));
1274 explicit_hosts.AddPattern(
1275 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path"));
1276 explicit_hosts.AddPattern(
1277 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path"));
1279 std::set<std::string> expected;
1280 expected.insert("www.foo.com");
1281 EXPECT_EQ(expected,
1282 permission_message_util::GetDistinctHosts(
1283 explicit_hosts, true, true));
1286 TEST(PermissionsTest, GetDistinctHosts_NetIs2ndBestRcd) {
1287 URLPatternSet explicit_hosts;
1288 explicit_hosts.AddPattern(
1289 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path"));
1290 explicit_hosts.AddPattern(
1291 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path"));
1292 explicit_hosts.AddPattern(
1293 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
1294 explicit_hosts.AddPattern(
1295 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path"));
1296 explicit_hosts.AddPattern(
1297 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path"));
1298 // No http://www.foo.com/path
1300 std::set<std::string> expected;
1301 expected.insert("www.foo.net");
1302 EXPECT_EQ(expected,
1303 permission_message_util::GetDistinctHosts(
1304 explicit_hosts, true, true));
1307 TEST(PermissionsTest, GetDistinctHosts_OrgIs3rdBestRcd) {
1308 URLPatternSet explicit_hosts;
1309 explicit_hosts.AddPattern(
1310 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path"));
1311 explicit_hosts.AddPattern(
1312 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path"));
1313 explicit_hosts.AddPattern(
1314 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
1315 // No http://www.foo.net/path
1316 explicit_hosts.AddPattern(
1317 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path"));
1318 // No http://www.foo.com/path
1320 std::set<std::string> expected;
1321 expected.insert("www.foo.org");
1322 EXPECT_EQ(expected,
1323 permission_message_util::GetDistinctHosts(
1324 explicit_hosts, true, true));
1327 TEST(PermissionsTest, GetDistinctHosts_FirstInListIs4thBestRcd) {
1328 URLPatternSet explicit_hosts;
1329 explicit_hosts.AddPattern(
1330 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path"));
1331 // No http://www.foo.org/path
1332 explicit_hosts.AddPattern(
1333 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
1334 // No http://www.foo.net/path
1335 explicit_hosts.AddPattern(
1336 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path"));
1337 // No http://www.foo.com/path
1339 std::set<std::string> expected;
1340 expected.insert("www.foo.ca");
1341 EXPECT_EQ(expected,
1342 permission_message_util::GetDistinctHosts(
1343 explicit_hosts, true, true));
1346 TEST(PermissionsTest, IsHostPrivilegeIncrease) {
1347 Manifest::Type type = Manifest::TYPE_EXTENSION;
1348 const PermissionMessageProvider* provider = PermissionMessageProvider::Get();
1349 ManifestPermissionSet empty_manifest_permissions;
1350 URLPatternSet elist1;
1351 URLPatternSet elist2;
1352 URLPatternSet slist1;
1353 URLPatternSet slist2;
1354 scoped_refptr<PermissionSet> set1;
1355 scoped_refptr<PermissionSet> set2;
1356 APIPermissionSet empty_perms;
1357 elist1.AddPattern(
1358 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path"));
1359 elist1.AddPattern(
1360 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path"));
1362 // Test that the host order does not matter.
1363 elist2.AddPattern(
1364 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path"));
1365 elist2.AddPattern(
1366 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path"));
1368 set1 = new PermissionSet(empty_perms, empty_manifest_permissions,
1369 elist1, slist1);
1370 set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
1371 elist2, slist2);
1373 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1, set2, type));
1374 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type));
1376 // Test that paths are ignored.
1377 elist2.ClearPatterns();
1378 elist2.AddPattern(
1379 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/*"));
1380 set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
1381 elist2, slist2);
1382 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1, set2, type));
1383 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type));
1385 // Test that RCDs are ignored.
1386 elist2.ClearPatterns();
1387 elist2.AddPattern(
1388 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/*"));
1389 set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
1390 elist2, slist2);
1391 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1, set2, type));
1392 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type));
1394 // Test that subdomain wildcards are handled properly.
1395 elist2.ClearPatterns();
1396 elist2.AddPattern(
1397 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com.hk/*"));
1398 set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
1399 elist2, slist2);
1400 EXPECT_TRUE(provider->IsPrivilegeIncrease(set1, set2, type));
1401 // TODO(jstritar): Does not match subdomains properly. http://crbug.com/65337
1402 // EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type));
1404 // Test that different domains count as different hosts.
1405 elist2.ClearPatterns();
1406 elist2.AddPattern(
1407 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path"));
1408 elist2.AddPattern(
1409 URLPattern(URLPattern::SCHEME_HTTP, "http://www.example.org/path"));
1410 set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
1411 elist2, slist2);
1412 EXPECT_TRUE(provider->IsPrivilegeIncrease(set1, set2, type));
1413 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type));
1415 // Test that different subdomains count as different hosts.
1416 elist2.ClearPatterns();
1417 elist2.AddPattern(
1418 URLPattern(URLPattern::SCHEME_HTTP, "http://mail.google.com/*"));
1419 set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
1420 elist2, slist2);
1421 EXPECT_TRUE(provider->IsPrivilegeIncrease(set1, set2, type));
1422 EXPECT_TRUE(provider->IsPrivilegeIncrease(set2, set1, type));
1424 // Test that platform apps do not have host permissions increases.
1425 type = Manifest::TYPE_PLATFORM_APP;
1426 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1, set2, type));
1427 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type));
1430 TEST(PermissionsTest, GetAPIsAsStrings) {
1431 APIPermissionSet apis;
1432 URLPatternSet empty_set;
1434 apis.insert(APIPermission::kProxy);
1435 apis.insert(APIPermission::kBackground);
1436 apis.insert(APIPermission::kNotification);
1437 apis.insert(APIPermission::kTab);
1439 scoped_refptr<PermissionSet> perm_set = new PermissionSet(
1440 apis, ManifestPermissionSet(), empty_set, empty_set);
1441 std::set<std::string> api_names = perm_set->GetAPIsAsStrings();
1443 // The result is correct if it has the same number of elements
1444 // and we can convert it back to the id set.
1445 EXPECT_EQ(4u, api_names.size());
1446 EXPECT_EQ(apis,
1447 PermissionsInfo::GetInstance()->GetAllByName(api_names));
1450 TEST(PermissionsTest, IsEmpty) {
1451 APIPermissionSet empty_apis;
1452 URLPatternSet empty_extent;
1454 scoped_refptr<PermissionSet> empty = new PermissionSet();
1455 EXPECT_TRUE(empty->IsEmpty());
1456 scoped_refptr<PermissionSet> perm_set;
1458 perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(),
1459 empty_extent, empty_extent);
1460 EXPECT_TRUE(perm_set->IsEmpty());
1462 APIPermissionSet non_empty_apis;
1463 non_empty_apis.insert(APIPermission::kBackground);
1464 perm_set = new PermissionSet(non_empty_apis, ManifestPermissionSet(),
1465 empty_extent, empty_extent);
1466 EXPECT_FALSE(perm_set->IsEmpty());
1468 // Try non standard host
1469 URLPatternSet non_empty_extent;
1470 AddPattern(&non_empty_extent, "http://www.google.com/*");
1472 perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(),
1473 non_empty_extent, empty_extent);
1474 EXPECT_FALSE(perm_set->IsEmpty());
1476 perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(),
1477 empty_extent, non_empty_extent);
1478 EXPECT_FALSE(perm_set->IsEmpty());
1481 TEST(PermissionsTest, ImpliedPermissions) {
1482 URLPatternSet empty_extent;
1483 APIPermissionSet apis;
1484 apis.insert(APIPermission::kFileBrowserHandler);
1485 EXPECT_EQ(1U, apis.size());
1487 scoped_refptr<PermissionSet> perm_set;
1488 perm_set = new PermissionSet(apis, ManifestPermissionSet(),
1489 empty_extent, empty_extent);
1490 EXPECT_EQ(2U, perm_set->apis().size());
1493 TEST(PermissionsTest, SyncFileSystemPermission) {
1494 scoped_refptr<Extension> extension = LoadManifest(
1495 "permissions", "sync_file_system.json");
1496 APIPermissionSet apis;
1497 apis.insert(APIPermission::kSyncFileSystem);
1498 EXPECT_TRUE(extension->is_platform_app());
1499 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSyncFileSystem));
1500 std::vector<base::string16> warnings =
1501 PermissionsData::GetPermissionMessageStrings(extension.get());
1502 EXPECT_TRUE(Contains(warnings, "Store data in your Google Drive account"));
1503 ASSERT_EQ(1u, warnings.size());
1506 // Make sure that we don't crash when we're trying to show the permissions
1507 // even though chrome://thumb (and everything that's not chrome://favicon with
1508 // a chrome:// scheme) is not a valid permission.
1509 // More details here: crbug/246314.
1510 TEST(PermissionsTest, ChromeURLs) {
1511 URLPatternSet allowed_hosts;
1512 allowed_hosts.AddPattern(
1513 URLPattern(URLPattern::SCHEME_ALL, "http://www.google.com/"));
1514 allowed_hosts.AddPattern(
1515 URLPattern(URLPattern::SCHEME_ALL, "chrome://favicon/"));
1516 allowed_hosts.AddPattern(
1517 URLPattern(URLPattern::SCHEME_ALL, "chrome://thumb/"));
1518 scoped_refptr<PermissionSet> permissions(
1519 new PermissionSet(APIPermissionSet(), ManifestPermissionSet(),
1520 allowed_hosts, URLPatternSet()));
1521 PermissionMessageProvider::Get()->
1522 GetPermissionMessages(permissions, Manifest::TYPE_EXTENSION);
1525 TEST(PermissionsTest, IsPrivilegeIncrease_DeclarativeWebRequest) {
1526 scoped_refptr<Extension> extension(
1527 LoadManifest("permissions", "permissions_all_urls.json"));
1528 scoped_refptr<const PermissionSet> permissions(
1529 extension->GetActivePermissions());
1531 scoped_refptr<Extension> extension_dwr(
1532 LoadManifest("permissions", "web_request_all_host_permissions.json"));
1533 scoped_refptr<const PermissionSet> permissions_dwr(
1534 extension_dwr->GetActivePermissions());
1536 EXPECT_FALSE(PermissionMessageProvider::Get()->
1537 IsPrivilegeIncrease(permissions.get(),
1538 permissions_dwr.get(),
1539 extension->GetType()));
1542 } // namespace extensions