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