| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "chrome/browser/extensions/api/developer_private/developer_private_api.
h" | 5 #include "chrome/browser/extensions/api/developer_private/developer_private_api.
h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
| 11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
| 13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
| 14 #include "chrome/browser/chrome_notification_types.h" |
| 14 #include "chrome/browser/extensions/error_console/error_console.h" | 15 #include "chrome/browser/extensions/error_console/error_console.h" |
| 15 #include "chrome/browser/extensions/extension_function_test_utils.h" | 16 #include "chrome/browser/extensions/extension_function_test_utils.h" |
| 16 #include "chrome/browser/extensions/extension_service.h" | 17 #include "chrome/browser/extensions/extension_service.h" |
| 17 #include "chrome/browser/extensions/extension_service_test_base.h" | 18 #include "chrome/browser/extensions/extension_service_test_with_install.h" |
| 18 #include "chrome/browser/extensions/extension_util.h" | 19 #include "chrome/browser/extensions/extension_util.h" |
| 19 #include "chrome/browser/extensions/scripting_permissions_modifier.h" | 20 #include "chrome/browser/extensions/scripting_permissions_modifier.h" |
| 20 #include "chrome/browser/extensions/test_extension_dir.h" | 21 #include "chrome/browser/extensions/test_extension_dir.h" |
| 21 #include "chrome/browser/extensions/test_extension_system.h" | 22 #include "chrome/browser/extensions/test_extension_system.h" |
| 22 #include "chrome/browser/extensions/unpacked_installer.h" | 23 #include "chrome/browser/extensions/unpacked_installer.h" |
| 23 #include "chrome/browser/ui/browser.h" | 24 #include "chrome/browser/ui/browser.h" |
| 24 #include "chrome/common/extensions/api/developer_private.h" | 25 #include "chrome/common/extensions/api/developer_private.h" |
| 25 #include "chrome/common/pref_names.h" | 26 #include "chrome/common/pref_names.h" |
| 26 #include "chrome/test/base/test_browser_window.h" | 27 #include "chrome/test/base/test_browser_window.h" |
| 27 #include "components/crx_file/id_util.h" | 28 #include "components/crx_file/id_util.h" |
| 28 #include "components/policy/core/browser/browser_policy_connector.h" | 29 #include "components/policy/core/browser/browser_policy_connector.h" |
| 29 #include "components/policy/core/common/mock_configuration_policy_provider.h" | 30 #include "components/policy/core/common/mock_configuration_policy_provider.h" |
| 30 #include "components/policy/core/common/policy_map.h" | 31 #include "components/policy/core/common/policy_map.h" |
| 31 #include "components/policy/core/common/policy_service_impl.h" | 32 #include "components/policy/core/common/policy_service_impl.h" |
| 32 #include "components/policy/core/common/policy_types.h" | 33 #include "components/policy/core/common/policy_types.h" |
| 33 #include "components/policy/policy_constants.h" | 34 #include "components/policy/policy_constants.h" |
| 34 #include "components/sync_preferences/testing_pref_service_syncable.h" | 35 #include "components/sync_preferences/testing_pref_service_syncable.h" |
| 36 #include "content/public/browser/notification_service.h" |
| 35 #include "content/public/test/web_contents_tester.h" | 37 #include "content/public/test/web_contents_tester.h" |
| 36 #include "extensions/browser/api_test_utils.h" | 38 #include "extensions/browser/api_test_utils.h" |
| 37 #include "extensions/browser/event_router_factory.h" | 39 #include "extensions/browser/event_router_factory.h" |
| 38 #include "extensions/browser/extension_error_test_util.h" | 40 #include "extensions/browser/extension_error_test_util.h" |
| 39 #include "extensions/browser/extension_prefs.h" | 41 #include "extensions/browser/extension_prefs.h" |
| 40 #include "extensions/browser/extension_registry.h" | 42 #include "extensions/browser/extension_registry.h" |
| 41 #include "extensions/browser/extension_system.h" | 43 #include "extensions/browser/extension_system.h" |
| 42 #include "extensions/browser/extension_util.h" | 44 #include "extensions/browser/extension_util.h" |
| 45 #include "extensions/browser/mock_external_provider.h" |
| 43 #include "extensions/browser/test_extension_registry_observer.h" | 46 #include "extensions/browser/test_extension_registry_observer.h" |
| 44 #include "extensions/common/extension.h" | 47 #include "extensions/common/extension.h" |
| 45 #include "extensions/common/extension_builder.h" | 48 #include "extensions/common/extension_builder.h" |
| 46 #include "extensions/common/extension_set.h" | 49 #include "extensions/common/extension_set.h" |
| 47 #include "extensions/common/feature_switch.h" | 50 #include "extensions/common/feature_switch.h" |
| 48 #include "extensions/common/manifest_constants.h" | 51 #include "extensions/common/manifest_constants.h" |
| 49 #include "extensions/common/test_util.h" | 52 #include "extensions/common/test_util.h" |
| 50 #include "extensions/common/value_builder.h" | 53 #include "extensions/common/value_builder.h" |
| 51 | 54 |
| 52 using testing::Return; | 55 using testing::Return; |
| 53 using testing::_; | 56 using testing::_; |
| 54 | 57 |
| 55 namespace extensions { | 58 namespace extensions { |
| 56 | 59 |
| 57 namespace { | 60 namespace { |
| 58 | 61 |
| 62 const char kGoodCrx[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; |
| 63 |
| 59 std::unique_ptr<KeyedService> BuildAPI(content::BrowserContext* context) { | 64 std::unique_ptr<KeyedService> BuildAPI(content::BrowserContext* context) { |
| 60 return base::MakeUnique<DeveloperPrivateAPI>(context); | 65 return base::MakeUnique<DeveloperPrivateAPI>(context); |
| 61 } | 66 } |
| 62 | 67 |
| 63 std::unique_ptr<KeyedService> BuildEventRouter( | 68 std::unique_ptr<KeyedService> BuildEventRouter( |
| 64 content::BrowserContext* profile) { | 69 content::BrowserContext* profile) { |
| 65 return base::MakeUnique<EventRouter>(profile, ExtensionPrefs::Get(profile)); | 70 return base::MakeUnique<EventRouter>(profile, ExtensionPrefs::Get(profile)); |
| 66 } | 71 } |
| 67 | 72 |
| 68 bool HasAllUrlsPermission(const Extension* extension, | 73 bool HasAllUrlsPermission(const Extension* extension, |
| 69 content::BrowserContext* context) { | 74 content::BrowserContext* context) { |
| 70 return ScriptingPermissionsModifier(context, extension).IsAllowedOnAllUrls(); | 75 return ScriptingPermissionsModifier(context, extension).IsAllowedOnAllUrls(); |
| 71 } | 76 } |
| 72 | 77 |
| 73 bool HasPrefsPermission(bool (*has_pref)(const std::string&, | 78 bool HasPrefsPermission(bool (*has_pref)(const std::string&, |
| 74 content::BrowserContext*), | 79 content::BrowserContext*), |
| 75 content::BrowserContext* context, | 80 content::BrowserContext* context, |
| 76 const std::string& id) { | 81 const std::string& id) { |
| 77 return has_pref(id, context); | 82 return has_pref(id, context); |
| 78 } | 83 } |
| 79 | 84 |
| 80 } // namespace | 85 } // namespace |
| 81 | 86 |
| 82 class DeveloperPrivateApiUnitTest : public ExtensionServiceTestBase { | 87 class DeveloperPrivateApiUnitTest : public ExtensionServiceTestWithInstall { |
| 83 protected: | 88 protected: |
| 84 DeveloperPrivateApiUnitTest() {} | 89 DeveloperPrivateApiUnitTest() {} |
| 85 ~DeveloperPrivateApiUnitTest() override {} | 90 ~DeveloperPrivateApiUnitTest() override {} |
| 86 | 91 |
| 92 void AddMockExternalProvider( |
| 93 std::unique_ptr<ExternalProviderInterface> provider) { |
| 94 service()->AddProviderForTesting(std::move(provider)); |
| 95 } |
| 96 |
| 87 // A wrapper around extension_function_test_utils::RunFunction that runs with | 97 // A wrapper around extension_function_test_utils::RunFunction that runs with |
| 88 // the associated browser, no flags, and can take stack-allocated arguments. | 98 // the associated browser, no flags, and can take stack-allocated arguments. |
| 89 bool RunFunction(const scoped_refptr<UIThreadExtensionFunction>& function, | 99 bool RunFunction(const scoped_refptr<UIThreadExtensionFunction>& function, |
| 90 const base::ListValue& args); | 100 const base::ListValue& args); |
| 91 | 101 |
| 92 // Loads an unpacked extension that is backed by a real directory, allowing | 102 // Loads an unpacked extension that is backed by a real directory, allowing |
| 93 // it to be reloaded. | 103 // it to be reloaded. |
| 94 const Extension* LoadUnpackedExtension(); | 104 const Extension* LoadUnpackedExtension(); |
| 95 | 105 |
| 96 // Loads an extension with no real directory; this is faster, but means the | 106 // Loads an extension with no real directory; this is faster, but means the |
| (...skipping 750 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 ListBuilder() | 857 ListBuilder() |
| 848 .Append( | 858 .Append( |
| 849 DictionaryBuilder().Set("extensionId", extension->id()).Build()) | 859 DictionaryBuilder().Set("extensionId", extension->id()).Build()) |
| 850 .Build(); | 860 .Build(); |
| 851 function = new api::DeveloperPrivateDeleteExtensionErrorsFunction(); | 861 function = new api::DeveloperPrivateDeleteExtensionErrorsFunction(); |
| 852 EXPECT_TRUE(RunFunction(function, *args)) << function->GetError(); | 862 EXPECT_TRUE(RunFunction(function, *args)) << function->GetError(); |
| 853 // No more errors! | 863 // No more errors! |
| 854 EXPECT_TRUE(error_console->GetErrorsForExtension(extension->id()).empty()); | 864 EXPECT_TRUE(error_console->GetErrorsForExtension(extension->id()).empty()); |
| 855 } | 865 } |
| 856 | 866 |
| 867 // Tests that developerPrivate.repair does not succeed for a non-corrupted |
| 868 // extension. |
| 869 TEST_F(DeveloperPrivateApiUnitTest, RepairNotBrokenExtension) { |
| 870 base::FilePath extension_path = data_dir().AppendASCII("good.crx"); |
| 871 const Extension* extension = InstallCRX(extension_path, INSTALL_NEW); |
| 872 |
| 873 // Attempt to repair the good extension, expect failure. |
| 874 std::unique_ptr<base::ListValue> args = |
| 875 ListBuilder().Append(extension->id()).Build(); |
| 876 scoped_refptr<UIThreadExtensionFunction> function = |
| 877 new api::DeveloperPrivateRepairExtensionFunction(); |
| 878 EXPECT_FALSE(RunFunction(function, *args)); |
| 879 EXPECT_EQ("Cannot repair a healthy extension.", function->GetError()); |
| 880 } |
| 881 |
| 882 // Tests that developerPrivate.private cannot repair a policy-installed |
| 883 // extension. |
| 884 // Regression test for https://crbug.com/577959. |
| 885 TEST_F(DeveloperPrivateApiUnitTest, RepairPolicyExtension) { |
| 886 std::string extension_id(kGoodCrx); |
| 887 |
| 888 // Set up a mock provider with a policy extension. |
| 889 std::unique_ptr<MockExternalProvider> mock_provider = |
| 890 base::MakeUnique<MockExternalProvider>( |
| 891 service(), Manifest::EXTERNAL_POLICY_DOWNLOAD); |
| 892 MockExternalProvider* mock_provider_ptr = mock_provider.get(); |
| 893 AddMockExternalProvider(std::move(mock_provider)); |
| 894 mock_provider_ptr->UpdateOrAddExtension(extension_id, "1.0.0.0", |
| 895 data_dir().AppendASCII("good.crx")); |
| 896 // Reloading extensions should find our externally registered extension |
| 897 // and install it. |
| 898 content::WindowedNotificationObserver observer( |
| 899 extensions::NOTIFICATION_CRX_INSTALLER_DONE, |
| 900 content::NotificationService::AllSources()); |
| 901 service()->CheckForExternalUpdates(); |
| 902 observer.Wait(); |
| 903 |
| 904 // Attempt to repair the good extension, expect failure. |
| 905 std::unique_ptr<base::ListValue> args = |
| 906 ListBuilder().Append(extension_id).Build(); |
| 907 scoped_refptr<UIThreadExtensionFunction> function = |
| 908 new api::DeveloperPrivateRepairExtensionFunction(); |
| 909 EXPECT_FALSE(RunFunction(function, *args)); |
| 910 EXPECT_EQ("Cannot repair a healthy extension.", function->GetError()); |
| 911 |
| 912 // Corrupt the extension , still expect repair failure because this is a |
| 913 // policy extension. |
| 914 service()->DisableExtension(extension_id, Extension::DISABLE_CORRUPTED); |
| 915 args = ListBuilder().Append(extension_id).Build(); |
| 916 function = new api::DeveloperPrivateRepairExtensionFunction(); |
| 917 EXPECT_FALSE(RunFunction(function, *args)); |
| 918 EXPECT_EQ("Cannot repair a policy-installed extension.", |
| 919 function->GetError()); |
| 920 } |
| 921 |
| 857 // Test developerPrivate.updateProfileConfiguration: Try to turn on devMode | 922 // Test developerPrivate.updateProfileConfiguration: Try to turn on devMode |
| 858 // when DeveloperToolsDisabled policy is active. | 923 // when DeveloperToolsDisabled policy is active. |
| 859 TEST_F(DeveloperPrivateApiUnitTest, DeveloperPrivateDevModeDisabledPolicy) { | 924 TEST_F(DeveloperPrivateApiUnitTest, DeveloperPrivateDevModeDisabledPolicy) { |
| 860 testing_pref_service()->SetManagedPref(prefs::kExtensionsUIDeveloperMode, | 925 testing_pref_service()->SetManagedPref(prefs::kExtensionsUIDeveloperMode, |
| 861 base::MakeUnique<base::Value>(false)); | 926 base::MakeUnique<base::Value>(false)); |
| 862 | 927 |
| 863 UpdateProfileConfigurationDevMode(true); | 928 UpdateProfileConfigurationDevMode(true); |
| 864 | 929 |
| 865 EXPECT_FALSE( | 930 EXPECT_FALSE( |
| 866 profile()->GetPrefs()->GetBoolean(prefs::kExtensionsUIDeveloperMode)); | 931 profile()->GetPrefs()->GetBoolean(prefs::kExtensionsUIDeveloperMode)); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 882 EXPECT_TRUE( | 947 EXPECT_TRUE( |
| 883 profile()->GetPrefs()->GetBoolean(prefs::kExtensionsUIDeveloperMode)); | 948 profile()->GetPrefs()->GetBoolean(prefs::kExtensionsUIDeveloperMode)); |
| 884 | 949 |
| 885 std::unique_ptr<api::developer_private::ProfileInfo> profile_info; | 950 std::unique_ptr<api::developer_private::ProfileInfo> profile_info; |
| 886 ASSERT_NO_FATAL_FAILURE(GetProfileConfiguration(&profile_info)); | 951 ASSERT_NO_FATAL_FAILURE(GetProfileConfiguration(&profile_info)); |
| 887 EXPECT_TRUE(profile_info->in_developer_mode); | 952 EXPECT_TRUE(profile_info->in_developer_mode); |
| 888 EXPECT_FALSE(profile_info->is_developer_mode_controlled_by_policy); | 953 EXPECT_FALSE(profile_info->is_developer_mode_controlled_by_policy); |
| 889 } | 954 } |
| 890 | 955 |
| 891 } // namespace extensions | 956 } // namespace extensions |
| OLD | NEW |