| 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 |