permission_set_unittest.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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
29using extension_test_util::LoadManifest;
30
31namespace extensions {
32
33namespace {
34
35static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
36  int schemes = URLPattern::SCHEME_ALL;
37  extent->AddPattern(URLPattern(schemes, pattern));
38}
39
40size_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
50bool 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.
58TEST(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.
68TEST(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
76TEST(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
90TEST(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.
111TEST(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
129TEST(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
209TEST(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
233TEST(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
358TEST(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
471TEST(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
572TEST(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
637TEST(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
788TEST(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
808TEST(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
823TEST(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
900TEST(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
943TEST(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
956TEST(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
976TEST(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
1009TEST(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
1049TEST(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
1083TEST(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
1097TEST(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
1112TEST(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
1139TEST(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
1164TEST(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
1179bool 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
1203TEST(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
1228TEST(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
1386TEST(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
1408TEST(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
1429TEST(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
1449TEST(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
1468TEST(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
1552TEST(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
1572TEST(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
1603TEST(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
1615TEST(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.
1633TEST(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
1648TEST(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
1666