blob: 09634fd0158fe3188ba0ef79f19dfb25982be18d [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/actor/site_policy.h"
#include "base/base64.h"
#include "base/command_line.h"
#include "base/metrics/field_trial_params.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "chrome/browser/actor/actor_features.h"
#include "chrome/browser/optimization_guide/browser_test_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/optimization_guide/core/bloom_filter.h"
#include "components/optimization_guide/core/optimization_guide_switches.h"
#include "components/optimization_guide/proto/hints.pb.h"
#include "components/safe_browsing/buildflags.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/browser_test.h"
#include "net/dns/mock_host_resolver.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
#include "chrome/browser/safe_browsing/test_safe_browsing_service.h"
#include "components/safe_browsing/core/browser/db/fake_database_manager.h"
#include "components/safe_browsing/core/common/features.h"
#endif
namespace actor {
namespace {
class ActorSitePolicyBrowserTest : public InProcessBrowserTest {
public:
ActorSitePolicyBrowserTest() {
base::FieldTrialParams params;
params["allowlist"] = "a.com,b.com";
params["allowlist_only"] = "false";
scoped_feature_list_.InitAndEnableFeatureWithParameters(
kGlicActionAllowlist, std::move(params));
}
~ActorSitePolicyBrowserTest() override = default;
void SetUpCommandLine(base::CommandLine* command_line) override {
InProcessBrowserTest::SetUpCommandLine(command_line);
constexpr std::string kBlockedHost = "bar.com";
constexpr uint32_t kNumHashFunctions = 7;
constexpr uint32_t kNumBits = 511;
optimization_guide::BloomFilter blocklist_bloom_filter(kNumHashFunctions,
kNumBits);
blocklist_bloom_filter.Add(kBlockedHost);
std::string blocklist_bloom_filter_data(
reinterpret_cast<const char*>(&blocklist_bloom_filter.bytes()[0]),
blocklist_bloom_filter.bytes().size());
optimization_guide::proto::Configuration config;
optimization_guide::proto::OptimizationFilter*
blocklist_optimization_filter = config.add_optimization_blocklists();
blocklist_optimization_filter->set_optimization_type(
optimization_guide::proto::GLIC_ACTION_PAGE_BLOCK);
blocklist_optimization_filter->mutable_bloom_filter()
->set_num_hash_functions(kNumHashFunctions);
blocklist_optimization_filter->mutable_bloom_filter()->set_num_bits(
kNumBits);
blocklist_optimization_filter->mutable_bloom_filter()->set_data(
blocklist_bloom_filter_data);
std::string encoded_config;
config.SerializeToString(&encoded_config);
encoded_config = base::Base64Encode(encoded_config);
command_line->AppendSwitchASCII(
optimization_guide::switches::kHintsProtoOverride, encoded_config);
}
void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();
host_resolver()->AddRule("*", "127.0.0.1");
ASSERT_TRUE(embedded_https_test_server().Start());
// Optimization guide uses this histogram to signal initialization in tests.
optimization_guide::RetryForHistogramUntilCountReached(
&histogram_tester_for_init_,
"OptimizationGuide.HintsManager.HintCacheInitialized", 1);
InitActionBlocklist(browser()->profile());
}
protected:
void CheckUrl(const GURL& url, bool expected_allowed) {
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
base::test::TestFuture<bool> allowed;
MayActOnTab(*browser()->tab_strip_model()->GetActiveTab(),
allowed.GetCallback());
// The result should not be provided synchronously.
EXPECT_FALSE(allowed.IsReady());
EXPECT_EQ(expected_allowed, allowed.Get());
}
private:
base::HistogramTester histogram_tester_for_init_;
base::test::ScopedFeatureList scoped_feature_list_;
};
IN_PROC_BROWSER_TEST_F(ActorSitePolicyBrowserTest, Basic) {
const GURL allowed_url =
embedded_https_test_server().GetURL("a.com", "/title1.html");
CheckUrl(allowed_url, true);
}
IN_PROC_BROWSER_TEST_F(ActorSitePolicyBrowserTest, AllowIfNotInBlocklist) {
const GURL allowed_url =
embedded_https_test_server().GetURL("c.com", "/title1.html");
CheckUrl(allowed_url, true);
}
IN_PROC_BROWSER_TEST_F(ActorSitePolicyBrowserTest, BlockIfInBlocklist) {
const GURL blocked_url =
embedded_https_test_server().GetURL("bar.com", "/title1.html");
CheckUrl(blocked_url, false);
}
IN_PROC_BROWSER_TEST_F(ActorSitePolicyBrowserTest,
BlockSubdomainIfInBlocklist) {
const GURL blocked_url =
embedded_https_test_server().GetURL("sub.bar.com", "/title1.html");
CheckUrl(blocked_url, false);
}
#if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
class ActorSitePolicySafeBrowsingBrowserTest
: public ActorSitePolicyBrowserTest {
public:
ActorSitePolicySafeBrowsingBrowserTest() = default;
~ActorSitePolicySafeBrowsingBrowserTest() override = default;
protected:
void CreatedBrowserMainParts(
content::BrowserMainParts* browser_main_parts) override {
fake_safe_browsing_database_manager_ =
base::MakeRefCounted<safe_browsing::FakeSafeBrowsingDatabaseManager>(
content::GetUIThreadTaskRunner({}));
safe_browsing_factory_.SetTestDatabaseManager(
fake_safe_browsing_database_manager_.get());
safe_browsing::SafeBrowsingService::RegisterFactory(
&safe_browsing_factory_);
ActorSitePolicyBrowserTest::CreatedBrowserMainParts(browser_main_parts);
}
void TearDown() override {
safe_browsing::SafeBrowsingService::RegisterFactory(nullptr);
ActorSitePolicyBrowserTest::TearDown();
}
void AddDangerousUrl(const GURL& dangerous_url) {
fake_safe_browsing_database_manager_->AddDangerousUrl(
dangerous_url, safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_MALWARE);
}
void AddPhishingUrl(const GURL& phishing_url) {
fake_safe_browsing_database_manager_->AddDangerousUrl(
phishing_url, safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING);
}
private:
scoped_refptr<safe_browsing::FakeSafeBrowsingDatabaseManager>
fake_safe_browsing_database_manager_;
safe_browsing::TestSafeBrowsingServiceFactory safe_browsing_factory_;
};
class ActorSitePolicyDelayedWarningBrowserTest
: public ActorSitePolicySafeBrowsingBrowserTest {
public:
ActorSitePolicyDelayedWarningBrowserTest() {
scoped_feature_list_.InitAndEnableFeature(safe_browsing::kDelayedWarnings);
}
~ActorSitePolicyDelayedWarningBrowserTest() override = default;
private:
base::test::ScopedFeatureList scoped_feature_list_;
};
IN_PROC_BROWSER_TEST_F(ActorSitePolicySafeBrowsingBrowserTest,
BlockDangerousSite) {
const GURL dangerous_url =
embedded_https_test_server().GetURL("c.com", "/title1.html");
AddDangerousUrl(dangerous_url);
CheckUrl(dangerous_url, false);
}
IN_PROC_BROWSER_TEST_F(ActorSitePolicyDelayedWarningBrowserTest,
BlockPhishingSiteWithDelayedWarning) {
const GURL phishing_url =
embedded_https_test_server().GetURL("c.com", "/title1.html");
AddPhishingUrl(phishing_url);
CheckUrl(phishing_url, false);
}
#endif // BUILDFLAG(SAFE_BROWSING_AVAILABLE)
} // namespace
} // namespace actor