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.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/permission_set.h"
16 #include "chrome/common/extensions/permissions/permissions_data.h"
17 #include "chrome/common/extensions/permissions/permissions_info.h"
18 #include "chrome/common/extensions/permissions/socket_permission.h"
19 #include "extensions/common/error_utils.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 using extension_test_util::LoadManifest
;
24 namespace extensions
{
28 static void AddPattern(URLPatternSet
* extent
, const std::string
& pattern
) {
29 int schemes
= URLPattern::SCHEME_ALL
;
30 extent
->AddPattern(URLPattern(schemes
, pattern
));
33 size_t IndexOf(const std::vector
<string16
>& warnings
,
34 const std::string
& warning
) {
35 for (size_t i
= 0; i
< warnings
.size(); ++i
) {
36 if (warnings
[i
] == ASCIIToUTF16(warning
))
40 return warnings
.size();
43 bool Contains(const std::vector
<string16
>& warnings
,
44 const std::string
& warning
) {
45 return IndexOf(warnings
, warning
) != warnings
.size();
51 TEST(PermissionsTest
, GetByID
) {
52 PermissionsInfo
* info
= PermissionsInfo::GetInstance();
53 APIPermissionSet apis
= info
->GetAll();
54 for (APIPermissionSet::const_iterator i
= apis
.begin();
55 i
!= apis
.end(); ++i
) {
56 EXPECT_EQ(i
->id(), i
->info()->id());
60 // Tests that GetByName works with normal permission names and aliases.
61 TEST(PermissionsTest
, GetByName
) {
62 PermissionsInfo
* info
= PermissionsInfo::GetInstance();
63 EXPECT_EQ(APIPermission::kTab
, info
->GetByName("tabs")->id());
64 EXPECT_EQ(APIPermission::kManagement
,
65 info
->GetByName("management")->id());
66 EXPECT_FALSE(info
->GetByName("alsdkfjasldkfj"));
69 TEST(PermissionsTest
, GetAll
) {
71 PermissionsInfo
* info
= PermissionsInfo::GetInstance();
72 APIPermissionSet apis
= info
->GetAll();
73 for (APIPermissionSet::const_iterator api
= apis
.begin();
74 api
!= apis
.end(); ++api
) {
75 // Make sure only the valid permission IDs get returned.
76 EXPECT_NE(APIPermission::kInvalid
, api
->id());
77 EXPECT_NE(APIPermission::kUnknown
, api
->id());
80 EXPECT_EQ(count
, info
->get_permission_count());
83 TEST(PermissionsTest
, GetAllByName
) {
84 std::set
<std::string
> names
;
85 names
.insert("background");
86 names
.insert("management");
88 // This is an alias of kTab
89 names
.insert("windows");
91 // This unknown name should get dropped.
92 names
.insert("sdlkfjasdlkfj");
94 APIPermissionSet expected
;
95 expected
.insert(APIPermission::kBackground
);
96 expected
.insert(APIPermission::kManagement
);
97 expected
.insert(APIPermission::kTab
);
100 PermissionsInfo::GetInstance()->GetAllByName(names
));
103 // Tests that the aliases are properly mapped.
104 TEST(PermissionsTest
, Aliases
) {
105 PermissionsInfo
* info
= PermissionsInfo::GetInstance();
106 // tabs: tabs, windows
107 std::string tabs_name
= "tabs";
108 EXPECT_EQ(tabs_name
, info
->GetByID(APIPermission::kTab
)->name());
109 EXPECT_EQ(APIPermission::kTab
, info
->GetByName("tabs")->id());
110 EXPECT_EQ(APIPermission::kTab
, info
->GetByName("windows")->id());
112 // unlimitedStorage: unlimitedStorage, unlimited_storage
113 std::string storage_name
= "unlimitedStorage";
114 EXPECT_EQ(storage_name
, info
->GetByID(
115 APIPermission::kUnlimitedStorage
)->name());
116 EXPECT_EQ(APIPermission::kUnlimitedStorage
,
117 info
->GetByName("unlimitedStorage")->id());
118 EXPECT_EQ(APIPermission::kUnlimitedStorage
,
119 info
->GetByName("unlimited_storage")->id());
122 TEST(PermissionsTest
, EffectiveHostPermissions
) {
123 scoped_refptr
<Extension
> extension
;
124 scoped_refptr
<const PermissionSet
> permissions
;
126 extension
= LoadManifest("effective_host_permissions", "empty.json");
127 permissions
= extension
->GetActivePermissions();
129 PermissionsData::GetEffectiveHostPermissions(extension
.get())
132 permissions
->HasEffectiveAccessToURL(GURL("http://www.google.com")));
133 EXPECT_FALSE(permissions
->HasEffectiveAccessToAllHosts());
135 extension
= LoadManifest("effective_host_permissions", "one_host.json");
136 permissions
= extension
->GetActivePermissions();
137 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(
138 GURL("http://www.google.com")));
139 EXPECT_FALSE(permissions
->HasEffectiveAccessToURL(
140 GURL("https://www.google.com")));
141 EXPECT_FALSE(permissions
->HasEffectiveAccessToAllHosts());
143 extension
= LoadManifest("effective_host_permissions",
144 "one_host_wildcard.json");
145 permissions
= extension
->GetActivePermissions();
146 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(GURL("http://google.com")));
147 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(
148 GURL("http://foo.google.com")));
149 EXPECT_FALSE(permissions
->HasEffectiveAccessToAllHosts());
151 extension
= LoadManifest("effective_host_permissions", "two_hosts.json");
152 permissions
= extension
->GetActivePermissions();
153 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(
154 GURL("http://www.google.com")));
155 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(
156 GURL("http://www.reddit.com")));
157 EXPECT_FALSE(permissions
->HasEffectiveAccessToAllHosts());
159 extension
= LoadManifest("effective_host_permissions",
160 "https_not_considered.json");
161 permissions
= extension
->GetActivePermissions();
162 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(GURL("http://google.com")));
163 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(GURL("https://google.com")));
164 EXPECT_FALSE(permissions
->HasEffectiveAccessToAllHosts());
166 extension
= LoadManifest("effective_host_permissions",
167 "two_content_scripts.json");
168 permissions
= extension
->GetActivePermissions();
169 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(GURL("http://google.com")));
170 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(
171 GURL("http://www.reddit.com")));
172 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(
173 GURL("http://news.ycombinator.com")));
174 EXPECT_FALSE(permissions
->HasEffectiveAccessToAllHosts());
176 extension
= LoadManifest("effective_host_permissions", "all_hosts.json");
177 permissions
= extension
->GetActivePermissions();
178 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(GURL("http://test/")));
179 EXPECT_FALSE(permissions
->HasEffectiveAccessToURL(GURL("https://test/")));
181 permissions
->HasEffectiveAccessToURL(GURL("http://www.google.com")));
182 EXPECT_TRUE(permissions
->HasEffectiveAccessToAllHosts());
184 extension
= LoadManifest("effective_host_permissions", "all_hosts2.json");
185 permissions
= extension
->GetActivePermissions();
186 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(GURL("http://test/")));
188 permissions
->HasEffectiveAccessToURL(GURL("http://www.google.com")));
189 EXPECT_TRUE(permissions
->HasEffectiveAccessToAllHosts());
191 extension
= LoadManifest("effective_host_permissions", "all_hosts3.json");
192 permissions
= extension
->GetActivePermissions();
193 EXPECT_FALSE(permissions
->HasEffectiveAccessToURL(GURL("http://test/")));
194 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(GURL("https://test/")));
196 permissions
->HasEffectiveAccessToURL(GURL("http://www.google.com")));
197 EXPECT_TRUE(permissions
->HasEffectiveAccessToAllHosts());
200 TEST(PermissionsTest
, ExplicitAccessToOrigin
) {
201 APIPermissionSet apis
;
202 URLPatternSet explicit_hosts
;
203 URLPatternSet scriptable_hosts
;
205 AddPattern(&explicit_hosts
, "http://*.google.com/*");
206 // The explicit host paths should get set to /*.
207 AddPattern(&explicit_hosts
, "http://www.example.com/a/particular/path/*");
209 scoped_refptr
<PermissionSet
> perm_set
= new PermissionSet(
210 apis
, explicit_hosts
, scriptable_hosts
);
211 ASSERT_TRUE(perm_set
->HasExplicitAccessToOrigin(
212 GURL("http://www.google.com/")));
213 ASSERT_TRUE(perm_set
->HasExplicitAccessToOrigin(
214 GURL("http://test.google.com/")));
215 ASSERT_TRUE(perm_set
->HasExplicitAccessToOrigin(
216 GURL("http://www.example.com")));
217 ASSERT_TRUE(perm_set
->HasEffectiveAccessToURL(
218 GURL("http://www.example.com")));
219 ASSERT_FALSE(perm_set
->HasExplicitAccessToOrigin(
220 GURL("http://test.example.com")));
223 TEST(PermissionsTest
, CreateUnion
) {
224 APIPermission
* permission
= NULL
;
226 APIPermissionSet apis1
;
227 APIPermissionSet apis2
;
228 APIPermissionSet expected_apis
;
230 URLPatternSet explicit_hosts1
;
231 URLPatternSet explicit_hosts2
;
232 URLPatternSet expected_explicit_hosts
;
234 URLPatternSet scriptable_hosts1
;
235 URLPatternSet scriptable_hosts2
;
236 URLPatternSet expected_scriptable_hosts
;
238 URLPatternSet effective_hosts
;
240 scoped_refptr
<PermissionSet
> set1
;
241 scoped_refptr
<PermissionSet
> set2
;
242 scoped_refptr
<PermissionSet
> union_set
;
244 const APIPermissionInfo
* permission_info
=
245 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket
);
246 permission
= permission_info
->CreateAPIPermission();
248 scoped_ptr
<base::ListValue
> value(new base::ListValue());
250 base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
251 value
->Append(base::Value::CreateStringValue("udp-bind::8080"));
252 value
->Append(base::Value::CreateStringValue("udp-send-to::8888"));
253 if (!permission
->FromValue(value
.get())) {
258 // Union with an empty set.
259 apis1
.insert(APIPermission::kTab
);
260 apis1
.insert(APIPermission::kBackground
);
261 apis1
.insert(permission
->Clone());
262 expected_apis
.insert(APIPermission::kTab
);
263 expected_apis
.insert(APIPermission::kBackground
);
264 expected_apis
.insert(permission
);
266 AddPattern(&explicit_hosts1
, "http://*.google.com/*");
267 AddPattern(&expected_explicit_hosts
, "http://*.google.com/*");
268 AddPattern(&effective_hosts
, "http://*.google.com/*");
270 set1
= new PermissionSet(apis1
, explicit_hosts1
, scriptable_hosts1
);
271 set2
= new PermissionSet(apis2
, explicit_hosts2
, scriptable_hosts2
);
272 union_set
= PermissionSet::CreateUnion(set1
.get(), set2
.get());
273 EXPECT_TRUE(set1
->Contains(*set2
.get()));
274 EXPECT_TRUE(set1
->Contains(*union_set
.get()));
275 EXPECT_FALSE(set2
->Contains(*set1
.get()));
276 EXPECT_FALSE(set2
->Contains(*union_set
.get()));
277 EXPECT_TRUE(union_set
->Contains(*set1
.get()));
278 EXPECT_TRUE(union_set
->Contains(*set2
.get()));
280 EXPECT_FALSE(union_set
->HasEffectiveFullAccess());
281 EXPECT_EQ(expected_apis
, union_set
->apis());
282 EXPECT_EQ(expected_explicit_hosts
, union_set
->explicit_hosts());
283 EXPECT_EQ(expected_scriptable_hosts
, union_set
->scriptable_hosts());
284 EXPECT_EQ(expected_explicit_hosts
, union_set
->effective_hosts());
286 // Now use a real second set.
287 apis2
.insert(APIPermission::kTab
);
288 apis2
.insert(APIPermission::kProxy
);
289 apis2
.insert(APIPermission::kClipboardWrite
);
290 apis2
.insert(APIPermission::kPlugin
);
292 permission
= permission_info
->CreateAPIPermission();
294 scoped_ptr
<base::ListValue
> value(new base::ListValue());
296 base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
297 value
->Append(base::Value::CreateStringValue("udp-send-to::8899"));
298 if (!permission
->FromValue(value
.get())) {
302 apis2
.insert(permission
);
304 expected_apis
.insert(APIPermission::kTab
);
305 expected_apis
.insert(APIPermission::kProxy
);
306 expected_apis
.insert(APIPermission::kClipboardWrite
);
307 expected_apis
.insert(APIPermission::kPlugin
);
309 permission
= permission_info
->CreateAPIPermission();
311 scoped_ptr
<base::ListValue
> value(new base::ListValue());
313 base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
314 value
->Append(base::Value::CreateStringValue("udp-bind::8080"));
315 value
->Append(base::Value::CreateStringValue("udp-send-to::8888"));
316 value
->Append(base::Value::CreateStringValue("udp-send-to::8899"));
317 if (!permission
->FromValue(value
.get())) {
321 // Insert a new permission socket permisssion which will replace the old one.
322 expected_apis
.insert(permission
);
324 AddPattern(&explicit_hosts2
, "http://*.example.com/*");
325 AddPattern(&scriptable_hosts2
, "http://*.google.com/*");
326 AddPattern(&expected_explicit_hosts
, "http://*.example.com/*");
327 AddPattern(&expected_scriptable_hosts
, "http://*.google.com/*");
329 URLPatternSet::CreateUnion(
330 explicit_hosts2
, scriptable_hosts2
, &effective_hosts
);
332 set2
= new PermissionSet(apis2
, explicit_hosts2
, scriptable_hosts2
);
333 union_set
= PermissionSet::CreateUnion(set1
.get(), set2
.get());
335 EXPECT_FALSE(set1
->Contains(*set2
.get()));
336 EXPECT_FALSE(set1
->Contains(*union_set
.get()));
337 EXPECT_FALSE(set2
->Contains(*set1
.get()));
338 EXPECT_FALSE(set2
->Contains(*union_set
.get()));
339 EXPECT_TRUE(union_set
->Contains(*set1
.get()));
340 EXPECT_TRUE(union_set
->Contains(*set2
.get()));
342 EXPECT_TRUE(union_set
->HasEffectiveFullAccess());
343 EXPECT_TRUE(union_set
->HasEffectiveAccessToAllHosts());
344 EXPECT_EQ(expected_apis
, union_set
->apis());
345 EXPECT_EQ(expected_explicit_hosts
, union_set
->explicit_hosts());
346 EXPECT_EQ(expected_scriptable_hosts
, union_set
->scriptable_hosts());
347 EXPECT_EQ(effective_hosts
, union_set
->effective_hosts());
350 TEST(PermissionsTest
, CreateIntersection
) {
351 APIPermission
* permission
= NULL
;
353 APIPermissionSet apis1
;
354 APIPermissionSet apis2
;
355 APIPermissionSet expected_apis
;
357 URLPatternSet explicit_hosts1
;
358 URLPatternSet explicit_hosts2
;
359 URLPatternSet expected_explicit_hosts
;
361 URLPatternSet scriptable_hosts1
;
362 URLPatternSet scriptable_hosts2
;
363 URLPatternSet expected_scriptable_hosts
;
365 URLPatternSet effective_hosts
;
367 scoped_refptr
<PermissionSet
> set1
;
368 scoped_refptr
<PermissionSet
> set2
;
369 scoped_refptr
<PermissionSet
> new_set
;
371 const APIPermissionInfo
* permission_info
=
372 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket
);
374 // Intersection with an empty set.
375 apis1
.insert(APIPermission::kTab
);
376 apis1
.insert(APIPermission::kBackground
);
377 permission
= permission_info
->CreateAPIPermission();
379 scoped_ptr
<base::ListValue
> value(new base::ListValue());
381 base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
382 value
->Append(base::Value::CreateStringValue("udp-bind::8080"));
383 value
->Append(base::Value::CreateStringValue("udp-send-to::8888"));
384 if (!permission
->FromValue(value
.get())) {
388 apis1
.insert(permission
);
390 AddPattern(&explicit_hosts1
, "http://*.google.com/*");
391 AddPattern(&scriptable_hosts1
, "http://www.reddit.com/*");
393 set1
= new PermissionSet(apis1
, explicit_hosts1
, scriptable_hosts1
);
394 set2
= new PermissionSet(apis2
, explicit_hosts2
, scriptable_hosts2
);
395 new_set
= PermissionSet::CreateIntersection(set1
.get(), set2
.get());
396 EXPECT_TRUE(set1
->Contains(*new_set
.get()));
397 EXPECT_TRUE(set2
->Contains(*new_set
.get()));
398 EXPECT_TRUE(set1
->Contains(*set2
.get()));
399 EXPECT_FALSE(set2
->Contains(*set1
.get()));
400 EXPECT_FALSE(new_set
->Contains(*set1
.get()));
401 EXPECT_TRUE(new_set
->Contains(*set2
.get()));
403 EXPECT_TRUE(new_set
->IsEmpty());
404 EXPECT_FALSE(new_set
->HasEffectiveFullAccess());
405 EXPECT_EQ(expected_apis
, new_set
->apis());
406 EXPECT_EQ(expected_explicit_hosts
, new_set
->explicit_hosts());
407 EXPECT_EQ(expected_scriptable_hosts
, new_set
->scriptable_hosts());
408 EXPECT_EQ(expected_explicit_hosts
, new_set
->effective_hosts());
410 // Now use a real second set.
411 apis2
.insert(APIPermission::kTab
);
412 apis2
.insert(APIPermission::kProxy
);
413 apis2
.insert(APIPermission::kClipboardWrite
);
414 apis2
.insert(APIPermission::kPlugin
);
415 permission
= permission_info
->CreateAPIPermission();
417 scoped_ptr
<base::ListValue
> value(new base::ListValue());
418 value
->Append(base::Value::CreateStringValue("udp-bind::8080"));
419 value
->Append(base::Value::CreateStringValue("udp-send-to::8888"));
420 value
->Append(base::Value::CreateStringValue("udp-send-to::8899"));
421 if (!permission
->FromValue(value
.get())) {
425 apis2
.insert(permission
);
427 expected_apis
.insert(APIPermission::kTab
);
428 permission
= permission_info
->CreateAPIPermission();
430 scoped_ptr
<base::ListValue
> value(new base::ListValue());
431 value
->Append(base::Value::CreateStringValue("udp-bind::8080"));
432 value
->Append(base::Value::CreateStringValue("udp-send-to::8888"));
433 if (!permission
->FromValue(value
.get())) {
437 expected_apis
.insert(permission
);
439 AddPattern(&explicit_hosts2
, "http://*.example.com/*");
440 AddPattern(&explicit_hosts2
, "http://*.google.com/*");
441 AddPattern(&scriptable_hosts2
, "http://*.google.com/*");
442 AddPattern(&expected_explicit_hosts
, "http://*.google.com/*");
444 effective_hosts
.ClearPatterns();
445 AddPattern(&effective_hosts
, "http://*.google.com/*");
447 set2
= new PermissionSet(apis2
, explicit_hosts2
, scriptable_hosts2
);
448 new_set
= PermissionSet::CreateIntersection(set1
.get(), set2
.get());
450 EXPECT_TRUE(set1
->Contains(*new_set
.get()));
451 EXPECT_TRUE(set2
->Contains(*new_set
.get()));
452 EXPECT_FALSE(set1
->Contains(*set2
.get()));
453 EXPECT_FALSE(set2
->Contains(*set1
.get()));
454 EXPECT_FALSE(new_set
->Contains(*set1
.get()));
455 EXPECT_FALSE(new_set
->Contains(*set2
.get()));
457 EXPECT_FALSE(new_set
->HasEffectiveFullAccess());
458 EXPECT_FALSE(new_set
->HasEffectiveAccessToAllHosts());
459 EXPECT_EQ(expected_apis
, new_set
->apis());
460 EXPECT_EQ(expected_explicit_hosts
, new_set
->explicit_hosts());
461 EXPECT_EQ(expected_scriptable_hosts
, new_set
->scriptable_hosts());
462 EXPECT_EQ(effective_hosts
, new_set
->effective_hosts());
465 TEST(PermissionsTest
, CreateDifference
) {
466 APIPermission
* permission
= NULL
;
468 APIPermissionSet apis1
;
469 APIPermissionSet apis2
;
470 APIPermissionSet expected_apis
;
472 URLPatternSet explicit_hosts1
;
473 URLPatternSet explicit_hosts2
;
474 URLPatternSet expected_explicit_hosts
;
476 URLPatternSet scriptable_hosts1
;
477 URLPatternSet scriptable_hosts2
;
478 URLPatternSet expected_scriptable_hosts
;
480 URLPatternSet effective_hosts
;
482 scoped_refptr
<PermissionSet
> set1
;
483 scoped_refptr
<PermissionSet
> set2
;
484 scoped_refptr
<PermissionSet
> new_set
;
486 const APIPermissionInfo
* permission_info
=
487 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket
);
489 // Difference with an empty set.
490 apis1
.insert(APIPermission::kTab
);
491 apis1
.insert(APIPermission::kBackground
);
492 permission
= permission_info
->CreateAPIPermission();
494 scoped_ptr
<base::ListValue
> value(new base::ListValue());
496 base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
497 value
->Append(base::Value::CreateStringValue("udp-bind::8080"));
498 value
->Append(base::Value::CreateStringValue("udp-send-to::8888"));
499 if (!permission
->FromValue(value
.get())) {
503 apis1
.insert(permission
);
505 AddPattern(&explicit_hosts1
, "http://*.google.com/*");
506 AddPattern(&scriptable_hosts1
, "http://www.reddit.com/*");
508 set1
= new PermissionSet(apis1
, explicit_hosts1
, scriptable_hosts1
);
509 set2
= new PermissionSet(apis2
, explicit_hosts2
, scriptable_hosts2
);
510 new_set
= PermissionSet::CreateDifference(set1
.get(), set2
.get());
511 EXPECT_EQ(*set1
.get(), *new_set
.get());
513 // Now use a real second set.
514 apis2
.insert(APIPermission::kTab
);
515 apis2
.insert(APIPermission::kProxy
);
516 apis2
.insert(APIPermission::kClipboardWrite
);
517 apis2
.insert(APIPermission::kPlugin
);
518 permission
= permission_info
->CreateAPIPermission();
520 scoped_ptr
<base::ListValue
> value(new base::ListValue());
522 base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
523 value
->Append(base::Value::CreateStringValue("udp-send-to::8899"));
524 if (!permission
->FromValue(value
.get())) {
528 apis2
.insert(permission
);
530 expected_apis
.insert(APIPermission::kBackground
);
531 permission
= permission_info
->CreateAPIPermission();
533 scoped_ptr
<base::ListValue
> value(new base::ListValue());
534 value
->Append(base::Value::CreateStringValue("udp-bind::8080"));
535 value
->Append(base::Value::CreateStringValue("udp-send-to::8888"));
536 if (!permission
->FromValue(value
.get())) {
540 expected_apis
.insert(permission
);
542 AddPattern(&explicit_hosts2
, "http://*.example.com/*");
543 AddPattern(&explicit_hosts2
, "http://*.google.com/*");
544 AddPattern(&scriptable_hosts2
, "http://*.google.com/*");
545 AddPattern(&expected_scriptable_hosts
, "http://www.reddit.com/*");
547 effective_hosts
.ClearPatterns();
548 AddPattern(&effective_hosts
, "http://www.reddit.com/*");
550 set2
= new PermissionSet(apis2
, explicit_hosts2
, scriptable_hosts2
);
551 new_set
= PermissionSet::CreateDifference(set1
.get(), set2
.get());
553 EXPECT_TRUE(set1
->Contains(*new_set
.get()));
554 EXPECT_FALSE(set2
->Contains(*new_set
.get()));
556 EXPECT_FALSE(new_set
->HasEffectiveFullAccess());
557 EXPECT_FALSE(new_set
->HasEffectiveAccessToAllHosts());
558 EXPECT_EQ(expected_apis
, new_set
->apis());
559 EXPECT_EQ(expected_explicit_hosts
, new_set
->explicit_hosts());
560 EXPECT_EQ(expected_scriptable_hosts
, new_set
->scriptable_hosts());
561 EXPECT_EQ(effective_hosts
, new_set
->effective_hosts());
563 // |set3| = |set1| - |set2| --> |set3| intersect |set2| == empty_set
564 set1
= PermissionSet::CreateIntersection(new_set
.get(), set2
.get());
565 EXPECT_TRUE(set1
->IsEmpty());
568 TEST(PermissionsTest
, HasLessPrivilegesThan
) {
570 const char* base_name
;
571 bool expect_increase
;
573 { "allhosts1", false }, // all -> all
574 { "allhosts2", false }, // all -> one
575 { "allhosts3", true }, // one -> all
576 { "hosts1", false }, // http://a,http://b -> http://a,http://b
577 { "hosts2", true }, // http://a,http://b -> https://a,http://*.b
578 { "hosts3", false }, // http://a,http://b -> http://a
579 { "hosts4", true }, // http://a -> http://a,http://b
580 { "hosts5", false }, // http://a,b,c -> http://a,b,c + https://a,b,c
581 { "hosts6", false }, // http://a.com -> http://a.com + http://a.co.uk
582 { "permissions1", false }, // tabs -> tabs
583 { "permissions2", true }, // tabs -> tabs,bookmarks
584 { "permissions3", true }, // http://a -> http://a,tabs
585 { "permissions5", true }, // bookmarks -> bookmarks,history
586 { "equivalent_warnings", false }, // tabs --> tabs, webNavigation
587 #if !defined(OS_CHROMEOS) // plugins aren't allowed in ChromeOS
588 { "permissions4", false }, // plugin -> plugin,tabs
589 { "plugin1", false }, // plugin -> plugin
590 { "plugin2", false }, // plugin -> none
591 { "plugin3", true }, // none -> plugin
593 { "storage", false }, // none -> storage
594 { "notifications", false }, // none -> notifications
595 { "platformapp1", false }, // host permissions for platform apps
596 { "platformapp2", true }, // API permissions for platform apps
597 { "media_galleries1", true }, // read|all -> copyTo|all
598 { "media_galleries2", true }, // read|all -> read|copyTo|all
599 { "media_galleries3", true }, // all -> copyTo|all
600 { "media_galleries4", false }, // read|all -> all
601 { "media_galleries5", false }, // read|copyTo|all -> read|all
602 { "media_galleries6", false }, // read|all -> read|all
605 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(kTests
); ++i
) {
606 scoped_refptr
<Extension
> old_extension(
607 LoadManifest("allow_silent_upgrade",
608 std::string(kTests
[i
].base_name
) + "_old.json"));
609 scoped_refptr
<Extension
> new_extension(
610 LoadManifest("allow_silent_upgrade",
611 std::string(kTests
[i
].base_name
) + "_new.json"));
613 EXPECT_TRUE(new_extension
.get()) << kTests
[i
].base_name
<< "_new.json";
614 if (!new_extension
.get())
617 scoped_refptr
<const PermissionSet
> old_p(
618 old_extension
->GetActivePermissions());
619 scoped_refptr
<const PermissionSet
> new_p(
620 new_extension
->GetActivePermissions());
621 Manifest::Type extension_type
= old_extension
->GetType();
623 EXPECT_EQ(kTests
[i
].expect_increase
,
624 old_p
->HasLessPrivilegesThan(new_p
.get(), extension_type
))
625 << kTests
[i
].base_name
;
629 TEST(PermissionsTest
, PermissionMessages
) {
630 // Ensure that all permissions that needs to show install UI actually have
631 // strings associated with them.
632 APIPermissionSet skip
;
634 // These are considered "nuisance" or "trivial" permissions that don't need
636 skip
.insert(APIPermission::kActiveTab
);
637 skip
.insert(APIPermission::kAdView
);
638 skip
.insert(APIPermission::kAlarms
);
639 skip
.insert(APIPermission::kAppCurrentWindowInternal
);
640 skip
.insert(APIPermission::kAppRuntime
);
641 skip
.insert(APIPermission::kAppWindow
);
642 skip
.insert(APIPermission::kAudio
);
643 skip
.insert(APIPermission::kBrowsingData
);
644 skip
.insert(APIPermission::kContextMenus
);
645 skip
.insert(APIPermission::kDiagnostics
);
646 skip
.insert(APIPermission::kDownloadsShelf
);
647 skip
.insert(APIPermission::kFontSettings
);
648 skip
.insert(APIPermission::kFullscreen
);
649 skip
.insert(APIPermission::kIdle
);
650 skip
.insert(APIPermission::kLogPrivate
);
651 skip
.insert(APIPermission::kNotification
);
652 skip
.insert(APIPermission::kPointerLock
);
653 skip
.insert(APIPermission::kPower
);
654 skip
.insert(APIPermission::kPushMessaging
);
655 skip
.insert(APIPermission::kScreensaver
);
656 skip
.insert(APIPermission::kSessions
);
657 skip
.insert(APIPermission::kStorage
);
658 skip
.insert(APIPermission::kSystemCpu
);
659 skip
.insert(APIPermission::kSystemDisplay
);
660 skip
.insert(APIPermission::kSystemMemory
);
661 skip
.insert(APIPermission::kSystemStorage
);
662 skip
.insert(APIPermission::kTts
);
663 skip
.insert(APIPermission::kUnlimitedStorage
);
664 skip
.insert(APIPermission::kWebView
);
666 // TODO(erikkay) add a string for this permission.
667 skip
.insert(APIPermission::kBackground
);
669 skip
.insert(APIPermission::kClipboardWrite
);
671 // The cookie permission does nothing unless you have associated host
673 skip
.insert(APIPermission::kCookie
);
675 // These are warned as part of host permission checks.
676 skip
.insert(APIPermission::kDeclarativeContent
);
677 skip
.insert(APIPermission::kPageCapture
);
678 skip
.insert(APIPermission::kProxy
);
679 skip
.insert(APIPermission::kTabCapture
);
680 skip
.insert(APIPermission::kWebRequest
);
681 skip
.insert(APIPermission::kWebRequestBlocking
);
683 // This permission requires explicit user action (context menu handler)
684 // so we won't prompt for it for now.
685 skip
.insert(APIPermission::kFileBrowserHandler
);
687 // These permissions require explicit user action (configuration dialog)
688 // so we don't prompt for them at install time.
689 skip
.insert(APIPermission::kMediaGalleries
);
691 // If you've turned on the experimental command-line flag, we don't need
692 // to warn you further.
693 skip
.insert(APIPermission::kExperimental
);
695 // The Identity API has its own server-driven permission prompts.
696 skip
.insert(APIPermission::kIdentity
);
698 // These are private.
699 skip
.insert(APIPermission::kAutoTestPrivate
);
700 skip
.insert(APIPermission::kBookmarkManagerPrivate
);
701 skip
.insert(APIPermission::kBrailleDisplayPrivate
);
702 skip
.insert(APIPermission::kChromeosInfoPrivate
);
703 skip
.insert(APIPermission::kCloudPrintPrivate
);
704 skip
.insert(APIPermission::kCommandLinePrivate
);
705 skip
.insert(APIPermission::kDeveloperPrivate
);
706 skip
.insert(APIPermission::kDial
);
707 skip
.insert(APIPermission::kDownloadsInternal
);
708 skip
.insert(APIPermission::kEchoPrivate
);
709 skip
.insert(APIPermission::kEnterprisePlatformKeysPrivate
);
710 skip
.insert(APIPermission::kFeedbackPrivate
);
711 skip
.insert(APIPermission::kFileBrowserHandlerInternal
);
712 skip
.insert(APIPermission::kFileBrowserPrivate
);
713 skip
.insert(APIPermission::kIdentityPrivate
);
714 skip
.insert(APIPermission::kInfobars
);
715 skip
.insert(APIPermission::kInputMethodPrivate
);
716 skip
.insert(APIPermission::kMediaGalleriesPrivate
);
717 skip
.insert(APIPermission::kMediaPlayerPrivate
);
718 skip
.insert(APIPermission::kMetricsPrivate
);
719 skip
.insert(APIPermission::kMDns
);
720 skip
.insert(APIPermission::kPreferencesPrivate
);
721 skip
.insert(APIPermission::kRecoveryPrivate
);
722 skip
.insert(APIPermission::kRtcPrivate
);
723 skip
.insert(APIPermission::kStreamsPrivate
);
724 skip
.insert(APIPermission::kSystemPrivate
);
725 skip
.insert(APIPermission::kTerminalPrivate
);
726 skip
.insert(APIPermission::kVirtualKeyboardPrivate
);
727 skip
.insert(APIPermission::kWallpaperPrivate
);
728 skip
.insert(APIPermission::kWebRequestInternal
);
729 skip
.insert(APIPermission::kWebstorePrivate
);
731 // Warned as part of host permissions.
732 skip
.insert(APIPermission::kDevtools
);
735 skip
.insert(APIPermission::kBluetooth
);
736 skip
.insert(APIPermission::kFileSystem
);
737 skip
.insert(APIPermission::kFileSystemRetainEntries
);
738 skip
.insert(APIPermission::kSocket
);
739 skip
.insert(APIPermission::kSocketsUdp
);
740 skip
.insert(APIPermission::kUsbDevice
);
742 PermissionsInfo
* info
= PermissionsInfo::GetInstance();
743 APIPermissionSet permissions
= info
->GetAll();
744 for (APIPermissionSet::const_iterator i
= permissions
.begin();
745 i
!= permissions
.end(); ++i
) {
746 const APIPermissionInfo
* permission_info
= i
->info();
747 EXPECT_TRUE(permission_info
!= NULL
);
749 // Always skip permissions that cannot be in the manifest.
750 scoped_ptr
<const APIPermission
> permission(
751 permission_info
->CreateAPIPermission());
752 if (permission
->ManifestEntryForbidden())
755 if (skip
.count(i
->id())) {
756 EXPECT_EQ(PermissionMessage::kNone
, permission_info
->message_id())
757 << "unexpected message_id for " << permission_info
->name();
759 EXPECT_NE(PermissionMessage::kNone
, permission_info
->message_id())
760 << "missing message_id for " << permission_info
->name();
765 TEST(PermissionsTest
, FileSystemPermissionMessages
) {
766 APIPermissionSet api_permissions
;
767 api_permissions
.insert(APIPermission::kFileSystemWrite
);
768 api_permissions
.insert(APIPermission::kFileSystemDirectory
);
769 scoped_refptr
<PermissionSet
> permissions(
770 new PermissionSet(api_permissions
, URLPatternSet(), URLPatternSet()));
771 PermissionMessages messages
=
772 permissions
->GetPermissionMessages(Manifest::TYPE_PLATFORM_APP
);
773 ASSERT_EQ(2u, messages
.size());
774 std::sort(messages
.begin(), messages
.end());
775 std::set
<PermissionMessage::ID
> ids
;
776 for (PermissionMessages::const_iterator it
= messages
.begin();
777 it
!= messages
.end(); ++it
) {
778 ids
.insert(it
->id());
780 EXPECT_TRUE(ContainsKey(ids
, PermissionMessage::kFileSystemDirectory
));
781 EXPECT_TRUE(ContainsKey(ids
, PermissionMessage::kFileSystemWrite
));
784 TEST(PermissionsTest
, HiddenFileSystemPermissionMessages
) {
785 APIPermissionSet api_permissions
;
786 api_permissions
.insert(APIPermission::kFileSystemWrite
);
787 api_permissions
.insert(APIPermission::kFileSystemDirectory
);
788 api_permissions
.insert(APIPermission::kFileSystemWriteDirectory
);
789 scoped_refptr
<PermissionSet
> permissions(
790 new PermissionSet(api_permissions
, URLPatternSet(), URLPatternSet()));
791 PermissionMessages messages
=
792 permissions
->GetPermissionMessages(Manifest::TYPE_PLATFORM_APP
);
793 ASSERT_EQ(1u, messages
.size());
794 EXPECT_EQ(PermissionMessage::kFileSystemWriteDirectory
, messages
[0].id());
797 TEST(PermissionsTest
, MergedFileSystemPermissionComparison
) {
798 APIPermissionSet write_api_permissions
;
799 write_api_permissions
.insert(APIPermission::kFileSystemWrite
);
800 scoped_refptr
<PermissionSet
> write_permissions(new PermissionSet(
801 write_api_permissions
, URLPatternSet(), URLPatternSet()));
803 APIPermissionSet directory_api_permissions
;
804 directory_api_permissions
.insert(APIPermission::kFileSystemDirectory
);
805 scoped_refptr
<PermissionSet
> directory_permissions(new PermissionSet(
806 directory_api_permissions
, URLPatternSet(), URLPatternSet()));
808 APIPermissionSet write_directory_api_permissions
;
809 write_directory_api_permissions
.insert(
810 APIPermission::kFileSystemWriteDirectory
);
811 scoped_refptr
<PermissionSet
> write_directory_permissions(new PermissionSet(
812 write_directory_api_permissions
, URLPatternSet(), URLPatternSet()));
814 EXPECT_FALSE(write_directory_permissions
->HasLessPrivilegesThan(
815 write_permissions
, Manifest::TYPE_PLATFORM_APP
));
816 EXPECT_FALSE(write_directory_permissions
->HasLessPrivilegesThan(
817 directory_permissions
, Manifest::TYPE_PLATFORM_APP
));
818 EXPECT_TRUE(write_permissions
->HasLessPrivilegesThan(
819 directory_permissions
, Manifest::TYPE_PLATFORM_APP
));
820 EXPECT_TRUE(write_permissions
->HasLessPrivilegesThan(
821 write_directory_permissions
, Manifest::TYPE_PLATFORM_APP
));
822 EXPECT_TRUE(directory_permissions
->HasLessPrivilegesThan(
823 write_permissions
, Manifest::TYPE_PLATFORM_APP
));
824 EXPECT_TRUE(directory_permissions
->HasLessPrivilegesThan(
825 write_directory_permissions
, Manifest::TYPE_PLATFORM_APP
));
828 TEST(PermissionsTest
, GetWarningMessages_ManyHosts
) {
829 scoped_refptr
<Extension
> extension
;
831 extension
= LoadManifest("permissions", "many-hosts.json");
832 std::vector
<string16
> warnings
=
833 PermissionsData::GetPermissionMessageStrings(extension
.get());
834 ASSERT_EQ(1u, warnings
.size());
835 EXPECT_EQ("Access your data on encrypted.google.com and www.google.com",
836 UTF16ToUTF8(warnings
[0]));
839 TEST(PermissionsTest
, GetWarningMessages_Plugins
) {
840 scoped_refptr
<Extension
> extension
;
841 scoped_refptr
<PermissionSet
> permissions
;
843 extension
= LoadManifest("permissions", "plugins.json");
844 std::vector
<string16
> warnings
=
845 PermissionsData::GetPermissionMessageStrings(extension
.get());
846 // We don't parse the plugins key on Chrome OS, so it should not ask for any
848 #if defined(OS_CHROMEOS)
849 ASSERT_EQ(0u, warnings
.size());
851 ASSERT_EQ(1u, warnings
.size());
852 EXPECT_EQ("Access all data on your computer and the websites you visit",
853 UTF16ToUTF8(warnings
[0]));
857 TEST(PermissionsTest
, GetWarningMessages_AudioVideo
) {
858 // Both audio and video present.
859 scoped_refptr
<Extension
> extension
=
860 LoadManifest("permissions", "audio-video.json");
862 const_cast<PermissionSet
*>(
863 extension
->GetActivePermissions().get());
864 std::vector
<string16
> warnings
=
865 set
->GetWarningMessages(extension
->GetType());
866 EXPECT_FALSE(Contains(warnings
, "Use your microphone"));
867 EXPECT_FALSE(Contains(warnings
, "Use your camera"));
868 EXPECT_TRUE(Contains(warnings
, "Use your microphone and camera"));
869 size_t combined_index
= IndexOf(warnings
, "Use your microphone and camera");
870 size_t combined_size
= warnings
.size();
872 // Just audio present.
873 set
->apis_
.erase(APIPermission::kVideoCapture
);
874 warnings
= set
->GetWarningMessages(extension
->GetType());
875 EXPECT_EQ(combined_size
, warnings
.size());
876 EXPECT_EQ(combined_index
, IndexOf(warnings
, "Use your microphone"));
877 EXPECT_FALSE(Contains(warnings
, "Use your camera"));
878 EXPECT_FALSE(Contains(warnings
, "Use your microphone and camera"));
880 // Just video present.
881 set
->apis_
.erase(APIPermission::kAudioCapture
);
882 set
->apis_
.insert(APIPermission::kVideoCapture
);
883 warnings
= set
->GetWarningMessages(extension
->GetType());
884 EXPECT_EQ(combined_size
, warnings
.size());
885 EXPECT_FALSE(Contains(warnings
, "Use your microphone"));
886 EXPECT_FALSE(Contains(warnings
, "Use your microphone and camera"));
887 EXPECT_TRUE(Contains(warnings
, "Use your camera"));
890 TEST(PermissionsTest
, GetWarningMessages_DeclarativeWebRequest
) {
891 // Test that if the declarativeWebRequest permission is present
892 // in combination with all hosts permission, then only the warning
893 // for host permissions is shown, because that covers the use of
894 // declarativeWebRequest.
896 // Until Declarative Web Request is in stable, let's make sure it is enabled
897 // on the current channel.
898 ScopedCurrentChannel
sc(chrome::VersionInfo::CHANNEL_CANARY
);
900 // First verify that declarativeWebRequest produces a message when host
901 // permissions do not cover all hosts.
902 scoped_refptr
<Extension
> extension
=
903 LoadManifest("permissions", "web_request_com_host_permissions.json");
904 const PermissionSet
* set
= extension
->GetActivePermissions().get();
905 std::vector
<string16
> warnings
=
906 set
->GetWarningMessages(extension
->GetType());
907 EXPECT_TRUE(Contains(warnings
, "Block parts of web pages"));
908 EXPECT_FALSE(Contains(warnings
, "Access your data on all websites"));
910 // Now verify that declarativeWebRequest does not produce a message when host
911 // permissions do cover all hosts.
913 LoadManifest("permissions", "web_request_all_host_permissions.json");
914 set
= extension
->GetActivePermissions().get();
915 warnings
= set
->GetWarningMessages(extension
->GetType());
916 EXPECT_FALSE(Contains(warnings
, "Block parts of web pages"));
917 EXPECT_TRUE(Contains(warnings
, "Access your data on all websites"));
920 TEST(PermissionsTest
, GetWarningMessages_Serial
) {
921 scoped_refptr
<Extension
> extension
=
922 LoadManifest("permissions", "serial.json");
924 EXPECT_TRUE(extension
->is_platform_app());
925 EXPECT_TRUE(extension
->HasAPIPermission(APIPermission::kSerial
));
926 std::vector
<string16
> warnings
=
927 PermissionsData::GetPermissionMessageStrings(extension
.get());
929 Contains(warnings
, "Use serial devices attached to your computer"));
930 ASSERT_EQ(1u, warnings
.size());
933 TEST(PermissionsTest
, GetWarningMessages_Socket_AnyHost
) {
934 ScopedCurrentChannel
channel(chrome::VersionInfo::CHANNEL_DEV
);
936 scoped_refptr
<Extension
> extension
=
937 LoadManifest("permissions", "socket_any_host.json");
938 EXPECT_TRUE(extension
->is_platform_app());
939 EXPECT_TRUE(extension
->HasAPIPermission(APIPermission::kSocket
));
940 std::vector
<string16
> warnings
=
941 PermissionsData::GetPermissionMessageStrings(extension
.get());
942 EXPECT_EQ(1u, warnings
.size());
943 EXPECT_TRUE(Contains(warnings
, "Exchange data with any computer "
944 "on the local network or internet"));
947 TEST(PermissionsTest
, GetWarningMessages_Socket_OneDomainTwoHostnames
) {
948 ScopedCurrentChannel
channel(chrome::VersionInfo::CHANNEL_DEV
);
950 scoped_refptr
<Extension
> extension
=
951 LoadManifest("permissions", "socket_one_domain_two_hostnames.json");
952 EXPECT_TRUE(extension
->is_platform_app());
953 EXPECT_TRUE(extension
->HasAPIPermission(APIPermission::kSocket
));
954 std::vector
<string16
> warnings
=
955 PermissionsData::GetPermissionMessageStrings(extension
.get());
957 // Verify the warnings, including support for unicode characters, the fact
958 // that domain host warnings come before specific host warnings, and the fact
959 // that domains and hostnames are in alphabetical order regardless of the
960 // order in the manifest file.
961 EXPECT_EQ(2u, warnings
.size());
962 if (warnings
.size() > 0)
963 EXPECT_EQ(warnings
[0],
964 UTF8ToUTF16("Exchange data with any computer in the domain "
966 if (warnings
.size() > 1)
967 EXPECT_EQ(warnings
[1],
968 UTF8ToUTF16("Exchange data with the computers named: "
969 "b\xC3\xA5r.example.com foo.example.com"));
970 // "\xC3\xA5" = UTF-8 for lowercase A with ring above
973 TEST(PermissionsTest
, GetWarningMessages_Socket_TwoDomainsOneHostname
) {
974 ScopedCurrentChannel
channel(chrome::VersionInfo::CHANNEL_DEV
);
976 scoped_refptr
<Extension
> extension
=
977 LoadManifest("permissions", "socket_two_domains_one_hostname.json");
978 EXPECT_TRUE(extension
->is_platform_app());
979 EXPECT_TRUE(extension
->HasAPIPermission(APIPermission::kSocket
));
980 std::vector
<string16
> warnings
=
981 PermissionsData::GetPermissionMessageStrings(extension
.get());
983 // Verify the warnings, including the fact that domain host warnings come
984 // before specific host warnings and the fact that domains and hostnames are
985 // in alphabetical order regardless of the order in the manifest file.
986 EXPECT_EQ(2u, warnings
.size());
987 if (warnings
.size() > 0)
988 EXPECT_EQ(warnings
[0],
989 UTF8ToUTF16("Exchange data with any computer in the domains: "
990 "example.com foo.example.org"));
991 if (warnings
.size() > 1)
992 EXPECT_EQ(warnings
[1],
993 UTF8ToUTF16("Exchange data with the computer named "
997 TEST(PermissionsTest
, GetWarningMessages_PlatformApppHosts
) {
998 scoped_refptr
<Extension
> extension
;
1000 extension
= LoadManifest("permissions", "platform_app_hosts.json");
1001 EXPECT_TRUE(extension
->is_platform_app());
1002 std::vector
<string16
> warnings
=
1003 PermissionsData::GetPermissionMessageStrings(extension
.get());
1004 ASSERT_EQ(0u, warnings
.size());
1006 extension
= LoadManifest("permissions", "platform_app_all_urls.json");
1007 EXPECT_TRUE(extension
->is_platform_app());
1008 warnings
= PermissionsData::GetPermissionMessageStrings(extension
.get());
1009 ASSERT_EQ(0u, warnings
.size());
1012 TEST(PermissionsTest
, GetDistinctHostsForDisplay
) {
1013 scoped_refptr
<PermissionSet
> perm_set
;
1014 APIPermissionSet empty_perms
;
1015 std::set
<std::string
> expected
;
1016 expected
.insert("www.foo.com");
1017 expected
.insert("www.bar.com");
1018 expected
.insert("www.baz.com");
1019 URLPatternSet explicit_hosts
;
1020 URLPatternSet scriptable_hosts
;
1023 SCOPED_TRACE("no dupes");
1025 // Simple list with no dupes.
1026 explicit_hosts
.AddPattern(
1027 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.com/path"));
1028 explicit_hosts
.AddPattern(
1029 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.bar.com/path"));
1030 explicit_hosts
.AddPattern(
1031 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.baz.com/path"));
1032 perm_set
= new PermissionSet(
1033 empty_perms
, explicit_hosts
, scriptable_hosts
);
1034 EXPECT_EQ(expected
, perm_set
->GetDistinctHostsForDisplay());
1038 SCOPED_TRACE("two dupes");
1041 explicit_hosts
.AddPattern(
1042 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.com/path"));
1043 explicit_hosts
.AddPattern(
1044 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.baz.com/path"));
1045 perm_set
= new PermissionSet(
1046 empty_perms
, explicit_hosts
, scriptable_hosts
);
1047 EXPECT_EQ(expected
, perm_set
->GetDistinctHostsForDisplay());
1051 SCOPED_TRACE("schemes differ");
1053 // Add a pattern that differs only by scheme. This should be filtered out.
1054 explicit_hosts
.AddPattern(
1055 URLPattern(URLPattern::SCHEME_HTTPS
, "https://www.bar.com/path"));
1056 perm_set
= new PermissionSet(
1057 empty_perms
, explicit_hosts
, scriptable_hosts
);
1058 EXPECT_EQ(expected
, perm_set
->GetDistinctHostsForDisplay());
1062 SCOPED_TRACE("paths differ");
1064 // Add some dupes by path.
1065 explicit_hosts
.AddPattern(
1066 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.bar.com/pathypath"));
1067 perm_set
= new PermissionSet(
1068 empty_perms
, explicit_hosts
, scriptable_hosts
);
1069 EXPECT_EQ(expected
, perm_set
->GetDistinctHostsForDisplay());
1073 SCOPED_TRACE("subdomains differ");
1075 // We don't do anything special for subdomains.
1076 explicit_hosts
.AddPattern(
1077 URLPattern(URLPattern::SCHEME_HTTP
, "http://monkey.www.bar.com/path"));
1078 explicit_hosts
.AddPattern(
1079 URLPattern(URLPattern::SCHEME_HTTP
, "http://bar.com/path"));
1081 expected
.insert("monkey.www.bar.com");
1082 expected
.insert("bar.com");
1084 perm_set
= new PermissionSet(
1085 empty_perms
, explicit_hosts
, scriptable_hosts
);
1086 EXPECT_EQ(expected
, perm_set
->GetDistinctHostsForDisplay());
1090 SCOPED_TRACE("RCDs differ");
1092 // Now test for RCD uniquing.
1093 explicit_hosts
.AddPattern(
1094 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.com/path"));
1095 explicit_hosts
.AddPattern(
1096 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.co.uk/path"));
1097 explicit_hosts
.AddPattern(
1098 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.de/path"));
1099 explicit_hosts
.AddPattern(
1100 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.ca.us/path"));
1101 explicit_hosts
.AddPattern(
1102 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.net/path"));
1103 explicit_hosts
.AddPattern(
1104 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.com.my/path"));
1106 // This is an unknown RCD, which shouldn't be uniqued out.
1107 explicit_hosts
.AddPattern(
1108 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.xyzzy/path"));
1109 // But it should only occur once.
1110 explicit_hosts
.AddPattern(
1111 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.xyzzy/path"));
1113 expected
.insert("www.foo.xyzzy");
1115 perm_set
= new PermissionSet(
1116 empty_perms
, explicit_hosts
, scriptable_hosts
);
1117 EXPECT_EQ(expected
, perm_set
->GetDistinctHostsForDisplay());
1121 SCOPED_TRACE("wildcards");
1123 explicit_hosts
.AddPattern(
1124 URLPattern(URLPattern::SCHEME_HTTP
, "http://*.google.com/*"));
1126 expected
.insert("*.google.com");
1128 perm_set
= new PermissionSet(
1129 empty_perms
, explicit_hosts
, scriptable_hosts
);
1130 EXPECT_EQ(expected
, perm_set
->GetDistinctHostsForDisplay());
1134 SCOPED_TRACE("scriptable hosts");
1135 explicit_hosts
.ClearPatterns();
1136 scriptable_hosts
.ClearPatterns();
1139 explicit_hosts
.AddPattern(
1140 URLPattern(URLPattern::SCHEME_HTTP
, "http://*.google.com/*"));
1141 scriptable_hosts
.AddPattern(
1142 URLPattern(URLPattern::SCHEME_HTTP
, "http://*.example.com/*"));
1144 expected
.insert("*.google.com");
1145 expected
.insert("*.example.com");
1147 perm_set
= new PermissionSet(
1148 empty_perms
, explicit_hosts
, scriptable_hosts
);
1149 EXPECT_EQ(expected
, perm_set
->GetDistinctHostsForDisplay());
1153 // We don't display warnings for file URLs because they are off by default.
1154 SCOPED_TRACE("file urls");
1155 explicit_hosts
.ClearPatterns();
1156 scriptable_hosts
.ClearPatterns();
1159 explicit_hosts
.AddPattern(
1160 URLPattern(URLPattern::SCHEME_FILE
, "file:///*"));
1162 perm_set
= new PermissionSet(
1163 empty_perms
, explicit_hosts
, scriptable_hosts
);
1164 EXPECT_EQ(expected
, perm_set
->GetDistinctHostsForDisplay());
1168 TEST(PermissionsTest
, GetDistinctHostsForDisplay_ComIsBestRcd
) {
1169 scoped_refptr
<PermissionSet
> perm_set
;
1170 APIPermissionSet empty_perms
;
1171 URLPatternSet explicit_hosts
;
1172 URLPatternSet scriptable_hosts
;
1173 explicit_hosts
.AddPattern(
1174 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.ca/path"));
1175 explicit_hosts
.AddPattern(
1176 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.org/path"));
1177 explicit_hosts
.AddPattern(
1178 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.co.uk/path"));
1179 explicit_hosts
.AddPattern(
1180 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.net/path"));
1181 explicit_hosts
.AddPattern(
1182 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.jp/path"));
1183 explicit_hosts
.AddPattern(
1184 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.com/path"));
1186 std::set
<std::string
> expected
;
1187 expected
.insert("www.foo.com");
1188 perm_set
= new PermissionSet(
1189 empty_perms
, explicit_hosts
, scriptable_hosts
);
1190 EXPECT_EQ(expected
, perm_set
->GetDistinctHostsForDisplay());
1193 TEST(PermissionsTest
, GetDistinctHostsForDisplay_NetIs2ndBestRcd
) {
1194 scoped_refptr
<PermissionSet
> perm_set
;
1195 APIPermissionSet empty_perms
;
1196 URLPatternSet explicit_hosts
;
1197 URLPatternSet scriptable_hosts
;
1198 explicit_hosts
.AddPattern(
1199 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.ca/path"));
1200 explicit_hosts
.AddPattern(
1201 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.org/path"));
1202 explicit_hosts
.AddPattern(
1203 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.co.uk/path"));
1204 explicit_hosts
.AddPattern(
1205 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.net/path"));
1206 explicit_hosts
.AddPattern(
1207 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.jp/path"));
1208 // No http://www.foo.com/path
1210 std::set
<std::string
> expected
;
1211 expected
.insert("www.foo.net");
1212 perm_set
= new PermissionSet(
1213 empty_perms
, explicit_hosts
, scriptable_hosts
);
1214 EXPECT_EQ(expected
, perm_set
->GetDistinctHostsForDisplay());
1217 TEST(PermissionsTest
,
1218 GetDistinctHostsForDisplay_OrgIs3rdBestRcd
) {
1219 scoped_refptr
<PermissionSet
> perm_set
;
1220 APIPermissionSet empty_perms
;
1221 URLPatternSet explicit_hosts
;
1222 URLPatternSet scriptable_hosts
;
1223 explicit_hosts
.AddPattern(
1224 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.ca/path"));
1225 explicit_hosts
.AddPattern(
1226 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.org/path"));
1227 explicit_hosts
.AddPattern(
1228 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.co.uk/path"));
1229 // No http://www.foo.net/path
1230 explicit_hosts
.AddPattern(
1231 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.jp/path"));
1232 // No http://www.foo.com/path
1234 std::set
<std::string
> expected
;
1235 expected
.insert("www.foo.org");
1236 perm_set
= new PermissionSet(
1237 empty_perms
, explicit_hosts
, scriptable_hosts
);
1238 EXPECT_EQ(expected
, perm_set
->GetDistinctHostsForDisplay());
1241 TEST(PermissionsTest
,
1242 GetDistinctHostsForDisplay_FirstInListIs4thBestRcd
) {
1243 scoped_refptr
<PermissionSet
> perm_set
;
1244 APIPermissionSet empty_perms
;
1245 URLPatternSet explicit_hosts
;
1246 URLPatternSet scriptable_hosts
;
1247 explicit_hosts
.AddPattern(
1248 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.ca/path"));
1249 // No http://www.foo.org/path
1250 explicit_hosts
.AddPattern(
1251 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.co.uk/path"));
1252 // No http://www.foo.net/path
1253 explicit_hosts
.AddPattern(
1254 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.jp/path"));
1255 // No http://www.foo.com/path
1257 std::set
<std::string
> expected
;
1258 expected
.insert("www.foo.ca");
1259 perm_set
= new PermissionSet(
1260 empty_perms
, explicit_hosts
, scriptable_hosts
);
1261 EXPECT_EQ(expected
, perm_set
->GetDistinctHostsForDisplay());
1264 TEST(PermissionsTest
, HasLessHostPrivilegesThan
) {
1265 Manifest::Type extension_type
= Manifest::TYPE_EXTENSION
;
1266 URLPatternSet elist1
;
1267 URLPatternSet elist2
;
1268 URLPatternSet slist1
;
1269 URLPatternSet slist2
;
1270 scoped_refptr
<PermissionSet
> set1
;
1271 scoped_refptr
<PermissionSet
> set2
;
1272 APIPermissionSet empty_perms
;
1274 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.google.com.hk/path"));
1276 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.google.com/path"));
1278 // Test that the host order does not matter.
1280 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.google.com/path"));
1282 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.google.com.hk/path"));
1284 set1
= new PermissionSet(empty_perms
, elist1
, slist1
);
1285 set2
= new PermissionSet(empty_perms
, elist2
, slist2
);
1287 EXPECT_FALSE(set1
->HasLessHostPrivilegesThan(set2
.get(), extension_type
));
1288 EXPECT_FALSE(set2
->HasLessHostPrivilegesThan(set1
.get(), extension_type
));
1290 // Test that paths are ignored.
1291 elist2
.ClearPatterns();
1293 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.google.com/*"));
1294 set2
= new PermissionSet(empty_perms
, elist2
, slist2
);
1295 EXPECT_FALSE(set1
->HasLessHostPrivilegesThan(set2
.get(), extension_type
));
1296 EXPECT_FALSE(set2
->HasLessHostPrivilegesThan(set1
.get(), extension_type
));
1298 // Test that RCDs are ignored.
1299 elist2
.ClearPatterns();
1301 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.google.com.hk/*"));
1302 set2
= new PermissionSet(empty_perms
, elist2
, slist2
);
1303 EXPECT_FALSE(set1
->HasLessHostPrivilegesThan(set2
.get(), extension_type
));
1304 EXPECT_FALSE(set2
->HasLessHostPrivilegesThan(set1
.get(), extension_type
));
1306 // Test that subdomain wildcards are handled properly.
1307 elist2
.ClearPatterns();
1309 URLPattern(URLPattern::SCHEME_HTTP
, "http://*.google.com.hk/*"));
1310 set2
= new PermissionSet(empty_perms
, elist2
, slist2
);
1311 EXPECT_TRUE(set1
->HasLessHostPrivilegesThan(set2
.get(), extension_type
));
1312 // TODO(jstritar): Does not match subdomains properly. http://crbug.com/65337
1313 // EXPECT_FALSE(set2->HasLessHostPrivilegesThan(set1.get()));
1315 // Test that different domains count as different hosts.
1316 elist2
.ClearPatterns();
1318 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.google.com/path"));
1320 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.example.org/path"));
1321 set2
= new PermissionSet(empty_perms
, elist2
, slist2
);
1322 EXPECT_TRUE(set1
->HasLessHostPrivilegesThan(set2
.get(), extension_type
));
1323 EXPECT_FALSE(set2
->HasLessHostPrivilegesThan(set1
.get(), extension_type
));
1325 // Test that different subdomains count as different hosts.
1326 elist2
.ClearPatterns();
1328 URLPattern(URLPattern::SCHEME_HTTP
, "http://mail.google.com/*"));
1329 set2
= new PermissionSet(empty_perms
, elist2
, slist2
);
1330 EXPECT_TRUE(set1
->HasLessHostPrivilegesThan(set2
.get(), extension_type
));
1331 EXPECT_TRUE(set2
->HasLessHostPrivilegesThan(set1
.get(), extension_type
));
1333 // Test that platform apps do not have host permissions increases.
1334 extension_type
= Manifest::TYPE_PLATFORM_APP
;
1335 EXPECT_FALSE(set1
->HasLessHostPrivilegesThan(set2
.get(), extension_type
));
1336 EXPECT_FALSE(set2
->HasLessHostPrivilegesThan(set1
.get(), extension_type
));
1339 TEST(PermissionsTest
, GetAPIsAsStrings
) {
1340 APIPermissionSet apis
;
1341 URLPatternSet empty_set
;
1343 apis
.insert(APIPermission::kProxy
);
1344 apis
.insert(APIPermission::kBackground
);
1345 apis
.insert(APIPermission::kNotification
);
1346 apis
.insert(APIPermission::kTab
);
1348 scoped_refptr
<PermissionSet
> perm_set
= new PermissionSet(
1349 apis
, empty_set
, empty_set
);
1350 std::set
<std::string
> api_names
= perm_set
->GetAPIsAsStrings();
1352 // The result is correct if it has the same number of elements
1353 // and we can convert it back to the id set.
1354 EXPECT_EQ(4u, api_names
.size());
1356 PermissionsInfo::GetInstance()->GetAllByName(api_names
));
1359 TEST(PermissionsTest
, IsEmpty
) {
1360 APIPermissionSet empty_apis
;
1361 URLPatternSet empty_extent
;
1363 scoped_refptr
<PermissionSet
> empty
= new PermissionSet();
1364 EXPECT_TRUE(empty
->IsEmpty());
1365 scoped_refptr
<PermissionSet
> perm_set
;
1367 perm_set
= new PermissionSet(empty_apis
, empty_extent
, empty_extent
);
1368 EXPECT_TRUE(perm_set
->IsEmpty());
1370 APIPermissionSet non_empty_apis
;
1371 non_empty_apis
.insert(APIPermission::kBackground
);
1372 perm_set
= new PermissionSet(
1373 non_empty_apis
, empty_extent
, empty_extent
);
1374 EXPECT_FALSE(perm_set
->IsEmpty());
1376 // Try non standard host
1377 URLPatternSet non_empty_extent
;
1378 AddPattern(&non_empty_extent
, "http://www.google.com/*");
1380 perm_set
= new PermissionSet(
1381 empty_apis
, non_empty_extent
, empty_extent
);
1382 EXPECT_FALSE(perm_set
->IsEmpty());
1384 perm_set
= new PermissionSet(
1385 empty_apis
, empty_extent
, non_empty_extent
);
1386 EXPECT_FALSE(perm_set
->IsEmpty());
1389 TEST(PermissionsTest
, ImpliedPermissions
) {
1390 URLPatternSet empty_extent
;
1391 APIPermissionSet apis
;
1392 apis
.insert(APIPermission::kWebRequest
);
1393 apis
.insert(APIPermission::kFileBrowserHandler
);
1394 EXPECT_EQ(2U, apis
.size());
1396 scoped_refptr
<PermissionSet
> perm_set
;
1397 perm_set
= new PermissionSet(apis
, empty_extent
, empty_extent
);
1398 EXPECT_EQ(4U, perm_set
->apis().size());
1401 TEST(PermissionsTest
, SyncFileSystemPermission
) {
1402 scoped_refptr
<Extension
> extension
= LoadManifest(
1403 "permissions", "sync_file_system.json");
1404 APIPermissionSet apis
;
1405 apis
.insert(APIPermission::kSyncFileSystem
);
1406 EXPECT_TRUE(extension
->is_platform_app());
1407 EXPECT_TRUE(extension
->HasAPIPermission(APIPermission::kSyncFileSystem
));
1408 std::vector
<string16
> warnings
=
1409 PermissionsData::GetPermissionMessageStrings(extension
.get());
1410 EXPECT_TRUE(Contains(warnings
, "Store data in your Google Drive account"));
1411 ASSERT_EQ(1u, warnings
.size());
1414 // Make sure that we don't crash when we're trying to show the permissions
1415 // even though chrome://thumb (and everything that's not chrome://favicon with
1416 // a chrome:// scheme) is not a valid permission.
1417 // More details here: crbug/246314.
1418 TEST(PermissionsTest
, ChromeURLs
) {
1419 URLPatternSet allowed_hosts
;
1420 allowed_hosts
.AddPattern(
1421 URLPattern(URLPattern::SCHEME_ALL
, "http://www.google.com/"));
1422 allowed_hosts
.AddPattern(
1423 URLPattern(URLPattern::SCHEME_ALL
, "chrome://favicon/"));
1424 allowed_hosts
.AddPattern(
1425 URLPattern(URLPattern::SCHEME_ALL
, "chrome://thumb/"));
1426 scoped_refptr
<PermissionSet
> permissions(
1427 new PermissionSet(APIPermissionSet(), allowed_hosts
, URLPatternSet()));
1428 permissions
->GetPermissionMessages(Manifest::TYPE_EXTENSION
);
1431 TEST(PermissionsTest
, HasLessPrivilegesThan_DeclarativeWebRequest
) {
1432 scoped_refptr
<Extension
> extension(
1433 LoadManifest("permissions", "permissions_all_urls.json"));
1434 scoped_refptr
<const PermissionSet
> permissions(
1435 extension
->GetActivePermissions());
1437 scoped_refptr
<Extension
> extension_dwr(
1438 LoadManifest("permissions", "web_request_all_host_permissions.json"));
1439 scoped_refptr
<const PermissionSet
> permissions_dwr(
1440 extension_dwr
->GetActivePermissions());
1442 EXPECT_FALSE(permissions
->HasLessPrivilegesThan(permissions_dwr
.get(),
1443 extension
->GetType()));
1445 } // namespace extensions