OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/files/file_path.h" | 5 #include "base/files/file_path.h" |
6 #include "base/json/json_file_value_serializer.h" | 6 #include "base/json/json_file_value_serializer.h" |
7 #include "base/memory/ref_counted.h" | 7 #include "base/memory/ref_counted.h" |
8 #include "base/run_loop.h" | 8 #include "base/run_loop.h" |
9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
11 #include "chrome/browser/chrome_notification_types.h" | 11 #include "chrome/browser/chrome_notification_types.h" |
12 #include "chrome/browser/extensions/extension_service.h" | 12 #include "chrome/browser/extensions/extension_service.h" |
13 #include "chrome/browser/extensions/extension_service_test_base.h" | 13 #include "chrome/browser/extensions/extension_service_test_base.h" |
| 14 #include "chrome/browser/extensions/extension_util.h" |
14 #include "chrome/browser/extensions/permissions_updater.h" | 15 #include "chrome/browser/extensions/permissions_updater.h" |
15 #include "chrome/common/chrome_paths.h" | 16 #include "chrome/common/chrome_paths.h" |
16 #include "chrome/common/extensions/extension_test_util.h" | 17 #include "chrome/common/extensions/extension_test_util.h" |
17 #include "chrome/test/base/testing_profile.h" | 18 #include "chrome/test/base/testing_profile.h" |
| 19 #include "components/crx_file/id_util.h" |
18 #include "content/public/browser/notification_observer.h" | 20 #include "content/public/browser/notification_observer.h" |
19 #include "content/public/browser/notification_registrar.h" | 21 #include "content/public/browser/notification_registrar.h" |
20 #include "content/public/browser/notification_service.h" | 22 #include "content/public/browser/notification_service.h" |
21 #include "extensions/browser/extension_prefs.h" | 23 #include "extensions/browser/extension_prefs.h" |
22 #include "extensions/common/extension.h" | 24 #include "extensions/common/extension.h" |
23 #include "extensions/common/extension_builder.h" | 25 #include "extensions/common/extension_builder.h" |
24 #include "extensions/common/feature_switch.h" | 26 #include "extensions/common/feature_switch.h" |
25 #include "extensions/common/permissions/permission_set.h" | 27 #include "extensions/common/permissions/permission_set.h" |
26 #include "extensions/common/permissions/permissions_data.h" | 28 #include "extensions/common/permissions/permissions_data.h" |
27 #include "extensions/common/value_builder.h" | 29 #include "extensions/common/value_builder.h" |
28 #include "testing/gtest/include/gtest/gtest.h" | 30 #include "testing/gtest/include/gtest/gtest.h" |
29 | 31 |
30 using extension_test_util::LoadManifest; | 32 using extension_test_util::LoadManifest; |
31 | 33 |
32 namespace extensions { | 34 namespace extensions { |
33 | 35 |
34 namespace { | 36 namespace { |
35 | 37 |
36 scoped_refptr<const Extension> CreateExtensionWithPermissions( | 38 scoped_refptr<const Extension> CreateExtensionWithPermissions( |
37 const std::set<URLPattern>& scriptable_hosts, | 39 const std::set<URLPattern>& scriptable_hosts, |
38 const std::set<URLPattern>& explicit_hosts, | 40 const std::set<URLPattern>& explicit_hosts, |
39 Manifest::Location location) { | 41 Manifest::Location location, |
| 42 const std::string& name) { |
40 ListBuilder scriptable_host_list; | 43 ListBuilder scriptable_host_list; |
41 for (std::set<URLPattern>::const_iterator pattern = scriptable_hosts.begin(); | 44 for (std::set<URLPattern>::const_iterator pattern = scriptable_hosts.begin(); |
42 pattern != scriptable_hosts.end(); | 45 pattern != scriptable_hosts.end(); |
43 ++pattern) { | 46 ++pattern) { |
44 scriptable_host_list.Append(pattern->GetAsString()); | 47 scriptable_host_list.Append(pattern->GetAsString()); |
45 } | 48 } |
46 | 49 |
47 ListBuilder explicit_host_list; | 50 ListBuilder explicit_host_list; |
48 for (std::set<URLPattern>::const_iterator pattern = explicit_hosts.begin(); | 51 for (std::set<URLPattern>::const_iterator pattern = explicit_hosts.begin(); |
49 pattern != explicit_hosts.end(); | 52 pattern != explicit_hosts.end(); |
50 ++pattern) { | 53 ++pattern) { |
51 explicit_host_list.Append(pattern->GetAsString()); | 54 explicit_host_list.Append(pattern->GetAsString()); |
52 } | 55 } |
53 | 56 |
54 DictionaryBuilder script; | 57 DictionaryBuilder script; |
55 script.Set("matches", scriptable_host_list.Pass()) | 58 script.Set("matches", scriptable_host_list.Pass()) |
56 .Set("js", ListBuilder().Append("foo.js")); | 59 .Set("js", ListBuilder().Append("foo.js")); |
57 | 60 |
58 return ExtensionBuilder() | 61 return ExtensionBuilder() |
59 .SetLocation(location) | 62 .SetLocation(location) |
60 .SetManifest( | 63 .SetManifest( |
61 DictionaryBuilder() | 64 DictionaryBuilder() |
62 .Set("name", "extension") | 65 .Set("name", name) |
63 .Set("description", "foo") | 66 .Set("description", "foo") |
64 .Set("manifest_version", 2) | 67 .Set("manifest_version", 2) |
65 .Set("version", "0.1.2.3") | 68 .Set("version", "0.1.2.3") |
66 .Set("content_scripts", ListBuilder().Append(script.Pass())) | 69 .Set("content_scripts", ListBuilder().Append(script.Pass())) |
67 .Set("permissions", explicit_host_list.Pass())) | 70 .Set("permissions", explicit_host_list.Pass())) |
| 71 .SetID(crx_file::id_util::GenerateId(name)) |
68 .Build(); | 72 .Build(); |
69 } | 73 } |
70 | 74 |
71 testing::AssertionResult SetsAreEqual(const std::set<URLPattern>& set1, | 75 testing::AssertionResult SetsAreEqual(const std::set<URLPattern>& set1, |
72 const std::set<URLPattern>& set2) { | 76 const std::set<URLPattern>& set2) { |
73 // Take the (set1 - set2) U (set2 - set1). This is then the set of all | 77 // Take the (set1 - set2) U (set2 - set1). This is then the set of all |
74 // elements which are in either set1 or set2, but not both. | 78 // elements which are in either set1 or set2, but not both. |
75 // If the sets are equal, this is none. | 79 // If the sets are equal, this is none. |
76 std::set<URLPattern> difference = base::STLSetUnion<std::set<URLPattern> >( | 80 std::set<URLPattern> difference = base::STLSetUnion<std::set<URLPattern> >( |
77 base::STLSetDifference<std::set<URLPattern> >(set1, set2), | 81 base::STLSetDifference<std::set<URLPattern> >(set1, set2), |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 all_host_patterns.insert(all_hosts); | 297 all_host_patterns.insert(all_hosts); |
294 all_host_patterns.insert(all_com); | 298 all_host_patterns.insert(all_com); |
295 | 299 |
296 safe_patterns.insert(google); | 300 safe_patterns.insert(google); |
297 safe_patterns.insert(sub_google); | 301 safe_patterns.insert(sub_google); |
298 | 302 |
299 std::set<URLPattern> all_patterns = base::STLSetUnion<std::set<URLPattern> >( | 303 std::set<URLPattern> all_patterns = base::STLSetUnion<std::set<URLPattern> >( |
300 all_host_patterns, safe_patterns); | 304 all_host_patterns, safe_patterns); |
301 | 305 |
302 scoped_refptr<const Extension> extension = CreateExtensionWithPermissions( | 306 scoped_refptr<const Extension> extension = CreateExtensionWithPermissions( |
303 all_patterns, all_patterns, Manifest::INTERNAL); | 307 all_patterns, all_patterns, Manifest::INTERNAL, "a"); |
304 const PermissionsData* permissions_data = extension->permissions_data(); | 308 const PermissionsData* permissions_data = extension->permissions_data(); |
305 PermissionsUpdater updater(profile_.get()); | 309 PermissionsUpdater updater(profile_.get()); |
306 updater.InitializePermissions(extension.get()); | 310 updater.InitializePermissions(extension.get()); |
307 | 311 |
308 // At first, the active permissions should have only the safe patterns and | 312 // At first, the active permissions should have only the safe patterns and |
309 // the withheld permissions should have only the all host patterns. | 313 // the withheld permissions should have only the all host patterns. |
310 EXPECT_TRUE(SetsAreEqual( | 314 EXPECT_TRUE(SetsAreEqual( |
311 permissions_data->active_permissions()->scriptable_hosts().patterns(), | 315 permissions_data->active_permissions()->scriptable_hosts().patterns(), |
312 safe_patterns)); | 316 safe_patterns)); |
313 EXPECT_TRUE(SetsAreEqual( | 317 EXPECT_TRUE(SetsAreEqual( |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 safe_patterns)); | 356 safe_patterns)); |
353 EXPECT_TRUE(SetsAreEqual( | 357 EXPECT_TRUE(SetsAreEqual( |
354 permissions_data->withheld_permissions()->scriptable_hosts().patterns(), | 358 permissions_data->withheld_permissions()->scriptable_hosts().patterns(), |
355 all_host_patterns)); | 359 all_host_patterns)); |
356 EXPECT_TRUE(SetsAreEqual( | 360 EXPECT_TRUE(SetsAreEqual( |
357 permissions_data->withheld_permissions()->explicit_hosts().patterns(), | 361 permissions_data->withheld_permissions()->explicit_hosts().patterns(), |
358 all_host_patterns)); | 362 all_host_patterns)); |
359 | 363 |
360 // Creating a component extension should result in no withheld permissions. | 364 // Creating a component extension should result in no withheld permissions. |
361 extension = CreateExtensionWithPermissions( | 365 extension = CreateExtensionWithPermissions( |
362 all_patterns, all_patterns, Manifest::COMPONENT); | 366 all_patterns, all_patterns, Manifest::COMPONENT, "b"); |
363 permissions_data = extension->permissions_data(); | 367 permissions_data = extension->permissions_data(); |
364 updater.InitializePermissions(extension.get()); | 368 updater.InitializePermissions(extension.get()); |
365 EXPECT_TRUE(SetsAreEqual( | 369 EXPECT_TRUE(SetsAreEqual( |
366 permissions_data->active_permissions()->scriptable_hosts().patterns(), | 370 permissions_data->active_permissions()->scriptable_hosts().patterns(), |
367 all_patterns)); | 371 all_patterns)); |
368 EXPECT_TRUE(permissions_data->withheld_permissions() | 372 EXPECT_TRUE(permissions_data->withheld_permissions() |
369 ->scriptable_hosts() | 373 ->scriptable_hosts() |
370 .patterns() | 374 .patterns() |
371 .empty()); | 375 .empty()); |
372 EXPECT_TRUE(SetsAreEqual( | 376 EXPECT_TRUE(SetsAreEqual( |
373 permissions_data->active_permissions()->explicit_hosts().patterns(), | 377 permissions_data->active_permissions()->explicit_hosts().patterns(), |
374 all_patterns)); | 378 all_patterns)); |
375 EXPECT_TRUE(permissions_data->withheld_permissions() | 379 EXPECT_TRUE(permissions_data->withheld_permissions() |
376 ->explicit_hosts() | 380 ->explicit_hosts() |
377 .patterns() | 381 .patterns() |
378 .empty()); | 382 .empty()); |
379 | 383 |
380 // Without the switch, we shouldn't withhold anything. | 384 // Without the switch, we shouldn't withhold anything. |
381 switch_override.reset(); | 385 switch_override.reset(); |
382 extension = CreateExtensionWithPermissions( | 386 extension = CreateExtensionWithPermissions( |
383 all_patterns, all_patterns, Manifest::INTERNAL); | 387 all_patterns, all_patterns, Manifest::INTERNAL, "c"); |
384 permissions_data = extension->permissions_data(); | 388 permissions_data = extension->permissions_data(); |
385 updater.InitializePermissions(extension.get()); | 389 updater.InitializePermissions(extension.get()); |
386 EXPECT_TRUE(SetsAreEqual( | 390 EXPECT_TRUE(SetsAreEqual( |
387 permissions_data->active_permissions()->scriptable_hosts().patterns(), | 391 permissions_data->active_permissions()->scriptable_hosts().patterns(), |
388 all_patterns)); | 392 all_patterns)); |
389 EXPECT_TRUE(permissions_data->withheld_permissions() | 393 EXPECT_TRUE(permissions_data->withheld_permissions() |
390 ->scriptable_hosts() | 394 ->scriptable_hosts() |
391 .patterns() | 395 .patterns() |
392 .empty()); | 396 .empty()); |
393 EXPECT_TRUE(SetsAreEqual( | 397 EXPECT_TRUE(SetsAreEqual( |
394 permissions_data->active_permissions()->explicit_hosts().patterns(), | 398 permissions_data->active_permissions()->explicit_hosts().patterns(), |
395 all_patterns)); | 399 all_patterns)); |
396 EXPECT_TRUE(permissions_data->withheld_permissions() | 400 EXPECT_TRUE(permissions_data->withheld_permissions() |
397 ->explicit_hosts() | 401 ->explicit_hosts() |
398 .patterns() | 402 .patterns() |
399 .empty()); | 403 .empty()); |
400 } | 404 } |
401 | 405 |
| 406 // Tests that withholding all hosts behaves properly with extensions installed |
| 407 // when the switch is turned on and off. |
| 408 TEST_F(PermissionsUpdaterTest, WithholdAllHostsWithTransientSwitch) { |
| 409 InitializeEmptyExtensionService(); |
| 410 |
| 411 URLPattern all_hosts(URLPattern::SCHEME_ALL, "<all_urls>"); |
| 412 std::set<URLPattern> all_host_patterns; |
| 413 all_host_patterns.insert(all_hosts); |
| 414 |
| 415 scoped_refptr<const Extension> extension_a = CreateExtensionWithPermissions( |
| 416 all_host_patterns, all_host_patterns, Manifest::INTERNAL, "a"); |
| 417 PermissionsUpdater updater(profile()); |
| 418 updater.InitializePermissions(extension_a.get()); |
| 419 const PermissionsData* permissions_data = extension_a->permissions_data(); |
| 420 |
| 421 // Since the extension was created without the switch on, it should default |
| 422 // to having all urls access. |
| 423 EXPECT_TRUE(SetsAreEqual( |
| 424 permissions_data->active_permissions()->scriptable_hosts().patterns(), |
| 425 all_host_patterns)); |
| 426 EXPECT_TRUE( |
| 427 permissions_data->withheld_permissions()->scriptable_hosts().is_empty()); |
| 428 EXPECT_TRUE(util::AllowedScriptingOnAllUrls(extension_a->id(), profile())); |
| 429 |
| 430 // Enable the switch, and re-init permission for the extension. |
| 431 scoped_ptr<FeatureSwitch::ScopedOverride> switch_override( |
| 432 new FeatureSwitch::ScopedOverride(FeatureSwitch::scripts_require_action(), |
| 433 FeatureSwitch::OVERRIDE_ENABLED)); |
| 434 updater.InitializePermissions(extension_a.get()); |
| 435 |
| 436 // Since the extension was installed when the switch was off, it should still |
| 437 // have the all urls pref. |
| 438 permissions_data = extension_a->permissions_data(); |
| 439 EXPECT_TRUE(SetsAreEqual( |
| 440 permissions_data->active_permissions()->scriptable_hosts().patterns(), |
| 441 all_host_patterns)); |
| 442 EXPECT_TRUE( |
| 443 permissions_data->withheld_permissions()->scriptable_hosts().is_empty()); |
| 444 EXPECT_TRUE(util::AllowedScriptingOnAllUrls(extension_a->id(), profile())); |
| 445 |
| 446 // Load a new extension, which also has all urls. Since the switch is now on, |
| 447 // the permissions should be withheld. |
| 448 scoped_refptr<const Extension> extension_b = CreateExtensionWithPermissions( |
| 449 all_host_patterns, all_host_patterns, Manifest::INTERNAL, "b"); |
| 450 updater.InitializePermissions(extension_b.get()); |
| 451 permissions_data = extension_b->permissions_data(); |
| 452 |
| 453 EXPECT_TRUE( |
| 454 permissions_data->active_permissions()->scriptable_hosts().is_empty()); |
| 455 EXPECT_TRUE(SetsAreEqual( |
| 456 permissions_data->withheld_permissions()->scriptable_hosts().patterns(), |
| 457 all_host_patterns)); |
| 458 EXPECT_FALSE(util::AllowedScriptingOnAllUrls(extension_b->id(), profile())); |
| 459 |
| 460 // Disable the switch, and reload the extension. |
| 461 switch_override.reset(); |
| 462 updater.InitializePermissions(extension_b.get()); |
| 463 |
| 464 // Since the extension was installed with the switch on, it should still be |
| 465 // restricted with the switch off. |
| 466 permissions_data = extension_b->permissions_data(); |
| 467 EXPECT_TRUE( |
| 468 permissions_data->active_permissions()->scriptable_hosts().is_empty()); |
| 469 EXPECT_TRUE(SetsAreEqual( |
| 470 permissions_data->withheld_permissions()->scriptable_hosts().patterns(), |
| 471 all_host_patterns)); |
| 472 EXPECT_FALSE(util::AllowedScriptingOnAllUrls(extension_b->id(), profile())); |
| 473 } |
| 474 |
402 } // namespace extensions | 475 } // namespace extensions |
OLD | NEW |