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 "chrome/common/extensions/permissions/permission_message_util.h"
16 #include "chrome/common/extensions/permissions/socket_permission.h"
17 #include "extensions/common/error_utils.h"
18 #include "extensions/common/extension.h"
19 #include "extensions/common/permissions/permission_message_provider.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 "testing/gtest/include/gtest/gtest.h"
25 using extension_test_util::LoadManifest
;
27 namespace extensions
{
31 static void AddPattern(URLPatternSet
* extent
, const std::string
& pattern
) {
32 int schemes
= URLPattern::SCHEME_ALL
;
33 extent
->AddPattern(URLPattern(schemes
, pattern
));
36 size_t IndexOf(const std::vector
<base::string16
>& warnings
,
37 const std::string
& warning
) {
38 for (size_t i
= 0; i
< warnings
.size(); ++i
) {
39 if (warnings
[i
] == base::ASCIIToUTF16(warning
))
43 return warnings
.size();
46 bool Contains(const std::vector
<base::string16
>& warnings
,
47 const std::string
& warning
) {
48 return IndexOf(warnings
, warning
) != warnings
.size();
54 TEST(PermissionsTest
, GetByID
) {
55 PermissionsInfo
* info
= PermissionsInfo::GetInstance();
56 APIPermissionSet apis
= info
->GetAll();
57 for (APIPermissionSet::const_iterator i
= apis
.begin();
58 i
!= apis
.end(); ++i
) {
59 EXPECT_EQ(i
->id(), i
->info()->id());
63 // Tests that GetByName works with normal permission names and aliases.
64 TEST(PermissionsTest
, GetByName
) {
65 PermissionsInfo
* info
= PermissionsInfo::GetInstance();
66 EXPECT_EQ(APIPermission::kTab
, info
->GetByName("tabs")->id());
67 EXPECT_EQ(APIPermission::kManagement
,
68 info
->GetByName("management")->id());
69 EXPECT_FALSE(info
->GetByName("alsdkfjasldkfj"));
72 TEST(PermissionsTest
, GetAll
) {
74 PermissionsInfo
* info
= PermissionsInfo::GetInstance();
75 APIPermissionSet apis
= info
->GetAll();
76 for (APIPermissionSet::const_iterator api
= apis
.begin();
77 api
!= apis
.end(); ++api
) {
78 // Make sure only the valid permission IDs get returned.
79 EXPECT_NE(APIPermission::kInvalid
, api
->id());
80 EXPECT_NE(APIPermission::kUnknown
, api
->id());
83 EXPECT_EQ(count
, info
->get_permission_count());
86 TEST(PermissionsTest
, GetAllByName
) {
87 std::set
<std::string
> names
;
88 names
.insert("background");
89 names
.insert("management");
91 // This is an alias of kTab
92 names
.insert("windows");
94 // This unknown name should get dropped.
95 names
.insert("sdlkfjasdlkfj");
97 APIPermissionSet expected
;
98 expected
.insert(APIPermission::kBackground
);
99 expected
.insert(APIPermission::kManagement
);
100 expected
.insert(APIPermission::kTab
);
103 PermissionsInfo::GetInstance()->GetAllByName(names
));
106 // Tests that the aliases are properly mapped.
107 TEST(PermissionsTest
, Aliases
) {
108 PermissionsInfo
* info
= PermissionsInfo::GetInstance();
109 // tabs: tabs, windows
110 std::string tabs_name
= "tabs";
111 EXPECT_EQ(tabs_name
, info
->GetByID(APIPermission::kTab
)->name());
112 EXPECT_EQ(APIPermission::kTab
, info
->GetByName("tabs")->id());
113 EXPECT_EQ(APIPermission::kTab
, info
->GetByName("windows")->id());
115 // unlimitedStorage: unlimitedStorage, unlimited_storage
116 std::string storage_name
= "unlimitedStorage";
117 EXPECT_EQ(storage_name
, info
->GetByID(
118 APIPermission::kUnlimitedStorage
)->name());
119 EXPECT_EQ(APIPermission::kUnlimitedStorage
,
120 info
->GetByName("unlimitedStorage")->id());
121 EXPECT_EQ(APIPermission::kUnlimitedStorage
,
122 info
->GetByName("unlimited_storage")->id());
125 TEST(PermissionsTest
, EffectiveHostPermissions
) {
126 scoped_refptr
<Extension
> extension
;
127 scoped_refptr
<const PermissionSet
> permissions
;
129 extension
= LoadManifest("effective_host_permissions", "empty.json");
130 permissions
= extension
->GetActivePermissions();
132 PermissionsData::GetEffectiveHostPermissions(extension
.get())
135 permissions
->HasEffectiveAccessToURL(GURL("http://www.google.com")));
136 EXPECT_FALSE(permissions
->HasEffectiveAccessToAllHosts());
138 extension
= LoadManifest("effective_host_permissions", "one_host.json");
139 permissions
= extension
->GetActivePermissions();
140 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(
141 GURL("http://www.google.com")));
142 EXPECT_FALSE(permissions
->HasEffectiveAccessToURL(
143 GURL("https://www.google.com")));
144 EXPECT_FALSE(permissions
->HasEffectiveAccessToAllHosts());
146 extension
= LoadManifest("effective_host_permissions",
147 "one_host_wildcard.json");
148 permissions
= extension
->GetActivePermissions();
149 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(GURL("http://google.com")));
150 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(
151 GURL("http://foo.google.com")));
152 EXPECT_FALSE(permissions
->HasEffectiveAccessToAllHosts());
154 extension
= LoadManifest("effective_host_permissions", "two_hosts.json");
155 permissions
= extension
->GetActivePermissions();
156 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(
157 GURL("http://www.google.com")));
158 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(
159 GURL("http://www.reddit.com")));
160 EXPECT_FALSE(permissions
->HasEffectiveAccessToAllHosts());
162 extension
= LoadManifest("effective_host_permissions",
163 "https_not_considered.json");
164 permissions
= extension
->GetActivePermissions();
165 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(GURL("http://google.com")));
166 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(GURL("https://google.com")));
167 EXPECT_FALSE(permissions
->HasEffectiveAccessToAllHosts());
169 extension
= LoadManifest("effective_host_permissions",
170 "two_content_scripts.json");
171 permissions
= extension
->GetActivePermissions();
172 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(GURL("http://google.com")));
173 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(
174 GURL("http://www.reddit.com")));
175 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(
176 GURL("http://news.ycombinator.com")));
177 EXPECT_FALSE(permissions
->HasEffectiveAccessToAllHosts());
179 extension
= LoadManifest("effective_host_permissions", "all_hosts.json");
180 permissions
= extension
->GetActivePermissions();
181 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(GURL("http://test/")));
182 EXPECT_FALSE(permissions
->HasEffectiveAccessToURL(GURL("https://test/")));
184 permissions
->HasEffectiveAccessToURL(GURL("http://www.google.com")));
185 EXPECT_TRUE(permissions
->HasEffectiveAccessToAllHosts());
187 extension
= LoadManifest("effective_host_permissions", "all_hosts2.json");
188 permissions
= extension
->GetActivePermissions();
189 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(GURL("http://test/")));
191 permissions
->HasEffectiveAccessToURL(GURL("http://www.google.com")));
192 EXPECT_TRUE(permissions
->HasEffectiveAccessToAllHosts());
194 extension
= LoadManifest("effective_host_permissions", "all_hosts3.json");
195 permissions
= extension
->GetActivePermissions();
196 EXPECT_FALSE(permissions
->HasEffectiveAccessToURL(GURL("http://test/")));
197 EXPECT_TRUE(permissions
->HasEffectiveAccessToURL(GURL("https://test/")));
199 permissions
->HasEffectiveAccessToURL(GURL("http://www.google.com")));
200 EXPECT_TRUE(permissions
->HasEffectiveAccessToAllHosts());
203 TEST(PermissionsTest
, ExplicitAccessToOrigin
) {
204 APIPermissionSet apis
;
205 ManifestPermissionSet manifest_permissions
;
206 URLPatternSet explicit_hosts
;
207 URLPatternSet scriptable_hosts
;
209 AddPattern(&explicit_hosts
, "http://*.google.com/*");
210 // The explicit host paths should get set to /*.
211 AddPattern(&explicit_hosts
, "http://www.example.com/a/particular/path/*");
213 scoped_refptr
<PermissionSet
> perm_set
= new PermissionSet(
214 apis
, manifest_permissions
, explicit_hosts
, scriptable_hosts
);
215 ASSERT_TRUE(perm_set
->HasExplicitAccessToOrigin(
216 GURL("http://www.google.com/")));
217 ASSERT_TRUE(perm_set
->HasExplicitAccessToOrigin(
218 GURL("http://test.google.com/")));
219 ASSERT_TRUE(perm_set
->HasExplicitAccessToOrigin(
220 GURL("http://www.example.com")));
221 ASSERT_TRUE(perm_set
->HasEffectiveAccessToURL(
222 GURL("http://www.example.com")));
223 ASSERT_FALSE(perm_set
->HasExplicitAccessToOrigin(
224 GURL("http://test.example.com")));
227 TEST(PermissionsTest
, CreateUnion
) {
228 APIPermission
* permission
= NULL
;
230 ManifestPermissionSet manifest_permissions
;
231 APIPermissionSet apis1
;
232 APIPermissionSet apis2
;
233 APIPermissionSet expected_apis
;
235 URLPatternSet explicit_hosts1
;
236 URLPatternSet explicit_hosts2
;
237 URLPatternSet expected_explicit_hosts
;
239 URLPatternSet scriptable_hosts1
;
240 URLPatternSet scriptable_hosts2
;
241 URLPatternSet expected_scriptable_hosts
;
243 URLPatternSet effective_hosts
;
245 scoped_refptr
<PermissionSet
> set1
;
246 scoped_refptr
<PermissionSet
> set2
;
247 scoped_refptr
<PermissionSet
> union_set
;
249 const APIPermissionInfo
* permission_info
=
250 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket
);
251 permission
= permission_info
->CreateAPIPermission();
253 scoped_ptr
<base::ListValue
> value(new base::ListValue());
255 base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
256 value
->Append(base::Value::CreateStringValue("udp-bind::8080"));
257 value
->Append(base::Value::CreateStringValue("udp-send-to::8888"));
258 if (!permission
->FromValue(value
.get())) {
263 // Union with an empty set.
264 apis1
.insert(APIPermission::kTab
);
265 apis1
.insert(APIPermission::kBackground
);
266 apis1
.insert(permission
->Clone());
267 expected_apis
.insert(APIPermission::kTab
);
268 expected_apis
.insert(APIPermission::kBackground
);
269 expected_apis
.insert(permission
);
271 AddPattern(&explicit_hosts1
, "http://*.google.com/*");
272 AddPattern(&expected_explicit_hosts
, "http://*.google.com/*");
273 AddPattern(&effective_hosts
, "http://*.google.com/*");
275 set1
= new PermissionSet(apis1
, manifest_permissions
,
276 explicit_hosts1
, scriptable_hosts1
);
277 set2
= new PermissionSet(apis2
, manifest_permissions
,
278 explicit_hosts2
, scriptable_hosts2
);
279 union_set
= PermissionSet::CreateUnion(set1
.get(), set2
.get());
280 EXPECT_TRUE(set1
->Contains(*set2
.get()));
281 EXPECT_TRUE(set1
->Contains(*union_set
.get()));
282 EXPECT_FALSE(set2
->Contains(*set1
.get()));
283 EXPECT_FALSE(set2
->Contains(*union_set
.get()));
284 EXPECT_TRUE(union_set
->Contains(*set1
.get()));
285 EXPECT_TRUE(union_set
->Contains(*set2
.get()));
287 EXPECT_FALSE(union_set
->HasEffectiveFullAccess());
288 EXPECT_EQ(expected_apis
, union_set
->apis());
289 EXPECT_EQ(expected_explicit_hosts
, union_set
->explicit_hosts());
290 EXPECT_EQ(expected_scriptable_hosts
, union_set
->scriptable_hosts());
291 EXPECT_EQ(expected_explicit_hosts
, union_set
->effective_hosts());
293 // Now use a real second set.
294 apis2
.insert(APIPermission::kTab
);
295 apis2
.insert(APIPermission::kProxy
);
296 apis2
.insert(APIPermission::kClipboardWrite
);
297 apis2
.insert(APIPermission::kPlugin
);
299 permission
= permission_info
->CreateAPIPermission();
301 scoped_ptr
<base::ListValue
> value(new base::ListValue());
303 base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
304 value
->Append(base::Value::CreateStringValue("udp-send-to::8899"));
305 if (!permission
->FromValue(value
.get())) {
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());
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 if (!permission
->FromValue(value
.get())) {
328 // Insert a new permission socket permisssion which will replace the old one.
329 expected_apis
.insert(permission
);
331 AddPattern(&explicit_hosts2
, "http://*.example.com/*");
332 AddPattern(&scriptable_hosts2
, "http://*.google.com/*");
333 AddPattern(&expected_explicit_hosts
, "http://*.example.com/*");
334 AddPattern(&expected_scriptable_hosts
, "http://*.google.com/*");
336 URLPatternSet::CreateUnion(
337 explicit_hosts2
, scriptable_hosts2
, &effective_hosts
);
339 set2
= new PermissionSet(apis2
, manifest_permissions
,
340 explicit_hosts2
, scriptable_hosts2
);
341 union_set
= PermissionSet::CreateUnion(set1
.get(), set2
.get());
343 EXPECT_FALSE(set1
->Contains(*set2
.get()));
344 EXPECT_FALSE(set1
->Contains(*union_set
.get()));
345 EXPECT_FALSE(set2
->Contains(*set1
.get()));
346 EXPECT_FALSE(set2
->Contains(*union_set
.get()));
347 EXPECT_TRUE(union_set
->Contains(*set1
.get()));
348 EXPECT_TRUE(union_set
->Contains(*set2
.get()));
350 EXPECT_TRUE(union_set
->HasEffectiveFullAccess());
351 EXPECT_TRUE(union_set
->HasEffectiveAccessToAllHosts());
352 EXPECT_EQ(expected_apis
, union_set
->apis());
353 EXPECT_EQ(expected_explicit_hosts
, union_set
->explicit_hosts());
354 EXPECT_EQ(expected_scriptable_hosts
, union_set
->scriptable_hosts());
355 EXPECT_EQ(effective_hosts
, union_set
->effective_hosts());
358 TEST(PermissionsTest
, CreateIntersection
) {
359 APIPermission
* permission
= NULL
;
361 ManifestPermissionSet manifest_permissions
;
362 APIPermissionSet apis1
;
363 APIPermissionSet apis2
;
364 APIPermissionSet expected_apis
;
366 URLPatternSet explicit_hosts1
;
367 URLPatternSet explicit_hosts2
;
368 URLPatternSet expected_explicit_hosts
;
370 URLPatternSet scriptable_hosts1
;
371 URLPatternSet scriptable_hosts2
;
372 URLPatternSet expected_scriptable_hosts
;
374 URLPatternSet effective_hosts
;
376 scoped_refptr
<PermissionSet
> set1
;
377 scoped_refptr
<PermissionSet
> set2
;
378 scoped_refptr
<PermissionSet
> new_set
;
380 const APIPermissionInfo
* permission_info
=
381 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket
);
383 // Intersection with an empty set.
384 apis1
.insert(APIPermission::kTab
);
385 apis1
.insert(APIPermission::kBackground
);
386 permission
= permission_info
->CreateAPIPermission();
388 scoped_ptr
<base::ListValue
> value(new base::ListValue());
390 base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
391 value
->Append(base::Value::CreateStringValue("udp-bind::8080"));
392 value
->Append(base::Value::CreateStringValue("udp-send-to::8888"));
393 if (!permission
->FromValue(value
.get())) {
397 apis1
.insert(permission
);
399 AddPattern(&explicit_hosts1
, "http://*.google.com/*");
400 AddPattern(&scriptable_hosts1
, "http://www.reddit.com/*");
402 set1
= new PermissionSet(apis1
, manifest_permissions
,
403 explicit_hosts1
, scriptable_hosts1
);
404 set2
= new PermissionSet(apis2
, manifest_permissions
,
405 explicit_hosts2
, scriptable_hosts2
);
406 new_set
= PermissionSet::CreateIntersection(set1
.get(), set2
.get());
407 EXPECT_TRUE(set1
->Contains(*new_set
.get()));
408 EXPECT_TRUE(set2
->Contains(*new_set
.get()));
409 EXPECT_TRUE(set1
->Contains(*set2
.get()));
410 EXPECT_FALSE(set2
->Contains(*set1
.get()));
411 EXPECT_FALSE(new_set
->Contains(*set1
.get()));
412 EXPECT_TRUE(new_set
->Contains(*set2
.get()));
414 EXPECT_TRUE(new_set
->IsEmpty());
415 EXPECT_FALSE(new_set
->HasEffectiveFullAccess());
416 EXPECT_EQ(expected_apis
, new_set
->apis());
417 EXPECT_EQ(expected_explicit_hosts
, new_set
->explicit_hosts());
418 EXPECT_EQ(expected_scriptable_hosts
, new_set
->scriptable_hosts());
419 EXPECT_EQ(expected_explicit_hosts
, new_set
->effective_hosts());
421 // Now use a real second set.
422 apis2
.insert(APIPermission::kTab
);
423 apis2
.insert(APIPermission::kProxy
);
424 apis2
.insert(APIPermission::kClipboardWrite
);
425 apis2
.insert(APIPermission::kPlugin
);
426 permission
= permission_info
->CreateAPIPermission();
428 scoped_ptr
<base::ListValue
> value(new base::ListValue());
429 value
->Append(base::Value::CreateStringValue("udp-bind::8080"));
430 value
->Append(base::Value::CreateStringValue("udp-send-to::8888"));
431 value
->Append(base::Value::CreateStringValue("udp-send-to::8899"));
432 if (!permission
->FromValue(value
.get())) {
436 apis2
.insert(permission
);
438 expected_apis
.insert(APIPermission::kTab
);
439 permission
= permission_info
->CreateAPIPermission();
441 scoped_ptr
<base::ListValue
> value(new base::ListValue());
442 value
->Append(base::Value::CreateStringValue("udp-bind::8080"));
443 value
->Append(base::Value::CreateStringValue("udp-send-to::8888"));
444 if (!permission
->FromValue(value
.get())) {
448 expected_apis
.insert(permission
);
450 AddPattern(&explicit_hosts2
, "http://*.example.com/*");
451 AddPattern(&explicit_hosts2
, "http://*.google.com/*");
452 AddPattern(&scriptable_hosts2
, "http://*.google.com/*");
453 AddPattern(&expected_explicit_hosts
, "http://*.google.com/*");
455 effective_hosts
.ClearPatterns();
456 AddPattern(&effective_hosts
, "http://*.google.com/*");
458 set2
= new PermissionSet(apis2
, manifest_permissions
,
459 explicit_hosts2
, scriptable_hosts2
);
460 new_set
= PermissionSet::CreateIntersection(set1
.get(), set2
.get());
462 EXPECT_TRUE(set1
->Contains(*new_set
.get()));
463 EXPECT_TRUE(set2
->Contains(*new_set
.get()));
464 EXPECT_FALSE(set1
->Contains(*set2
.get()));
465 EXPECT_FALSE(set2
->Contains(*set1
.get()));
466 EXPECT_FALSE(new_set
->Contains(*set1
.get()));
467 EXPECT_FALSE(new_set
->Contains(*set2
.get()));
469 EXPECT_FALSE(new_set
->HasEffectiveFullAccess());
470 EXPECT_FALSE(new_set
->HasEffectiveAccessToAllHosts());
471 EXPECT_EQ(expected_apis
, new_set
->apis());
472 EXPECT_EQ(expected_explicit_hosts
, new_set
->explicit_hosts());
473 EXPECT_EQ(expected_scriptable_hosts
, new_set
->scriptable_hosts());
474 EXPECT_EQ(effective_hosts
, new_set
->effective_hosts());
477 TEST(PermissionsTest
, CreateDifference
) {
478 APIPermission
* permission
= NULL
;
480 ManifestPermissionSet manifest_permissions
;
481 APIPermissionSet apis1
;
482 APIPermissionSet apis2
;
483 APIPermissionSet expected_apis
;
485 URLPatternSet explicit_hosts1
;
486 URLPatternSet explicit_hosts2
;
487 URLPatternSet expected_explicit_hosts
;
489 URLPatternSet scriptable_hosts1
;
490 URLPatternSet scriptable_hosts2
;
491 URLPatternSet expected_scriptable_hosts
;
493 URLPatternSet effective_hosts
;
495 scoped_refptr
<PermissionSet
> set1
;
496 scoped_refptr
<PermissionSet
> set2
;
497 scoped_refptr
<PermissionSet
> new_set
;
499 const APIPermissionInfo
* permission_info
=
500 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket
);
502 // Difference with an empty set.
503 apis1
.insert(APIPermission::kTab
);
504 apis1
.insert(APIPermission::kBackground
);
505 permission
= permission_info
->CreateAPIPermission();
507 scoped_ptr
<base::ListValue
> value(new base::ListValue());
509 base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
510 value
->Append(base::Value::CreateStringValue("udp-bind::8080"));
511 value
->Append(base::Value::CreateStringValue("udp-send-to::8888"));
512 if (!permission
->FromValue(value
.get())) {
516 apis1
.insert(permission
);
518 AddPattern(&explicit_hosts1
, "http://*.google.com/*");
519 AddPattern(&scriptable_hosts1
, "http://www.reddit.com/*");
521 set1
= new PermissionSet(apis1
, manifest_permissions
,
522 explicit_hosts1
, scriptable_hosts1
);
523 set2
= new PermissionSet(apis2
, manifest_permissions
,
524 explicit_hosts2
, scriptable_hosts2
);
525 new_set
= PermissionSet::CreateDifference(set1
.get(), set2
.get());
526 EXPECT_EQ(*set1
.get(), *new_set
.get());
528 // Now use a real second set.
529 apis2
.insert(APIPermission::kTab
);
530 apis2
.insert(APIPermission::kProxy
);
531 apis2
.insert(APIPermission::kClipboardWrite
);
532 apis2
.insert(APIPermission::kPlugin
);
533 permission
= permission_info
->CreateAPIPermission();
535 scoped_ptr
<base::ListValue
> value(new base::ListValue());
537 base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
538 value
->Append(base::Value::CreateStringValue("udp-send-to::8899"));
539 if (!permission
->FromValue(value
.get())) {
543 apis2
.insert(permission
);
545 expected_apis
.insert(APIPermission::kBackground
);
546 permission
= permission_info
->CreateAPIPermission();
548 scoped_ptr
<base::ListValue
> value(new base::ListValue());
549 value
->Append(base::Value::CreateStringValue("udp-bind::8080"));
550 value
->Append(base::Value::CreateStringValue("udp-send-to::8888"));
551 if (!permission
->FromValue(value
.get())) {
555 expected_apis
.insert(permission
);
557 AddPattern(&explicit_hosts2
, "http://*.example.com/*");
558 AddPattern(&explicit_hosts2
, "http://*.google.com/*");
559 AddPattern(&scriptable_hosts2
, "http://*.google.com/*");
560 AddPattern(&expected_scriptable_hosts
, "http://www.reddit.com/*");
562 effective_hosts
.ClearPatterns();
563 AddPattern(&effective_hosts
, "http://www.reddit.com/*");
565 set2
= new PermissionSet(apis2
, manifest_permissions
,
566 explicit_hosts2
, scriptable_hosts2
);
567 new_set
= PermissionSet::CreateDifference(set1
.get(), set2
.get());
569 EXPECT_TRUE(set1
->Contains(*new_set
.get()));
570 EXPECT_FALSE(set2
->Contains(*new_set
.get()));
572 EXPECT_FALSE(new_set
->HasEffectiveFullAccess());
573 EXPECT_FALSE(new_set
->HasEffectiveAccessToAllHosts());
574 EXPECT_EQ(expected_apis
, new_set
->apis());
575 EXPECT_EQ(expected_explicit_hosts
, new_set
->explicit_hosts());
576 EXPECT_EQ(expected_scriptable_hosts
, new_set
->scriptable_hosts());
577 EXPECT_EQ(effective_hosts
, new_set
->effective_hosts());
579 // |set3| = |set1| - |set2| --> |set3| intersect |set2| == empty_set
580 set1
= PermissionSet::CreateIntersection(new_set
.get(), set2
.get());
581 EXPECT_TRUE(set1
->IsEmpty());
584 TEST(PermissionsTest
, IsPrivilegeIncrease
) {
586 const char* base_name
;
587 bool expect_increase
;
589 { "allhosts1", false }, // all -> all
590 { "allhosts2", false }, // all -> one
591 { "allhosts3", true }, // one -> all
592 { "hosts1", false }, // http://a,http://b -> http://a,http://b
593 { "hosts2", true }, // http://a,http://b -> https://a,http://*.b
594 { "hosts3", false }, // http://a,http://b -> http://a
595 { "hosts4", true }, // http://a -> http://a,http://b
596 { "hosts5", false }, // http://a,b,c -> http://a,b,c + https://a,b,c
597 { "hosts6", false }, // http://a.com -> http://a.com + http://a.co.uk
598 { "permissions1", false }, // tabs -> tabs
599 { "permissions2", true }, // tabs -> tabs,bookmarks
600 { "permissions3", true }, // http://a -> http://a,tabs
601 { "permissions5", true }, // bookmarks -> bookmarks,history
602 { "equivalent_warnings", false }, // tabs --> tabs, webNavigation
603 #if !defined(OS_CHROMEOS) // plugins aren't allowed in ChromeOS
604 { "permissions4", false }, // plugin -> plugin,tabs
605 { "plugin1", false }, // plugin -> plugin
606 { "plugin2", false }, // plugin -> none
607 { "plugin3", true }, // none -> plugin
609 { "storage", false }, // none -> storage
610 { "notifications", false }, // none -> notifications
611 { "platformapp1", false }, // host permissions for platform apps
612 { "platformapp2", true }, // API permissions for platform apps
613 { "media_galleries1", true }, // all -> read|all
614 { "media_galleries2", true }, // read|all -> read|delete|copyTo|all
615 { "media_galleries3", true }, // all -> read|delete|all
616 { "media_galleries4", false }, // read|all -> all
617 { "media_galleries5", false }, // read|copyTo|delete|all -> read|all
618 { "media_galleries6", false }, // read|all -> read|all
619 { "media_galleries7", true }, // read|delete|all -> read|copyTo|delete|all
620 { "sockets1", true }, // none -> tcp:*:*
621 { "sockets2", false }, // tcp:*:* -> tcp:*:*
622 { "sockets3", true }, // tcp:a.com:80 -> tcp:*:*
625 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(kTests
); ++i
) {
626 scoped_refptr
<Extension
> old_extension(
627 LoadManifest("allow_silent_upgrade",
628 std::string(kTests
[i
].base_name
) + "_old.json"));
629 scoped_refptr
<Extension
> new_extension(
630 LoadManifest("allow_silent_upgrade",
631 std::string(kTests
[i
].base_name
) + "_new.json"));
633 EXPECT_TRUE(new_extension
.get()) << kTests
[i
].base_name
<< "_new.json";
634 if (!new_extension
.get())
637 scoped_refptr
<const PermissionSet
> old_p(
638 old_extension
->GetActivePermissions());
639 scoped_refptr
<const PermissionSet
> new_p(
640 new_extension
->GetActivePermissions());
641 Manifest::Type extension_type
= old_extension
->GetType();
643 bool increased
= PermissionMessageProvider::Get()->IsPrivilegeIncrease(
644 old_p
.get(), new_p
.get(), extension_type
);
645 EXPECT_EQ(kTests
[i
].expect_increase
, increased
) << kTests
[i
].base_name
;
649 TEST(PermissionsTest
, PermissionMessages
) {
650 // Ensure that all permissions that needs to show install UI actually have
651 // strings associated with them.
652 APIPermissionSet skip
;
654 // These are considered "nuisance" or "trivial" permissions that don't need
656 skip
.insert(APIPermission::kActiveTab
);
657 skip
.insert(APIPermission::kAdView
);
658 skip
.insert(APIPermission::kAlarms
);
659 skip
.insert(APIPermission::kAlwaysOnTopWindows
);
660 skip
.insert(APIPermission::kAppCurrentWindowInternal
);
661 skip
.insert(APIPermission::kAppRuntime
);
662 skip
.insert(APIPermission::kAppWindow
);
663 skip
.insert(APIPermission::kAudio
);
664 skip
.insert(APIPermission::kBrowsingData
);
665 skip
.insert(APIPermission::kCastStreaming
);
666 skip
.insert(APIPermission::kContextMenus
);
667 skip
.insert(APIPermission::kDiagnostics
);
668 skip
.insert(APIPermission::kDns
);
669 skip
.insert(APIPermission::kDownloadsShelf
);
670 skip
.insert(APIPermission::kFontSettings
);
671 skip
.insert(APIPermission::kFullscreen
);
672 skip
.insert(APIPermission::kGcm
);
673 skip
.insert(APIPermission::kIdle
);
674 skip
.insert(APIPermission::kIdltest
);
675 skip
.insert(APIPermission::kLogPrivate
);
676 skip
.insert(APIPermission::kNotification
);
677 skip
.insert(APIPermission::kPointerLock
);
678 skip
.insert(APIPermission::kPower
);
679 skip
.insert(APIPermission::kPushMessaging
);
680 skip
.insert(APIPermission::kSessions
);
681 skip
.insert(APIPermission::kStorage
);
682 skip
.insert(APIPermission::kSystemCpu
);
683 skip
.insert(APIPermission::kSystemDisplay
);
684 skip
.insert(APIPermission::kSystemMemory
);
685 skip
.insert(APIPermission::kSystemNetwork
);
686 skip
.insert(APIPermission::kSystemStorage
);
687 skip
.insert(APIPermission::kTts
);
688 skip
.insert(APIPermission::kUnlimitedStorage
);
689 skip
.insert(APIPermission::kWebView
);
690 skip
.insert(APIPermission::kOverrideEscFullscreen
);
692 // TODO(erikkay) add a string for this permission.
693 skip
.insert(APIPermission::kBackground
);
695 skip
.insert(APIPermission::kClipboardWrite
);
697 // The cookie permission does nothing unless you have associated host
699 skip
.insert(APIPermission::kCookie
);
701 // These are warned as part of host permission checks.
702 skip
.insert(APIPermission::kDeclarativeContent
);
703 skip
.insert(APIPermission::kPageCapture
);
704 skip
.insert(APIPermission::kProxy
);
705 skip
.insert(APIPermission::kTabCapture
);
706 skip
.insert(APIPermission::kWebRequest
);
707 skip
.insert(APIPermission::kWebRequestBlocking
);
709 // This permission requires explicit user action (context menu handler)
710 // so we won't prompt for it for now.
711 skip
.insert(APIPermission::kFileBrowserHandler
);
713 // These permissions require explicit user action (configuration dialog)
714 // so we don't prompt for them at install time.
715 skip
.insert(APIPermission::kMediaGalleries
);
717 // If you've turned on the experimental command-line flag, we don't need
718 // to warn you further.
719 skip
.insert(APIPermission::kExperimental
);
721 // The Identity API has its own server-driven permission prompts.
722 skip
.insert(APIPermission::kIdentity
);
724 // These are private.
725 skip
.insert(APIPermission::kAutoTestPrivate
);
726 skip
.insert(APIPermission::kBookmarkManagerPrivate
);
727 skip
.insert(APIPermission::kBrailleDisplayPrivate
);
728 skip
.insert(APIPermission::kCast
);
729 skip
.insert(APIPermission::kCastStreaming
);
730 skip
.insert(APIPermission::kChromeosInfoPrivate
);
731 skip
.insert(APIPermission::kCloudPrintPrivate
);
732 skip
.insert(APIPermission::kCommandLinePrivate
);
733 skip
.insert(APIPermission::kDeveloperPrivate
);
734 skip
.insert(APIPermission::kDial
);
735 skip
.insert(APIPermission::kDownloadsInternal
);
736 skip
.insert(APIPermission::kEchoPrivate
);
737 skip
.insert(APIPermission::kEnterprisePlatformKeysPrivate
);
738 skip
.insert(APIPermission::kFeedbackPrivate
);
739 skip
.insert(APIPermission::kFileBrowserHandlerInternal
);
740 skip
.insert(APIPermission::kFileBrowserPrivate
);
741 skip
.insert(APIPermission::kFirstRunPrivate
);
742 skip
.insert(APIPermission::kIdentityPrivate
);
743 skip
.insert(APIPermission::kInfobars
);
744 skip
.insert(APIPermission::kInputMethodPrivate
);
745 skip
.insert(APIPermission::kMediaGalleriesPrivate
);
746 skip
.insert(APIPermission::kMediaPlayerPrivate
);
747 skip
.insert(APIPermission::kMetricsPrivate
);
748 skip
.insert(APIPermission::kMDns
);
749 skip
.insert(APIPermission::kPreferencesPrivate
);
750 skip
.insert(APIPermission::kPrincipalsPrivate
);
751 skip
.insert(APIPermission::kImageWriterPrivate
);
752 skip
.insert(APIPermission::kReadingListPrivate
);
753 skip
.insert(APIPermission::kRtcPrivate
);
754 skip
.insert(APIPermission::kStreamsPrivate
);
755 skip
.insert(APIPermission::kSystemPrivate
);
756 skip
.insert(APIPermission::kTabCaptureForTab
);
757 skip
.insert(APIPermission::kTerminalPrivate
);
758 skip
.insert(APIPermission::kVirtualKeyboardPrivate
);
759 skip
.insert(APIPermission::kWallpaperPrivate
);
760 skip
.insert(APIPermission::kWebRequestInternal
);
761 skip
.insert(APIPermission::kWebrtcAudioPrivate
);
762 skip
.insert(APIPermission::kWebrtcLoggingPrivate
);
763 skip
.insert(APIPermission::kWebstorePrivate
);
765 // Warned as part of host permissions.
766 skip
.insert(APIPermission::kDevtools
);
769 skip
.insert(APIPermission::kBluetooth
);
770 skip
.insert(APIPermission::kFileSystem
);
771 skip
.insert(APIPermission::kFileSystemProvider
);
772 skip
.insert(APIPermission::kFileSystemRetainEntries
);
773 skip
.insert(APIPermission::kSocket
);
774 skip
.insert(APIPermission::kUsbDevice
);
776 PermissionsInfo
* info
= PermissionsInfo::GetInstance();
777 APIPermissionSet permissions
= info
->GetAll();
778 for (APIPermissionSet::const_iterator i
= permissions
.begin();
779 i
!= permissions
.end(); ++i
) {
780 const APIPermissionInfo
* permission_info
= i
->info();
781 EXPECT_TRUE(permission_info
!= NULL
);
783 if (skip
.count(i
->id())) {
784 EXPECT_EQ(PermissionMessage::kNone
, permission_info
->message_id())
785 << "unexpected message_id for " << permission_info
->name();
787 EXPECT_NE(PermissionMessage::kNone
, permission_info
->message_id())
788 << "missing message_id for " << permission_info
->name();
793 TEST(PermissionsTest
, FileSystemPermissionMessages
) {
794 APIPermissionSet api_permissions
;
795 api_permissions
.insert(APIPermission::kFileSystemWrite
);
796 api_permissions
.insert(APIPermission::kFileSystemDirectory
);
797 scoped_refptr
<PermissionSet
> permissions(
798 new PermissionSet(api_permissions
, ManifestPermissionSet(),
799 URLPatternSet(), URLPatternSet()));
800 PermissionMessages messages
=
801 PermissionMessageProvider::Get()->GetPermissionMessages(
802 permissions
, Manifest::TYPE_PLATFORM_APP
);
803 ASSERT_EQ(2u, messages
.size());
804 std::sort(messages
.begin(), messages
.end());
805 std::set
<PermissionMessage::ID
> ids
;
806 for (PermissionMessages::const_iterator it
= messages
.begin();
807 it
!= messages
.end(); ++it
) {
808 ids
.insert(it
->id());
810 EXPECT_TRUE(ContainsKey(ids
, PermissionMessage::kFileSystemDirectory
));
811 EXPECT_TRUE(ContainsKey(ids
, PermissionMessage::kFileSystemWrite
));
814 TEST(PermissionsTest
, HiddenFileSystemPermissionMessages
) {
815 APIPermissionSet api_permissions
;
816 api_permissions
.insert(APIPermission::kFileSystemWrite
);
817 api_permissions
.insert(APIPermission::kFileSystemDirectory
);
818 api_permissions
.insert(APIPermission::kFileSystemWriteDirectory
);
819 scoped_refptr
<PermissionSet
> permissions(
820 new PermissionSet(api_permissions
, ManifestPermissionSet(),
821 URLPatternSet(), URLPatternSet()));
822 PermissionMessages messages
=
823 PermissionMessageProvider::Get()->GetPermissionMessages(
824 permissions
, Manifest::TYPE_PLATFORM_APP
);
825 ASSERT_EQ(1u, messages
.size());
826 EXPECT_EQ(PermissionMessage::kFileSystemWriteDirectory
, messages
[0].id());
829 TEST(PermissionsTest
, MergedFileSystemPermissionComparison
) {
830 APIPermissionSet write_api_permissions
;
831 write_api_permissions
.insert(APIPermission::kFileSystemWrite
);
832 scoped_refptr
<PermissionSet
> write_permissions(
833 new PermissionSet(write_api_permissions
, ManifestPermissionSet(),
834 URLPatternSet(), URLPatternSet()));
836 APIPermissionSet directory_api_permissions
;
837 directory_api_permissions
.insert(APIPermission::kFileSystemDirectory
);
838 scoped_refptr
<PermissionSet
> directory_permissions(
839 new PermissionSet(directory_api_permissions
, ManifestPermissionSet(),
840 URLPatternSet(), URLPatternSet()));
842 APIPermissionSet write_directory_api_permissions
;
843 write_directory_api_permissions
.insert(
844 APIPermission::kFileSystemWriteDirectory
);
845 scoped_refptr
<PermissionSet
> write_directory_permissions(
846 new PermissionSet(write_directory_api_permissions
,
847 ManifestPermissionSet(),
851 const PermissionMessageProvider
* provider
= PermissionMessageProvider::Get();
852 EXPECT_FALSE(provider
->IsPrivilegeIncrease(write_directory_permissions
,
854 Manifest::TYPE_PLATFORM_APP
));
855 EXPECT_FALSE(provider
->IsPrivilegeIncrease(write_directory_permissions
,
856 directory_permissions
,
857 Manifest::TYPE_PLATFORM_APP
));
858 EXPECT_TRUE(provider
->IsPrivilegeIncrease(write_permissions
,
859 directory_permissions
,
860 Manifest::TYPE_PLATFORM_APP
));
861 EXPECT_TRUE(provider
->IsPrivilegeIncrease(write_permissions
,
862 write_directory_permissions
,
863 Manifest::TYPE_PLATFORM_APP
));
864 EXPECT_TRUE(provider
->IsPrivilegeIncrease(directory_permissions
,
866 Manifest::TYPE_PLATFORM_APP
));
867 EXPECT_TRUE(provider
->IsPrivilegeIncrease(directory_permissions
,
868 write_directory_permissions
,
869 Manifest::TYPE_PLATFORM_APP
));
872 TEST(PermissionsTest
, GetWarningMessages_ManyHosts
) {
873 scoped_refptr
<Extension
> extension
;
875 extension
= LoadManifest("permissions", "many-hosts.json");
876 std::vector
<base::string16
> warnings
=
877 PermissionsData::GetPermissionMessageStrings(extension
.get());
878 ASSERT_EQ(1u, warnings
.size());
879 EXPECT_EQ("Access your data on encrypted.google.com and www.google.com",
880 base::UTF16ToUTF8(warnings
[0]));
883 TEST(PermissionsTest
, GetWarningMessages_Plugins
) {
884 scoped_refptr
<Extension
> extension
;
885 scoped_refptr
<PermissionSet
> permissions
;
887 extension
= LoadManifest("permissions", "plugins.json");
888 std::vector
<base::string16
> warnings
=
889 PermissionsData::GetPermissionMessageStrings(extension
.get());
890 // We don't parse the plugins key on Chrome OS, so it should not ask for any
892 #if defined(OS_CHROMEOS)
893 ASSERT_EQ(0u, warnings
.size());
895 ASSERT_EQ(1u, warnings
.size());
896 EXPECT_EQ("Access all data on your computer and the websites you visit",
897 base::UTF16ToUTF8(warnings
[0]));
901 TEST(PermissionsTest
, GetWarningMessages_AudioVideo
) {
902 // Both audio and video present.
903 scoped_refptr
<Extension
> extension
=
904 LoadManifest("permissions", "audio-video.json");
905 const PermissionMessageProvider
* provider
= PermissionMessageProvider::Get();
907 const_cast<PermissionSet
*>(
908 extension
->GetActivePermissions().get());
909 std::vector
<base::string16
> warnings
=
910 provider
->GetWarningMessages(set
, extension
->GetType());
911 EXPECT_FALSE(Contains(warnings
, "Use your microphone"));
912 EXPECT_FALSE(Contains(warnings
, "Use your camera"));
913 EXPECT_TRUE(Contains(warnings
, "Use your microphone and camera"));
914 size_t combined_index
= IndexOf(warnings
, "Use your microphone and camera");
915 size_t combined_size
= warnings
.size();
917 // Just audio present.
918 set
->apis_
.erase(APIPermission::kVideoCapture
);
919 warnings
= provider
->GetWarningMessages(set
, extension
->GetType());
920 EXPECT_EQ(combined_size
, warnings
.size());
921 EXPECT_EQ(combined_index
, IndexOf(warnings
, "Use your microphone"));
922 EXPECT_FALSE(Contains(warnings
, "Use your camera"));
923 EXPECT_FALSE(Contains(warnings
, "Use your microphone and camera"));
925 // Just video present.
926 set
->apis_
.erase(APIPermission::kAudioCapture
);
927 set
->apis_
.insert(APIPermission::kVideoCapture
);
928 warnings
= provider
->GetWarningMessages(set
, extension
->GetType());
929 EXPECT_EQ(combined_size
, warnings
.size());
930 EXPECT_FALSE(Contains(warnings
, "Use your microphone"));
931 EXPECT_FALSE(Contains(warnings
, "Use your microphone and camera"));
932 EXPECT_TRUE(Contains(warnings
, "Use your camera"));
935 TEST(PermissionsTest
, GetWarningMessages_DeclarativeWebRequest
) {
936 // Test that if the declarativeWebRequest permission is present
937 // in combination with all hosts permission, then only the warning
938 // for host permissions is shown, because that covers the use of
939 // declarativeWebRequest.
941 // Until Declarative Web Request is in stable, let's make sure it is enabled
942 // on the current channel.
943 ScopedCurrentChannel
sc(chrome::VersionInfo::CHANNEL_CANARY
);
945 // First verify that declarativeWebRequest produces a message when host
946 // permissions do not cover all hosts.
947 scoped_refptr
<Extension
> extension
=
948 LoadManifest("permissions", "web_request_com_host_permissions.json");
949 const PermissionMessageProvider
* provider
= PermissionMessageProvider::Get();
950 const PermissionSet
* set
= extension
->GetActivePermissions().get();
951 std::vector
<base::string16
> warnings
=
952 provider
->GetWarningMessages(set
, extension
->GetType());
953 EXPECT_TRUE(Contains(warnings
, "Block parts of web pages"));
954 EXPECT_FALSE(Contains(warnings
, "Access your data on all websites"));
956 // Now verify that declarativeWebRequest does not produce a message when host
957 // permissions do cover all hosts.
959 LoadManifest("permissions", "web_request_all_host_permissions.json");
960 set
= extension
->GetActivePermissions().get();
961 warnings
= provider
->GetWarningMessages(set
, extension
->GetType());
962 EXPECT_FALSE(Contains(warnings
, "Block parts of web pages"));
963 EXPECT_TRUE(Contains(warnings
, "Access your data on all websites"));
966 TEST(PermissionsTest
, GetWarningMessages_Serial
) {
967 scoped_refptr
<Extension
> extension
=
968 LoadManifest("permissions", "serial.json");
970 EXPECT_TRUE(extension
->is_platform_app());
971 EXPECT_TRUE(extension
->HasAPIPermission(APIPermission::kSerial
));
972 std::vector
<base::string16
> warnings
=
973 PermissionsData::GetPermissionMessageStrings(extension
.get());
975 Contains(warnings
, "Use serial devices attached to your computer"));
976 ASSERT_EQ(1u, warnings
.size());
979 TEST(PermissionsTest
, GetWarningMessages_Socket_AnyHost
) {
980 ScopedCurrentChannel
channel(chrome::VersionInfo::CHANNEL_DEV
);
982 scoped_refptr
<Extension
> extension
=
983 LoadManifest("permissions", "socket_any_host.json");
984 EXPECT_TRUE(extension
->is_platform_app());
985 EXPECT_TRUE(extension
->HasAPIPermission(APIPermission::kSocket
));
986 std::vector
<base::string16
> warnings
=
987 PermissionsData::GetPermissionMessageStrings(extension
.get());
988 EXPECT_EQ(1u, warnings
.size());
989 EXPECT_TRUE(Contains(warnings
, "Exchange data with any computer "
990 "on the local network or internet"));
993 TEST(PermissionsTest
, GetWarningMessages_Socket_OneDomainTwoHostnames
) {
994 ScopedCurrentChannel
channel(chrome::VersionInfo::CHANNEL_DEV
);
996 scoped_refptr
<Extension
> extension
=
997 LoadManifest("permissions", "socket_one_domain_two_hostnames.json");
998 EXPECT_TRUE(extension
->is_platform_app());
999 EXPECT_TRUE(extension
->HasAPIPermission(APIPermission::kSocket
));
1000 std::vector
<base::string16
> warnings
=
1001 PermissionsData::GetPermissionMessageStrings(extension
.get());
1003 // Verify the warnings, including support for unicode characters, the fact
1004 // that domain host warnings come before specific host warnings, and the fact
1005 // that domains and hostnames are in alphabetical order regardless of the
1006 // order in the manifest file.
1007 EXPECT_EQ(2u, warnings
.size());
1008 if (warnings
.size() > 0)
1009 EXPECT_EQ(warnings
[0],
1010 base::UTF8ToUTF16("Exchange data with any computer in the domain "
1012 if (warnings
.size() > 1)
1013 EXPECT_EQ(warnings
[1],
1014 base::UTF8ToUTF16("Exchange data with the computers named: "
1015 "b\xC3\xA5r.example.com foo.example.com"));
1016 // "\xC3\xA5" = UTF-8 for lowercase A with ring above
1019 TEST(PermissionsTest
, GetWarningMessages_Socket_TwoDomainsOneHostname
) {
1020 ScopedCurrentChannel
channel(chrome::VersionInfo::CHANNEL_DEV
);
1022 scoped_refptr
<Extension
> extension
=
1023 LoadManifest("permissions", "socket_two_domains_one_hostname.json");
1024 EXPECT_TRUE(extension
->is_platform_app());
1025 EXPECT_TRUE(extension
->HasAPIPermission(APIPermission::kSocket
));
1026 std::vector
<base::string16
> warnings
=
1027 PermissionsData::GetPermissionMessageStrings(extension
.get());
1029 // Verify the warnings, including the fact that domain host warnings come
1030 // before specific host warnings and the fact that domains and hostnames are
1031 // in alphabetical order regardless of the order in the manifest file.
1032 EXPECT_EQ(2u, warnings
.size());
1033 if (warnings
.size() > 0)
1034 EXPECT_EQ(warnings
[0],
1035 base::UTF8ToUTF16("Exchange data with any computer in the "
1036 "domains: example.com foo.example.org"));
1037 if (warnings
.size() > 1)
1038 EXPECT_EQ(warnings
[1],
1039 base::UTF8ToUTF16("Exchange data with the computer named "
1040 "bar.example.org"));
1043 TEST(PermissionsTest
, GetWarningMessages_PlatformApppHosts
) {
1044 scoped_refptr
<Extension
> extension
;
1046 extension
= LoadManifest("permissions", "platform_app_hosts.json");
1047 EXPECT_TRUE(extension
->is_platform_app());
1048 std::vector
<base::string16
> warnings
=
1049 PermissionsData::GetPermissionMessageStrings(extension
.get());
1050 ASSERT_EQ(0u, warnings
.size());
1052 extension
= LoadManifest("permissions", "platform_app_all_urls.json");
1053 EXPECT_TRUE(extension
->is_platform_app());
1054 warnings
= PermissionsData::GetPermissionMessageStrings(extension
.get());
1055 ASSERT_EQ(0u, warnings
.size());
1058 TEST(PermissionsTest
, GetDistinctHosts
) {
1059 URLPatternSet explicit_hosts
;
1060 std::set
<std::string
> expected
;
1061 expected
.insert("www.foo.com");
1062 expected
.insert("www.bar.com");
1063 expected
.insert("www.baz.com");
1066 SCOPED_TRACE("no dupes");
1068 // Simple list with no dupes.
1069 explicit_hosts
.AddPattern(
1070 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.com/path"));
1071 explicit_hosts
.AddPattern(
1072 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.bar.com/path"));
1073 explicit_hosts
.AddPattern(
1074 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.baz.com/path"));
1076 permission_message_util::GetDistinctHosts(
1077 explicit_hosts
, true, true));
1081 SCOPED_TRACE("two dupes");
1084 explicit_hosts
.AddPattern(
1085 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.com/path"));
1086 explicit_hosts
.AddPattern(
1087 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.baz.com/path"));
1089 permission_message_util::GetDistinctHosts(
1090 explicit_hosts
, true, true));
1094 SCOPED_TRACE("schemes differ");
1096 // Add a pattern that differs only by scheme. This should be filtered out.
1097 explicit_hosts
.AddPattern(
1098 URLPattern(URLPattern::SCHEME_HTTPS
, "https://www.bar.com/path"));
1100 permission_message_util::GetDistinctHosts(
1101 explicit_hosts
, true, true));
1105 SCOPED_TRACE("paths differ");
1107 // Add some dupes by path.
1108 explicit_hosts
.AddPattern(
1109 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.bar.com/pathypath"));
1111 permission_message_util::GetDistinctHosts(
1112 explicit_hosts
, true, true));
1116 SCOPED_TRACE("subdomains differ");
1118 // We don't do anything special for subdomains.
1119 explicit_hosts
.AddPattern(
1120 URLPattern(URLPattern::SCHEME_HTTP
, "http://monkey.www.bar.com/path"));
1121 explicit_hosts
.AddPattern(
1122 URLPattern(URLPattern::SCHEME_HTTP
, "http://bar.com/path"));
1124 expected
.insert("monkey.www.bar.com");
1125 expected
.insert("bar.com");
1128 permission_message_util::GetDistinctHosts(
1129 explicit_hosts
, true, true));
1133 SCOPED_TRACE("RCDs differ");
1135 // Now test for RCD uniquing.
1136 explicit_hosts
.AddPattern(
1137 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.com/path"));
1138 explicit_hosts
.AddPattern(
1139 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.co.uk/path"));
1140 explicit_hosts
.AddPattern(
1141 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.de/path"));
1142 explicit_hosts
.AddPattern(
1143 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.ca.us/path"));
1144 explicit_hosts
.AddPattern(
1145 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.net/path"));
1146 explicit_hosts
.AddPattern(
1147 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.com.my/path"));
1149 // This is an unknown RCD, which shouldn't be uniqued out.
1150 explicit_hosts
.AddPattern(
1151 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.xyzzy/path"));
1152 // But it should only occur once.
1153 explicit_hosts
.AddPattern(
1154 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.xyzzy/path"));
1156 expected
.insert("www.foo.xyzzy");
1159 permission_message_util::GetDistinctHosts(
1160 explicit_hosts
, true, true));
1164 SCOPED_TRACE("wildcards");
1166 explicit_hosts
.AddPattern(
1167 URLPattern(URLPattern::SCHEME_HTTP
, "http://*.google.com/*"));
1169 expected
.insert("*.google.com");
1172 permission_message_util::GetDistinctHosts(
1173 explicit_hosts
, true, true));
1177 SCOPED_TRACE("scriptable hosts");
1179 APIPermissionSet empty_perms
;
1180 explicit_hosts
.ClearPatterns();
1181 URLPatternSet scriptable_hosts
;
1184 explicit_hosts
.AddPattern(
1185 URLPattern(URLPattern::SCHEME_HTTP
, "http://*.google.com/*"));
1186 scriptable_hosts
.AddPattern(
1187 URLPattern(URLPattern::SCHEME_HTTP
, "http://*.example.com/*"));
1189 expected
.insert("*.google.com");
1190 expected
.insert("*.example.com");
1192 scoped_refptr
<PermissionSet
> perm_set(new PermissionSet(
1193 empty_perms
, ManifestPermissionSet(),
1194 explicit_hosts
, scriptable_hosts
));
1196 permission_message_util::GetDistinctHosts(
1197 perm_set
->effective_hosts(), true, true));
1201 // We don't display warnings for file URLs because they are off by default.
1202 SCOPED_TRACE("file urls");
1204 explicit_hosts
.ClearPatterns();
1207 explicit_hosts
.AddPattern(
1208 URLPattern(URLPattern::SCHEME_FILE
, "file:///*"));
1211 permission_message_util::GetDistinctHosts(
1212 explicit_hosts
, true, true));
1216 TEST(PermissionsTest
, GetDistinctHosts_ComIsBestRcd
) {
1217 URLPatternSet explicit_hosts
;
1218 explicit_hosts
.AddPattern(
1219 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.ca/path"));
1220 explicit_hosts
.AddPattern(
1221 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.org/path"));
1222 explicit_hosts
.AddPattern(
1223 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.co.uk/path"));
1224 explicit_hosts
.AddPattern(
1225 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.net/path"));
1226 explicit_hosts
.AddPattern(
1227 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.jp/path"));
1228 explicit_hosts
.AddPattern(
1229 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.com/path"));
1231 std::set
<std::string
> expected
;
1232 expected
.insert("www.foo.com");
1234 permission_message_util::GetDistinctHosts(
1235 explicit_hosts
, true, true));
1238 TEST(PermissionsTest
, GetDistinctHosts_NetIs2ndBestRcd
) {
1239 URLPatternSet explicit_hosts
;
1240 explicit_hosts
.AddPattern(
1241 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.ca/path"));
1242 explicit_hosts
.AddPattern(
1243 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.org/path"));
1244 explicit_hosts
.AddPattern(
1245 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.co.uk/path"));
1246 explicit_hosts
.AddPattern(
1247 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.net/path"));
1248 explicit_hosts
.AddPattern(
1249 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.jp/path"));
1250 // No http://www.foo.com/path
1252 std::set
<std::string
> expected
;
1253 expected
.insert("www.foo.net");
1255 permission_message_util::GetDistinctHosts(
1256 explicit_hosts
, true, true));
1259 TEST(PermissionsTest
, GetDistinctHosts_OrgIs3rdBestRcd
) {
1260 URLPatternSet explicit_hosts
;
1261 explicit_hosts
.AddPattern(
1262 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.ca/path"));
1263 explicit_hosts
.AddPattern(
1264 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.org/path"));
1265 explicit_hosts
.AddPattern(
1266 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.co.uk/path"));
1267 // No http://www.foo.net/path
1268 explicit_hosts
.AddPattern(
1269 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.jp/path"));
1270 // No http://www.foo.com/path
1272 std::set
<std::string
> expected
;
1273 expected
.insert("www.foo.org");
1275 permission_message_util::GetDistinctHosts(
1276 explicit_hosts
, true, true));
1279 TEST(PermissionsTest
, GetDistinctHosts_FirstInListIs4thBestRcd
) {
1280 URLPatternSet explicit_hosts
;
1281 explicit_hosts
.AddPattern(
1282 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.ca/path"));
1283 // No http://www.foo.org/path
1284 explicit_hosts
.AddPattern(
1285 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.co.uk/path"));
1286 // No http://www.foo.net/path
1287 explicit_hosts
.AddPattern(
1288 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.foo.jp/path"));
1289 // No http://www.foo.com/path
1291 std::set
<std::string
> expected
;
1292 expected
.insert("www.foo.ca");
1294 permission_message_util::GetDistinctHosts(
1295 explicit_hosts
, true, true));
1298 TEST(PermissionsTest
, IsHostPrivilegeIncrease
) {
1299 Manifest::Type type
= Manifest::TYPE_EXTENSION
;
1300 const PermissionMessageProvider
* provider
= PermissionMessageProvider::Get();
1301 ManifestPermissionSet empty_manifest_permissions
;
1302 URLPatternSet elist1
;
1303 URLPatternSet elist2
;
1304 URLPatternSet slist1
;
1305 URLPatternSet slist2
;
1306 scoped_refptr
<PermissionSet
> set1
;
1307 scoped_refptr
<PermissionSet
> set2
;
1308 APIPermissionSet empty_perms
;
1310 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.google.com.hk/path"));
1312 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.google.com/path"));
1314 // Test that the host order does not matter.
1316 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.google.com/path"));
1318 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.google.com.hk/path"));
1320 set1
= new PermissionSet(empty_perms
, empty_manifest_permissions
,
1322 set2
= new PermissionSet(empty_perms
, empty_manifest_permissions
,
1325 EXPECT_FALSE(provider
->IsPrivilegeIncrease(set1
, set2
, type
));
1326 EXPECT_FALSE(provider
->IsPrivilegeIncrease(set2
, set1
, type
));
1328 // Test that paths are ignored.
1329 elist2
.ClearPatterns();
1331 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.google.com/*"));
1332 set2
= new PermissionSet(empty_perms
, empty_manifest_permissions
,
1334 EXPECT_FALSE(provider
->IsPrivilegeIncrease(set1
, set2
, type
));
1335 EXPECT_FALSE(provider
->IsPrivilegeIncrease(set2
, set1
, type
));
1337 // Test that RCDs are ignored.
1338 elist2
.ClearPatterns();
1340 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.google.com.hk/*"));
1341 set2
= new PermissionSet(empty_perms
, empty_manifest_permissions
,
1343 EXPECT_FALSE(provider
->IsPrivilegeIncrease(set1
, set2
, type
));
1344 EXPECT_FALSE(provider
->IsPrivilegeIncrease(set2
, set1
, type
));
1346 // Test that subdomain wildcards are handled properly.
1347 elist2
.ClearPatterns();
1349 URLPattern(URLPattern::SCHEME_HTTP
, "http://*.google.com.hk/*"));
1350 set2
= new PermissionSet(empty_perms
, empty_manifest_permissions
,
1352 EXPECT_TRUE(provider
->IsPrivilegeIncrease(set1
, set2
, type
));
1353 // TODO(jstritar): Does not match subdomains properly. http://crbug.com/65337
1354 // EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type));
1356 // Test that different domains count as different hosts.
1357 elist2
.ClearPatterns();
1359 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.google.com/path"));
1361 URLPattern(URLPattern::SCHEME_HTTP
, "http://www.example.org/path"));
1362 set2
= new PermissionSet(empty_perms
, empty_manifest_permissions
,
1364 EXPECT_TRUE(provider
->IsPrivilegeIncrease(set1
, set2
, type
));
1365 EXPECT_FALSE(provider
->IsPrivilegeIncrease(set2
, set1
, type
));
1367 // Test that different subdomains count as different hosts.
1368 elist2
.ClearPatterns();
1370 URLPattern(URLPattern::SCHEME_HTTP
, "http://mail.google.com/*"));
1371 set2
= new PermissionSet(empty_perms
, empty_manifest_permissions
,
1373 EXPECT_TRUE(provider
->IsPrivilegeIncrease(set1
, set2
, type
));
1374 EXPECT_TRUE(provider
->IsPrivilegeIncrease(set2
, set1
, type
));
1376 // Test that platform apps do not have host permissions increases.
1377 type
= Manifest::TYPE_PLATFORM_APP
;
1378 EXPECT_FALSE(provider
->IsPrivilegeIncrease(set1
, set2
, type
));
1379 EXPECT_FALSE(provider
->IsPrivilegeIncrease(set2
, set1
, type
));
1382 TEST(PermissionsTest
, GetAPIsAsStrings
) {
1383 APIPermissionSet apis
;
1384 URLPatternSet empty_set
;
1386 apis
.insert(APIPermission::kProxy
);
1387 apis
.insert(APIPermission::kBackground
);
1388 apis
.insert(APIPermission::kNotification
);
1389 apis
.insert(APIPermission::kTab
);
1391 scoped_refptr
<PermissionSet
> perm_set
= new PermissionSet(
1392 apis
, ManifestPermissionSet(), empty_set
, empty_set
);
1393 std::set
<std::string
> api_names
= perm_set
->GetAPIsAsStrings();
1395 // The result is correct if it has the same number of elements
1396 // and we can convert it back to the id set.
1397 EXPECT_EQ(4u, api_names
.size());
1399 PermissionsInfo::GetInstance()->GetAllByName(api_names
));
1402 TEST(PermissionsTest
, IsEmpty
) {
1403 APIPermissionSet empty_apis
;
1404 URLPatternSet empty_extent
;
1406 scoped_refptr
<PermissionSet
> empty
= new PermissionSet();
1407 EXPECT_TRUE(empty
->IsEmpty());
1408 scoped_refptr
<PermissionSet
> perm_set
;
1410 perm_set
= new PermissionSet(empty_apis
, ManifestPermissionSet(),
1411 empty_extent
, empty_extent
);
1412 EXPECT_TRUE(perm_set
->IsEmpty());
1414 APIPermissionSet non_empty_apis
;
1415 non_empty_apis
.insert(APIPermission::kBackground
);
1416 perm_set
= new PermissionSet(non_empty_apis
, ManifestPermissionSet(),
1417 empty_extent
, empty_extent
);
1418 EXPECT_FALSE(perm_set
->IsEmpty());
1420 // Try non standard host
1421 URLPatternSet non_empty_extent
;
1422 AddPattern(&non_empty_extent
, "http://www.google.com/*");
1424 perm_set
= new PermissionSet(empty_apis
, ManifestPermissionSet(),
1425 non_empty_extent
, empty_extent
);
1426 EXPECT_FALSE(perm_set
->IsEmpty());
1428 perm_set
= new PermissionSet(empty_apis
, ManifestPermissionSet(),
1429 empty_extent
, non_empty_extent
);
1430 EXPECT_FALSE(perm_set
->IsEmpty());
1433 TEST(PermissionsTest
, ImpliedPermissions
) {
1434 URLPatternSet empty_extent
;
1435 APIPermissionSet apis
;
1436 apis
.insert(APIPermission::kWebRequest
);
1437 apis
.insert(APIPermission::kFileBrowserHandler
);
1438 EXPECT_EQ(2U, apis
.size());
1440 scoped_refptr
<PermissionSet
> perm_set
;
1441 perm_set
= new PermissionSet(apis
, ManifestPermissionSet(),
1442 empty_extent
, empty_extent
);
1443 EXPECT_EQ(4U, perm_set
->apis().size());
1446 TEST(PermissionsTest
, SyncFileSystemPermission
) {
1447 scoped_refptr
<Extension
> extension
= LoadManifest(
1448 "permissions", "sync_file_system.json");
1449 APIPermissionSet apis
;
1450 apis
.insert(APIPermission::kSyncFileSystem
);
1451 EXPECT_TRUE(extension
->is_platform_app());
1452 EXPECT_TRUE(extension
->HasAPIPermission(APIPermission::kSyncFileSystem
));
1453 std::vector
<base::string16
> warnings
=
1454 PermissionsData::GetPermissionMessageStrings(extension
.get());
1455 EXPECT_TRUE(Contains(warnings
, "Store data in your Google Drive account"));
1456 ASSERT_EQ(1u, warnings
.size());
1459 // Make sure that we don't crash when we're trying to show the permissions
1460 // even though chrome://thumb (and everything that's not chrome://favicon with
1461 // a chrome:// scheme) is not a valid permission.
1462 // More details here: crbug/246314.
1463 TEST(PermissionsTest
, ChromeURLs
) {
1464 URLPatternSet allowed_hosts
;
1465 allowed_hosts
.AddPattern(
1466 URLPattern(URLPattern::SCHEME_ALL
, "http://www.google.com/"));
1467 allowed_hosts
.AddPattern(
1468 URLPattern(URLPattern::SCHEME_ALL
, "chrome://favicon/"));
1469 allowed_hosts
.AddPattern(
1470 URLPattern(URLPattern::SCHEME_ALL
, "chrome://thumb/"));
1471 scoped_refptr
<PermissionSet
> permissions(
1472 new PermissionSet(APIPermissionSet(), ManifestPermissionSet(),
1473 allowed_hosts
, URLPatternSet()));
1474 PermissionMessageProvider::Get()->
1475 GetPermissionMessages(permissions
, Manifest::TYPE_EXTENSION
);
1478 TEST(PermissionsTest
, IsPrivilegeIncrease_DeclarativeWebRequest
) {
1479 scoped_refptr
<Extension
> extension(
1480 LoadManifest("permissions", "permissions_all_urls.json"));
1481 scoped_refptr
<const PermissionSet
> permissions(
1482 extension
->GetActivePermissions());
1484 scoped_refptr
<Extension
> extension_dwr(
1485 LoadManifest("permissions", "web_request_all_host_permissions.json"));
1486 scoped_refptr
<const PermissionSet
> permissions_dwr(
1487 extension_dwr
->GetActivePermissions());
1489 EXPECT_FALSE(PermissionMessageProvider::Get()->
1490 IsPrivilegeIncrease(permissions
.get(),
1491 permissions_dwr
.get(),
1492 extension
->GetType()));
1495 } // namespace extensions