diff --git a/android/android_browser_tests.gni b/android/android_browser_tests.gni index 28c4737b9016..ddb6e9828b23 100644 --- a/android/android_browser_tests.gni +++ b/android/android_browser_tests.gni @@ -38,6 +38,7 @@ android_test_exception_sources = [ "//brave/browser/extensions/brave_extension_functional_test.h", "//brave/browser/extensions/brave_extension_provider_browsertest.cc", "//brave/browser/extensions/brave_theme_event_router_browsertest.cc", + "//brave/browser/extensions/extension_system_browsertest.cc", "//brave/browser/perf/brave_perf_features_processor_browsertest.cc", "//brave/browser/policy/brave_policy_browsertest.cc", "//brave/browser/renderer_context_menu/brave_mock_render_view_context_menu.cc", diff --git a/browser/brave_browser_main_parts.cc b/browser/brave_browser_main_parts.cc index fec164cdd759..667ae94d173a 100644 --- a/browser/brave_browser_main_parts.cc +++ b/browser/brave_browser_main_parts.cc @@ -15,6 +15,7 @@ #include "brave/components/brave_sync/features.h" #include "brave/components/constants/brave_constants.h" #include "brave/components/constants/pref_names.h" +#include "brave/components/greaselion/browser/buildflags/buildflags.h" #include "brave/components/speedreader/common/buildflags/buildflags.h" #include "brave/components/tor/buildflags/buildflags.h" #include "brave/components/translate/core/common/brave_translate_features.h" @@ -63,6 +64,11 @@ #include "chrome/browser/browser_process.h" #endif +#if BUILDFLAG(ENABLE_GREASELION) +#include "brave/browser/greaselion/greaselion_service_factory.h" +#include "brave/components/greaselion/browser/greaselion_service.h" +#endif + #if BUILDFLAG(ETHEREUM_REMOTE_CLIENT_ENABLED) && BUILDFLAG(ENABLE_EXTENSIONS) #include "brave/browser/extensions/brave_component_loader.h" #include "chrome/browser/extensions/extension_service.h" @@ -185,6 +191,16 @@ void BraveBrowserMainParts::PostProfileInit(Profile* profile, } #endif +#if BUILDFLAG(ENABLE_GREASELION) + if (auto* greaselion_service = + greaselion::GreaselionServiceFactory::GetForBrowserContext(profile)) { + extensions::ExtensionService* extension_service = + extensions::ExtensionSystem::Get(profile)->extension_service(); + DCHECK(extension_service); + greaselion_service->SetExtensionService(extension_service); + } +#endif + #if BUILDFLAG(ETHEREUM_REMOTE_CLIENT_ENABLED) && BUILDFLAG(ENABLE_EXTENSIONS) extensions::ExtensionService* service = extensions::ExtensionSystem::Get(profile)->extension_service(); diff --git a/browser/extensions/extension_system_browsertest.cc b/browser/extensions/extension_system_browsertest.cc new file mode 100644 index 000000000000..88871dc68900 --- /dev/null +++ b/browser/extensions/extension_system_browsertest.cc @@ -0,0 +1,89 @@ +/* Copyright (c) 2023 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "base/path_service.h" +#include "base/strings/stringprintf.h" +#include "brave/components/constants/brave_paths.h" +#include "chrome/browser/extensions/extension_browsertest.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/content_mock_cert_verifier.h" +#include "net/dns/mock_host_resolver.h" +#include "services/network/public/cpp/network_switches.h" + +using extensions::ExtensionBrowserTest; + +class ExtensionSystemBrowserTest : public ExtensionBrowserTest { + public: + ExtensionSystemBrowserTest() { + brave::RegisterPathProvider(); + dir_test_data_ = base::PathService::CheckedGet(brave::DIR_TEST_DATA); + + https_server_ = std::make_unique( + net::test_server::EmbeddedTestServer::TYPE_HTTPS); + https_server_->ServeFilesFromDirectory(dir_test_data_); + EXPECT_TRUE(https_server_->Start()); + } + + void SetUpOnMainThread() override { + ExtensionBrowserTest::SetUpOnMainThread(); + host_resolver()->AddRule("*", "127.0.0.1"); + mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + ExtensionBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitchASCII( + network::switches::kHostResolverRules, + base::StringPrintf("MAP *:443 127.0.0.1:%d", https_server_->port())); + mock_cert_verifier_.SetUpCommandLine(command_line); + } + + void SetUpInProcessBrowserTestFixture() override { + ExtensionBrowserTest::SetUpInProcessBrowserTestFixture(); + mock_cert_verifier_.SetUpInProcessBrowserTestFixture(); + } + + void TearDownInProcessBrowserTestFixture() override { + mock_cert_verifier_.TearDownInProcessBrowserTestFixture(); + ExtensionBrowserTest::TearDownInProcessBrowserTestFixture(); + } + + void NavigateAndExpectErrorPage(const GURL& url, bool expect_error_page) { + SCOPED_TRACE(url); + auto* rfh = ui_test_utils::NavigateToURL(browser(), url); + ASSERT_TRUE(rfh); + EXPECT_EQ(rfh->IsErrorDocument(), expect_error_page); + } + + protected: + base::FilePath dir_test_data_; + content::ContentMockCertVerifier mock_cert_verifier_; + std::unique_ptr https_server_; +}; + +IN_PROC_BROWSER_TEST_F(ExtensionSystemBrowserTest, + PRE_DeclarativeNetRequestWorksAfterRestart) { + NavigateAndExpectErrorPage(GURL("https://a.com/simple.html"), false); + NavigateAndExpectErrorPage(GURL("https://b.com/simple.html"), false); + + // Load extension that should block b.com main frame via declarative net + // requests feature. + ASSERT_TRUE(InstallExtensionWithPermissionsGranted( + dir_test_data_.AppendASCII("extensions") + .AppendASCII("declarative_net_request"), + 1)); + + NavigateAndExpectErrorPage(GURL("https://a.com/simple.html"), false); + NavigateAndExpectErrorPage(GURL("https://b.com/simple.html"), true); +} + +IN_PROC_BROWSER_TEST_F(ExtensionSystemBrowserTest, + DeclarativeNetRequestWorksAfterRestart) { + // After a browser restart the extensions should work as expected. + NavigateAndExpectErrorPage(GURL("https://a.com/simple.html"), false); + NavigateAndExpectErrorPage(GURL("https://b.com/simple.html"), true); +} diff --git a/browser/greaselion/greaselion_service_factory.cc b/browser/greaselion/greaselion_service_factory.cc index 9f6e2b3060b8..057d657c819c 100644 --- a/browser/greaselion/greaselion_service_factory.cc +++ b/browser/greaselion/greaselion_service_factory.cc @@ -58,7 +58,6 @@ KeyedService* GreaselionServiceFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { extensions::ExtensionSystem* extension_system = extensions::ExtensionSystem::Get(context); - extension_system->InitForRegularProfile(true /* extensions_enabled */); extensions::ExtensionRegistry* extension_registry = extensions::ExtensionRegistry::Get(context); scoped_refptr task_runner = diff --git a/components/greaselion/browser/greaselion_service.h b/components/greaselion/browser/greaselion_service.h index 52406e800035..05c2a86368fb 100644 --- a/components/greaselion/browser/greaselion_service.h +++ b/components/greaselion/browser/greaselion_service.h @@ -22,6 +22,10 @@ namespace base { class Version; } +namespace extensions { +class ExtensionService; +} + namespace greaselion { enum GreaselionFeature { @@ -45,6 +49,8 @@ class GreaselionService : public KeyedService, // KeyedService void Shutdown() override {} + virtual void SetExtensionService( + extensions::ExtensionService* extension_service) = 0; virtual void SetFeatureEnabled(GreaselionFeature feature, bool enabled) = 0; virtual void UpdateInstalledExtensions() = 0; virtual bool IsGreaselionExtension(const std::string& id) = 0; diff --git a/components/greaselion/browser/greaselion_service_impl.cc b/components/greaselion/browser/greaselion_service_impl.cc index f4519dac469c..dfce273ef643 100644 --- a/components/greaselion/browser/greaselion_service_impl.cc +++ b/components/greaselion/browser/greaselion_service_impl.cc @@ -226,7 +226,6 @@ GreaselionServiceImpl::GreaselionServiceImpl( : download_service_(download_service), install_directory_(install_directory), extension_system_(extension_system), - extension_service_(extension_system->extension_service()), extension_registry_(extension_registry), all_rules_installed_successfully_(true), update_in_progress_(false), @@ -253,6 +252,13 @@ void GreaselionServiceImpl::Shutdown() { base::BindOnce(&DeleteExtensionDirs, extension_dirs_)); } +void GreaselionServiceImpl::SetExtensionService( + extensions::ExtensionService* extension_service) { + DCHECK(extension_service); + DCHECK(!extension_service_); + extension_service_ = extension_service; +} + bool GreaselionServiceImpl::IsGreaselionExtension(const std::string& id) { return base::Contains(greaselion_extensions_, id); } diff --git a/components/greaselion/browser/greaselion_service_impl.h b/components/greaselion/browser/greaselion_service_impl.h index 5b812a0cc6e6..96616249b90f 100644 --- a/components/greaselion/browser/greaselion_service_impl.h +++ b/components/greaselion/browser/greaselion_service_impl.h @@ -50,6 +50,8 @@ class GreaselionServiceImpl : public GreaselionService, void Shutdown() override; // GreaselionService overrides + void SetExtensionService( + extensions::ExtensionService* extension_service) override; void SetFeatureEnabled(GreaselionFeature feature, bool enabled) override; void UpdateInstalledExtensions() override; bool IsGreaselionExtension(const std::string& id) override; @@ -85,8 +87,6 @@ class GreaselionServiceImpl : public GreaselionService, const base::FilePath install_directory_; raw_ptr extension_system_ = nullptr; // NOT OWNED - raw_ptr extension_service_ = - nullptr; // NOT OWNED raw_ptr extension_registry_ = nullptr; // NOT OWNED bool all_rules_installed_successfully_; @@ -98,6 +98,8 @@ class GreaselionServiceImpl : public GreaselionService, std::vector greaselion_extensions_; std::vector extension_dirs_; base::Version browser_version_; + raw_ptr extension_service_ = + nullptr; // NOT OWNED base::WeakPtrFactory weak_factory_; }; diff --git a/test/BUILD.gn b/test/BUILD.gn index 29b15b0f67cb..fbe5c1c62bbf 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -759,6 +759,7 @@ test("brave_browser_tests") { "//brave/browser/extensions/brave_extension_functional_test.h", "//brave/browser/extensions/brave_extension_provider_browsertest.cc", "//brave/browser/extensions/brave_theme_event_router_browsertest.cc", + "//brave/browser/extensions/extension_system_browsertest.cc", "//brave/browser/perf/brave_perf_features_processor_browsertest.cc", "//brave/browser/policy/brave_policy_browsertest.cc", "//brave/browser/profiles/brave_profile_manager_browsertest.cc", diff --git a/test/data/extensions/declarative_net_request/manifest.json b/test/data/extensions/declarative_net_request/manifest.json new file mode 100644 index 000000000000..de97790b5d38 --- /dev/null +++ b/test/data/extensions/declarative_net_request/manifest.json @@ -0,0 +1,18 @@ +{ + "name": "Declarative net request", + "version": "0.1", + "manifest_version": 3, + "background": {}, + "permissions": ["declarativeNetRequest"], + "declarative_net_request": { + "rule_resources": [ + { + "id": "rules", + "enabled": true, + "path": "rules.json" + } + ] + }, + "host_permissions": ["*://*/*"], + "action": {} +} diff --git a/test/data/extensions/declarative_net_request/rules.json b/test/data/extensions/declarative_net_request/rules.json new file mode 100644 index 000000000000..7435076bc660 --- /dev/null +++ b/test/data/extensions/declarative_net_request/rules.json @@ -0,0 +1,13 @@ +[ + { + "id": 1, + "priority": 1, + "action": { + "type": "block" + }, + "condition": { + "urlFilter": "https://b.com/*", + "resourceTypes": ["main_frame"] + } + } +]