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