Commit 425f8559 authored by David Dorwin's avatar David Dorwin Committed by Commit Bot

Extract Safe Sites from blocklist policy

Although PolicyBlocklistNavigationThrottle uses Safe Sites, blocklists
and Safe Sites are conceptually different. Also, Safe Sites does not
require Prefs, which makes it easier to use outside //chrome.

Also extract SafeSearchService from PolicyBlocklistService.

Bug: 1147231
Change-Id: I4e2714478177bebcf26a07ed0e6230aa67e0792f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2530145
Auto-Submit: David Dorwin <ddorwin@chromium.org>
Reviewed-by: default avatarOwen Min <zmin@chromium.org>
Reviewed-by: default avatarNicolas Ouellet-Payeur <nicolaso@chromium.org>
Commit-Queue: David Dorwin <ddorwin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826798}
parent 1589e87b
...@@ -6,6 +6,25 @@ import("//build/config/features.gni") ...@@ -6,6 +6,25 @@ import("//build/config/features.gni")
assert(!is_ios, "Policy Throttle should not be referenced on iOS") assert(!is_ios, "Policy Throttle should not be referenced on iOS")
source_set("safe_sites_navigation_throttle") {
sources = [
"safe_search_service.cc",
"safe_search_service.h",
"safe_sites_navigation_throttle.cc",
"safe_sites_navigation_throttle.h",
]
deps = [
"//base",
"//components/keyed_service/content:content",
"//components/policy/core/browser",
"//components/safe_search_api",
"//components/safe_search_api:safe_search_client",
"//content/public/browser",
"//net",
]
}
source_set("content") { source_set("content") {
sources = [ sources = [
"policy_blocklist_navigation_throttle.cc", "policy_blocklist_navigation_throttle.cc",
...@@ -15,15 +34,12 @@ source_set("content") { ...@@ -15,15 +34,12 @@ source_set("content") {
] ]
deps = [ deps = [
"//base", ":safe_sites_navigation_throttle",
"//components/keyed_service/content:content", "//components/keyed_service/content:content",
"//components/policy/core/browser", "//components/policy/core/browser",
"//components/prefs", "//components/prefs",
"//components/safe_search_api",
"//components/safe_search_api:safe_search_client",
"//components/user_prefs:user_prefs", "//components/user_prefs:user_prefs",
"//content/public/browser", "//content/public/browser",
"//net",
] ]
} }
...@@ -32,6 +48,7 @@ source_set("unit_tests") { ...@@ -32,6 +48,7 @@ source_set("unit_tests") {
sources = [ "policy_blocklist_navigation_throttle_unittest.cc" ] sources = [ "policy_blocklist_navigation_throttle_unittest.cc" ]
deps = [ deps = [
":content", ":content",
":safe_sites_navigation_throttle",
"//base", "//base",
"//components/keyed_service/content", "//components/keyed_service/content",
"//components/policy/core/browser", "//components/policy/core/browser",
......
...@@ -6,11 +6,9 @@ ...@@ -6,11 +6,9 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/check_op.h" #include "base/check_op.h"
#include "base/strings/string_piece.h"
#include "components/policy/content/policy_blocklist_service.h" #include "components/policy/content/policy_blocklist_service.h"
#include "components/policy/core/browser/url_blocklist_manager.h" #include "components/policy/core/browser/url_blocklist_manager.h"
#include "components/policy/core/browser/url_blocklist_policy_handler.h" #include "components/policy/core/browser/url_blocklist_policy_handler.h"
#include "components/policy/core/browser/url_util.h"
#include "components/policy/core/common/policy_pref_names.h" #include "components/policy/core/common/policy_pref_names.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "components/user_prefs/user_prefs.h" #include "components/user_prefs/user_prefs.h"
...@@ -21,29 +19,30 @@ ...@@ -21,29 +19,30 @@
using URLBlocklistState = policy::URLBlocklist::URLBlocklistState; using URLBlocklistState = policy::URLBlocklist::URLBlocklistState;
using SafeSitesFilterBehavior = policy::SafeSitesFilterBehavior; using SafeSitesFilterBehavior = policy::SafeSitesFilterBehavior;
// Passing an Unretained pointer for the safe_sites_navigation_throttle_
// callback is safe because this object owns safe_sites_navigation_throttle_,
// which runs the callback from within the object.
PolicyBlocklistNavigationThrottle::PolicyBlocklistNavigationThrottle( PolicyBlocklistNavigationThrottle::PolicyBlocklistNavigationThrottle(
content::NavigationHandle* navigation_handle, content::NavigationHandle* navigation_handle,
content::BrowserContext* context) content::BrowserContext* context)
: NavigationThrottle(navigation_handle), : content::NavigationThrottle(navigation_handle),
safe_sites_navigation_throttle_(
navigation_handle,
context,
base::BindRepeating(
&PolicyBlocklistNavigationThrottle::OnDeferredSafeSitesResult,
base::Unretained(this))),
blocklist_service_(PolicyBlocklistFactory::GetForBrowserContext(context)), blocklist_service_(PolicyBlocklistFactory::GetForBrowserContext(context)),
prefs_(user_prefs::UserPrefs::Get(context)) { prefs_(user_prefs::UserPrefs::Get(context)) {
DCHECK(prefs_); DCHECK(prefs_);
} }
PolicyBlocklistNavigationThrottle::PolicyBlocklistNavigationThrottle(
content::NavigationHandle* navigation_handle,
content::BrowserContext* context,
base::StringPiece safe_sites_error_page_content)
: PolicyBlocklistNavigationThrottle(navigation_handle, context) {
safe_sites_error_page_content_ = safe_sites_error_page_content.as_string();
}
PolicyBlocklistNavigationThrottle::~PolicyBlocklistNavigationThrottle() = PolicyBlocklistNavigationThrottle::~PolicyBlocklistNavigationThrottle() =
default; default;
content::NavigationThrottle::ThrottleCheckResult content::NavigationThrottle::ThrottleCheckResult
PolicyBlocklistNavigationThrottle::WillStartRequest() { PolicyBlocklistNavigationThrottle::WillStartRequest() {
GURL url = navigation_handle()->GetURL(); const GURL& url = navigation_handle()->GetURL();
// Ignore blob scheme because we may use it to deliver navigation responses // Ignore blob scheme because we may use it to deliver navigation responses
// to the renderer process. // to the renderer process.
...@@ -63,12 +62,11 @@ PolicyBlocklistNavigationThrottle::WillStartRequest() { ...@@ -63,12 +62,11 @@ PolicyBlocklistNavigationThrottle::WillStartRequest() {
return CheckSafeSitesFilter(url); return CheckSafeSitesFilter(url);
} }
// SafeSitesNavigationThrottle is unconditional and does not check PrefService
// because it is used outside //chrome. Therefore, the policy must be checked
// here to determine whether to use SafeSitesNavigationThrottle.
content::NavigationThrottle::ThrottleCheckResult content::NavigationThrottle::ThrottleCheckResult
PolicyBlocklistNavigationThrottle::CheckSafeSitesFilter(const GURL& url) { PolicyBlocklistNavigationThrottle::CheckSafeSitesFilter(const GURL& url) {
// Safe Sites filter applies to top-level HTTP[S] requests.
if (!url.SchemeIsHTTPOrHTTPS())
return PROCEED;
SafeSitesFilterBehavior filter_behavior = SafeSitesFilterBehavior filter_behavior =
static_cast<SafeSitesFilterBehavior>( static_cast<SafeSitesFilterBehavior>(
prefs_->GetInteger(policy::policy_prefs::kSafeSitesFilterBehavior)); prefs_->GetInteger(policy::policy_prefs::kSafeSitesFilterBehavior));
...@@ -76,25 +74,7 @@ PolicyBlocklistNavigationThrottle::CheckSafeSitesFilter(const GURL& url) { ...@@ -76,25 +74,7 @@ PolicyBlocklistNavigationThrottle::CheckSafeSitesFilter(const GURL& url) {
return PROCEED; return PROCEED;
DCHECK_EQ(filter_behavior, SafeSitesFilterBehavior::kSafeSitesFilterEnabled); DCHECK_EQ(filter_behavior, SafeSitesFilterBehavior::kSafeSitesFilterEnabled);
return safe_sites_navigation_throttle_.WillStartRequest();
GURL effective_url = policy::url_util::GetEmbeddedURL(url);
if (!effective_url.is_valid())
effective_url = url;
bool synchronous = blocklist_service_->CheckSafeSearchURL(
effective_url,
base::BindOnce(
&PolicyBlocklistNavigationThrottle::CheckSafeSearchCallback,
weak_ptr_factory_.GetWeakPtr()));
if (!synchronous) {
deferred_ = true;
return DEFER;
}
if (should_cancel_)
return ThrottleCheckResult(CANCEL, net::ERR_BLOCKED_BY_ADMINISTRATOR,
safe_sites_error_page_content_);
return PROCEED;
} }
content::NavigationThrottle::ThrottleCheckResult content::NavigationThrottle::ThrottleCheckResult
...@@ -106,18 +86,12 @@ const char* PolicyBlocklistNavigationThrottle::GetNameForLogging() { ...@@ -106,18 +86,12 @@ const char* PolicyBlocklistNavigationThrottle::GetNameForLogging() {
return "PolicyBlocklistNavigationThrottle"; return "PolicyBlocklistNavigationThrottle";
} }
void PolicyBlocklistNavigationThrottle::CheckSafeSearchCallback(bool is_safe) { void PolicyBlocklistNavigationThrottle::OnDeferredSafeSitesResult(
if (!deferred_) { bool is_safe,
should_cancel_ = !is_safe; ThrottleCheckResult cancel_result) {
return;
}
deferred_ = false;
if (is_safe) { if (is_safe) {
Resume(); Resume();
} else { } else {
CancelDeferredNavigation( CancelDeferredNavigation(cancel_result);
ThrottleCheckResult(CANCEL, net::ERR_BLOCKED_BY_ADMINISTRATOR,
safe_sites_error_page_content_));
} }
} }
\ No newline at end of file
...@@ -5,20 +5,13 @@ ...@@ -5,20 +5,13 @@
#ifndef COMPONENTS_POLICY_CONTENT_POLICY_BLOCKLIST_NAVIGATION_THROTTLE_H_ #ifndef COMPONENTS_POLICY_CONTENT_POLICY_BLOCKLIST_NAVIGATION_THROTTLE_H_
#define COMPONENTS_POLICY_CONTENT_POLICY_BLOCKLIST_NAVIGATION_THROTTLE_H_ #define COMPONENTS_POLICY_CONTENT_POLICY_BLOCKLIST_NAVIGATION_THROTTLE_H_
#include "base/macros.h" #include "components/policy/content/safe_sites_navigation_throttle.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string_piece_forward.h"
#include "content/public/browser/navigation_throttle.h" #include "content/public/browser/navigation_throttle.h"
class GURL; class GURL;
class PolicyBlocklistService; class PolicyBlocklistService;
class PrefService; class PrefService;
namespace content {
class BrowserContext;
class NavigationHandle;
} // namespace content
// PolicyBlocklistNavigationThrottle provides a simple way to block a navigation // PolicyBlocklistNavigationThrottle provides a simple way to block a navigation
// based on the URLBlocklistManager and Safe Search API. If the URL is on the // based on the URLBlocklistManager and Safe Search API. If the URL is on the
// blocklist or allowlist, the throttle will immediately block or allow the // blocklist or allowlist, the throttle will immediately block or allow the
...@@ -30,10 +23,10 @@ class PolicyBlocklistNavigationThrottle : public content::NavigationThrottle { ...@@ -30,10 +23,10 @@ class PolicyBlocklistNavigationThrottle : public content::NavigationThrottle {
PolicyBlocklistNavigationThrottle( PolicyBlocklistNavigationThrottle(
content::NavigationHandle* navigation_handle, content::NavigationHandle* navigation_handle,
content::BrowserContext* context); content::BrowserContext* context);
PolicyBlocklistNavigationThrottle( PolicyBlocklistNavigationThrottle(const PolicyBlocklistNavigationThrottle&) =
content::NavigationHandle* navigation_handle, delete;
content::BrowserContext* context, PolicyBlocklistNavigationThrottle& operator=(
base::StringPiece safe_sites_error_page_content); const PolicyBlocklistNavigationThrottle&) = delete;
~PolicyBlocklistNavigationThrottle() override; ~PolicyBlocklistNavigationThrottle() override;
// NavigationThrottle overrides. // NavigationThrottle overrides.
...@@ -42,30 +35,17 @@ class PolicyBlocklistNavigationThrottle : public content::NavigationThrottle { ...@@ -42,30 +35,17 @@ class PolicyBlocklistNavigationThrottle : public content::NavigationThrottle {
const char* GetNameForLogging() override; const char* GetNameForLogging() override;
private: private:
// To ensure both allow and block policies override Safe Sites,
// SafeSitesNavigationThrottle must be consulted as part of this throttle
// rather than added separately to the list of throttles.
ThrottleCheckResult CheckSafeSitesFilter(const GURL& url); ThrottleCheckResult CheckSafeSitesFilter(const GURL& url);
void OnDeferredSafeSitesResult(bool is_safe,
// Callback from PolicyBlocklistService. ThrottleCheckResult cancel_result);
void CheckSafeSearchCallback(bool is_safe); SafeSitesNavigationThrottle safe_sites_navigation_throttle_;
PolicyBlocklistService* blocklist_service_; PolicyBlocklistService* blocklist_service_;
PrefService* prefs_; PrefService* prefs_;
// HTML to be displayed when navigation is canceled by the Safe Sites filter.
// If null, a default error page will be displayed.
base::Optional<std::string> safe_sites_error_page_content_;
// Whether the request was deferred in order to check the Safe Search API.
bool deferred_ = false;
// Whether the Safe Search API callback determined the in-progress navigation
// should be canceled.
bool should_cancel_ = false;
base::WeakPtrFactory<PolicyBlocklistNavigationThrottle> weak_ptr_factory_{
this};
DISALLOW_COPY_AND_ASSIGN(PolicyBlocklistNavigationThrottle);
}; };
#endif // COMPONENTS_POLICY_CONTENT_POLICY_BLOCKLIST_NAVIGATION_THROTTLE_H_ #endif // COMPONENTS_POLICY_CONTENT_POLICY_BLOCKLIST_NAVIGATION_THROTTLE_H_
...@@ -2,16 +2,15 @@ ...@@ -2,16 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "components/policy/content/policy_blocklist_navigation_throttle.h"
#include <memory> #include <memory>
#include <string> #include <string>
#include <utility> #include <utility>
#include "base/macros.h"
#include "base/values.h" #include "base/values.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/policy/content/policy_blocklist_service.h" #include "components/policy/content/policy_blocklist_navigation_throttle.h"
#include "components/policy/content/safe_search_service.h"
#include "components/policy/content/safe_sites_navigation_throttle.h"
#include "components/policy/core/browser/url_blocklist_manager.h" #include "components/policy/core/browser/url_blocklist_manager.h"
#include "components/policy/core/browser/url_blocklist_policy_handler.h" #include "components/policy/core/browser/url_blocklist_policy_handler.h"
#include "components/policy/core/common/policy_pref_names.h" #include "components/policy/core/common/policy_pref_names.h"
...@@ -36,20 +35,23 @@ constexpr size_t kCacheSize = 2; ...@@ -36,20 +35,23 @@ constexpr size_t kCacheSize = 2;
} // namespace } // namespace
class PolicyBlocklistNavigationThrottleTest // TODO(crbug.com/1147231): Break out the tests into separate files. The
// SafeSites tests should be parameterized to run the same tests on both types.
class SafeSitesNavigationThrottleTest
: public content::RenderViewHostTestHarness, : public content::RenderViewHostTestHarness,
public content::WebContentsObserver { public content::WebContentsObserver {
public: public:
PolicyBlocklistNavigationThrottleTest() = default; SafeSitesNavigationThrottleTest() = default;
~PolicyBlocklistNavigationThrottleTest() override = default; SafeSitesNavigationThrottleTest(const SafeSitesNavigationThrottleTest&) =
delete;
SafeSitesNavigationThrottleTest& operator=(
const SafeSitesNavigationThrottleTest&) = delete;
~SafeSitesNavigationThrottleTest() override = default;
// content::RenderViewHostTestHarness: // content::RenderViewHostTestHarness:
void SetUp() override { void SetUp() override {
content::RenderViewHostTestHarness::SetUp(); content::RenderViewHostTestHarness::SetUp();
user_prefs::UserPrefs::Set(browser_context(), &pref_service_);
policy::URLBlocklistManager::RegisterProfilePrefs(pref_service_.registry());
// Prevent crashes in BrowserContextDependencyManager caused when tests // Prevent crashes in BrowserContextDependencyManager caused when tests
// that run in serial happen to reuse a memory address for a BrowserContext // that run in serial happen to reuse a memory address for a BrowserContext
// from a previously-run test. // from a previously-run test.
...@@ -58,7 +60,7 @@ class PolicyBlocklistNavigationThrottleTest ...@@ -58,7 +60,7 @@ class PolicyBlocklistNavigationThrottleTest
BrowserContextDependencyManager::GetInstance()->MarkBrowserContextLive( BrowserContextDependencyManager::GetInstance()->MarkBrowserContextLive(
browser_context()); browser_context());
PolicyBlocklistFactory::GetInstance() SafeSearchFactory::GetInstance()
->GetForBrowserContext(browser_context()) ->GetForBrowserContext(browser_context())
->SetSafeSearchURLCheckerForTest( ->SetSafeSearchURLCheckerForTest(
stub_url_checker_.BuildURLChecker(kCacheSize)); stub_url_checker_.BuildURLChecker(kCacheSize));
...@@ -73,16 +75,16 @@ class PolicyBlocklistNavigationThrottleTest ...@@ -73,16 +75,16 @@ class PolicyBlocklistNavigationThrottleTest
content::RenderViewHostTestHarness::TearDown(); content::RenderViewHostTestHarness::TearDown();
} }
protected:
// content::WebContentsObserver: // content::WebContentsObserver:
void DidStartNavigation( void DidStartNavigation(
content::NavigationHandle* navigation_handle) override { content::NavigationHandle* navigation_handle) override {
auto throttle = std::make_unique<PolicyBlocklistNavigationThrottle>( auto throttle = std::make_unique<SafeSitesNavigationThrottle>(
navigation_handle, browser_context()); navigation_handle, browser_context());
navigation_handle->RegisterThrottleForTesting(std::move(throttle)); navigation_handle->RegisterThrottleForTesting(std::move(throttle));
} }
protected:
std::unique_ptr<content::NavigationSimulator> StartNavigation( std::unique_ptr<content::NavigationSimulator> StartNavigation(
const GURL& first_url) { const GURL& first_url) {
auto navigation_simulator = auto navigation_simulator =
...@@ -93,6 +95,61 @@ class PolicyBlocklistNavigationThrottleTest ...@@ -93,6 +95,61 @@ class PolicyBlocklistNavigationThrottleTest
return navigation_simulator; return navigation_simulator;
} }
// Tests that redirects from a safe site to a porn site are handled correctly.
// Also tests the same scenario when the sites are in the cache.
// If |expected_error_page_content| is not null, the canceled throttle check
// result's error_page_content will be expected to match it.
void TestSafeSitesRedirectAndCachedSites(
const char* expected_error_page_content);
// Tests responses for both a safe site and a porn site both when the sites
// are in the cache and not. If |expected_error_page_content| is not null, the
// canceled throttle check result's error_page_content will be expected to
// match it.
void TestSafeSitesCachedSites(const char* expected_error_page_content);
safe_search_api::StubURLChecker stub_url_checker_;
};
class SafeSitesNavigationThrottleWithErrorContentTest
: public SafeSitesNavigationThrottleTest {
protected:
static const char kErrorPageContent[];
// content::WebContentsObserver:
void DidStartNavigation(
content::NavigationHandle* navigation_handle) override {
auto throttle = std::make_unique<SafeSitesNavigationThrottle>(
navigation_handle, browser_context(), kErrorPageContent);
navigation_handle->RegisterThrottleForTesting(std::move(throttle));
}
};
const char
SafeSitesNavigationThrottleWithErrorContentTest::kErrorPageContent[] =
"<html><body>URL was filtered.</body></html>";
class PolicyBlocklistNavigationThrottleTest
: public SafeSitesNavigationThrottleTest {
public:
void SetUp() override {
SafeSitesNavigationThrottleTest::SetUp();
user_prefs::UserPrefs::Set(browser_context(), &pref_service_);
policy::URLBlocklistManager::RegisterProfilePrefs(pref_service_.registry());
}
protected:
// content::WebContentsObserver:
void DidStartNavigation(
content::NavigationHandle* navigation_handle) override {
auto throttle = std::make_unique<PolicyBlocklistNavigationThrottle>(
navigation_handle, browser_context());
navigation_handle->RegisterThrottleForTesting(std::move(throttle));
}
void SetBlocklistUrlPattern(const std::string& pattern) { void SetBlocklistUrlPattern(const std::string& pattern) {
auto value = std::make_unique<base::Value>(base::Value::Type::LIST); auto value = std::make_unique<base::Value>(base::Value::Type::LIST);
value->Append(base::Value(pattern)); value->Append(base::Value(pattern));
...@@ -117,29 +174,8 @@ class PolicyBlocklistNavigationThrottleTest ...@@ -117,29 +174,8 @@ class PolicyBlocklistNavigationThrottleTest
} }
sync_preferences::TestingPrefServiceSyncable pref_service_; sync_preferences::TestingPrefServiceSyncable pref_service_;
safe_search_api::StubURLChecker stub_url_checker_;
private:
DISALLOW_COPY_AND_ASSIGN(PolicyBlocklistNavigationThrottleTest);
}; };
class PolicyBlocklistNavigationThrottleWithSafeSitesErrorContentTest
: public PolicyBlocklistNavigationThrottleTest {
public:
static const char kErrorPageContent[];
// content::WebContentsObserver:
void DidStartNavigation(
content::NavigationHandle* navigation_handle) override {
auto throttle = std::make_unique<PolicyBlocklistNavigationThrottle>(
navigation_handle, browser_context(), kErrorPageContent);
navigation_handle->RegisterThrottleForTesting(std::move(throttle));
}
};
const char PolicyBlocklistNavigationThrottleWithSafeSitesErrorContentTest::
kErrorPageContent[] = "<html><body>URL was filtered.</body></html>";
TEST_F(PolicyBlocklistNavigationThrottleTest, Blocklist) { TEST_F(PolicyBlocklistNavigationThrottleTest, Blocklist) {
SetBlocklistUrlPattern("example.com"); SetBlocklistUrlPattern("example.com");
...@@ -257,9 +293,8 @@ TEST_F(PolicyBlocklistNavigationThrottleTest, DISABLED_SafeSites_Failure) { ...@@ -257,9 +293,8 @@ TEST_F(PolicyBlocklistNavigationThrottleTest, DISABLED_SafeSites_Failure) {
navigation_simulator->GetLastThrottleCheckResult()); navigation_simulator->GetLastThrottleCheckResult());
} }
TEST_F(PolicyBlocklistNavigationThrottleTest, SafeSites_CachedSites) { void SafeSitesNavigationThrottleTest::TestSafeSitesCachedSites(
SetSafeSitesFilterBehavior(SafeSitesFilterBehavior::kSafeSitesFilterEnabled); const char* expected_error_page_content) {
// Check a couple of sites. // Check a couple of sites.
ASSERT_EQ(2u, kCacheSize); ASSERT_EQ(2u, kCacheSize);
const GURL safe_site = GURL("http://example.com/"); const GURL safe_site = GURL("http://example.com/");
...@@ -283,9 +318,16 @@ TEST_F(PolicyBlocklistNavigationThrottleTest, SafeSites_CachedSites) { ...@@ -283,9 +318,16 @@ TEST_F(PolicyBlocklistNavigationThrottleTest, SafeSites_CachedSites) {
navigation_simulator->Wait(); navigation_simulator->Wait();
EXPECT_EQ(content::NavigationThrottle::CANCEL, EXPECT_EQ(content::NavigationThrottle::CANCEL,
navigation_simulator->GetLastThrottleCheckResult()); navigation_simulator->GetLastThrottleCheckResult());
if (expected_error_page_content) {
EXPECT_STREQ(expected_error_page_content,
navigation_simulator->GetLastThrottleCheckResult()
.error_page_content()
->c_str());
} else {
EXPECT_FALSE(navigation_simulator->GetLastThrottleCheckResult() EXPECT_FALSE(navigation_simulator->GetLastThrottleCheckResult()
.error_page_content()); .error_page_content());
} }
}
stub_url_checker_.ClearResponses(); stub_url_checker_.ClearResponses();
{ {
...@@ -304,15 +346,33 @@ TEST_F(PolicyBlocklistNavigationThrottleTest, SafeSites_CachedSites) { ...@@ -304,15 +346,33 @@ TEST_F(PolicyBlocklistNavigationThrottleTest, SafeSites_CachedSites) {
ASSERT_FALSE(navigation_simulator->IsDeferred()); ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::CANCEL, EXPECT_EQ(content::NavigationThrottle::CANCEL,
navigation_simulator->GetLastThrottleCheckResult()); navigation_simulator->GetLastThrottleCheckResult());
if (expected_error_page_content) {
EXPECT_STREQ(expected_error_page_content,
navigation_simulator->GetLastThrottleCheckResult()
.error_page_content()
->c_str());
} else {
EXPECT_FALSE(navigation_simulator->GetLastThrottleCheckResult() EXPECT_FALSE(navigation_simulator->GetLastThrottleCheckResult()
.error_page_content()); .error_page_content());
} }
}
} }
TEST_F(PolicyBlocklistNavigationThrottleWithSafeSitesErrorContentTest, TEST_F(SafeSitesNavigationThrottleTest, SafeSites_CachedSites) {
SafeSites_CachedSites) { TestSafeSitesCachedSites(nullptr);
}
TEST_F(SafeSitesNavigationThrottleWithErrorContentTest, SafeSites_CachedSites) {
TestSafeSitesCachedSites(&kErrorPageContent[0]);
}
TEST_F(PolicyBlocklistNavigationThrottleTest, SafeSites_CachedSites) {
SetSafeSitesFilterBehavior(SafeSitesFilterBehavior::kSafeSitesFilterEnabled); SetSafeSitesFilterBehavior(SafeSitesFilterBehavior::kSafeSitesFilterEnabled);
TestSafeSitesCachedSites(nullptr);
}
void SafeSitesNavigationThrottleTest::TestSafeSitesRedirectAndCachedSites(
const char* expected_error_page_content) {
// Check a couple of sites. // Check a couple of sites.
ASSERT_EQ(2u, kCacheSize); ASSERT_EQ(2u, kCacheSize);
const GURL safe_site = GURL("http://example.com/"); const GURL safe_site = GURL("http://example.com/");
...@@ -327,19 +387,22 @@ TEST_F(PolicyBlocklistNavigationThrottleWithSafeSitesErrorContentTest, ...@@ -327,19 +387,22 @@ TEST_F(PolicyBlocklistNavigationThrottleWithSafeSitesErrorContentTest,
navigation_simulator->GetLastThrottleCheckResult()); navigation_simulator->GetLastThrottleCheckResult());
EXPECT_FALSE(navigation_simulator->GetLastThrottleCheckResult() EXPECT_FALSE(navigation_simulator->GetLastThrottleCheckResult()
.error_page_content()); .error_page_content());
}
stub_url_checker_.SetUpValidResponse(true /* is_porn */); stub_url_checker_.SetUpValidResponse(true /* is_porn */);
{ navigation_simulator->Redirect(porn_site);
auto navigation_simulator = StartNavigation(porn_site);
EXPECT_TRUE(navigation_simulator->IsDeferred()); EXPECT_TRUE(navigation_simulator->IsDeferred());
navigation_simulator->Wait(); navigation_simulator->Wait();
EXPECT_EQ(content::NavigationThrottle::CANCEL, EXPECT_EQ(content::NavigationThrottle::CANCEL,
navigation_simulator->GetLastThrottleCheckResult()); navigation_simulator->GetLastThrottleCheckResult());
EXPECT_STREQ(kErrorPageContent, if (expected_error_page_content) {
EXPECT_STREQ(expected_error_page_content,
navigation_simulator->GetLastThrottleCheckResult() navigation_simulator->GetLastThrottleCheckResult()
.error_page_content() .error_page_content()
->c_str()); ->c_str());
} else {
EXPECT_FALSE(navigation_simulator->GetLastThrottleCheckResult()
.error_page_content());
}
} }
stub_url_checker_.ClearResponses(); stub_url_checker_.ClearResponses();
...@@ -351,17 +414,35 @@ TEST_F(PolicyBlocklistNavigationThrottleWithSafeSitesErrorContentTest, ...@@ -351,17 +414,35 @@ TEST_F(PolicyBlocklistNavigationThrottleWithSafeSitesErrorContentTest,
navigation_simulator->GetLastThrottleCheckResult()); navigation_simulator->GetLastThrottleCheckResult());
EXPECT_FALSE(navigation_simulator->GetLastThrottleCheckResult() EXPECT_FALSE(navigation_simulator->GetLastThrottleCheckResult()
.error_page_content()); .error_page_content());
}
{ navigation_simulator->Redirect(porn_site);
// This check is synchronous since the site is in the cache.
auto navigation_simulator = StartNavigation(porn_site);
ASSERT_FALSE(navigation_simulator->IsDeferred()); ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::CANCEL, EXPECT_EQ(content::NavigationThrottle::CANCEL,
navigation_simulator->GetLastThrottleCheckResult()); navigation_simulator->GetLastThrottleCheckResult());
EXPECT_STREQ(kErrorPageContent, if (expected_error_page_content) {
EXPECT_STREQ(expected_error_page_content,
navigation_simulator->GetLastThrottleCheckResult() navigation_simulator->GetLastThrottleCheckResult()
.error_page_content() .error_page_content()
->c_str()); ->c_str());
} else {
EXPECT_FALSE(navigation_simulator->GetLastThrottleCheckResult()
.error_page_content());
} }
}
}
TEST_F(SafeSitesNavigationThrottleTest, SafeSites_RedirectAndCachedSites) {
TestSafeSitesRedirectAndCachedSites(nullptr);
}
TEST_F(SafeSitesNavigationThrottleWithErrorContentTest,
SafeSites_RedirectAndCachedSites) {
TestSafeSitesRedirectAndCachedSites(&kErrorPageContent[0]);
}
TEST_F(PolicyBlocklistNavigationThrottleTest,
SafeSites_RedirectAndCachedSites) {
SetSafeSitesFilterBehavior(SafeSitesFilterBehavior::kSafeSitesFilterEnabled);
TestSafeSitesRedirectAndCachedSites(nullptr);
} }
...@@ -7,35 +7,14 @@ ...@@ -7,35 +7,14 @@
#include <utility> #include <utility>
#include "base/bind.h" #include "base/bind.h"
#include "base/sequence_checker.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/policy/core/browser/url_util.h"
#include "components/safe_search_api/safe_search/safe_search_url_checker_client.h"
#include "components/safe_search_api/url_checker.h"
#include "components/user_prefs/user_prefs.h" #include "components/user_prefs/user_prefs.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "content/public/browser/storage_partition.h" #include "content/public/browser/storage_partition.h"
#include "net/base/net_errors.h"
namespace {
// Calls the PolicyBlocklistService callback with the result of the Safe Search
// API check.
void OnCheckURLDone(PolicyBlocklistService::CheckSafeSearchCallback callback,
const GURL& /* url */,
safe_search_api::Classification classification,
bool /* uncertain */) {
std::move(callback).Run(classification ==
safe_search_api::Classification::SAFE);
}
} // namespace
PolicyBlocklistService::PolicyBlocklistService( PolicyBlocklistService::PolicyBlocklistService(
content::BrowserContext* browser_context,
std::unique_ptr<policy::URLBlocklistManager> url_blocklist_manager) std::unique_ptr<policy::URLBlocklistManager> url_blocklist_manager)
: browser_context_(browser_context), : url_blocklist_manager_(std::move(url_blocklist_manager)) {}
url_blocklist_manager_(std::move(url_blocklist_manager)) {}
PolicyBlocklistService::~PolicyBlocklistService() = default; PolicyBlocklistService::~PolicyBlocklistService() = default;
...@@ -44,53 +23,6 @@ PolicyBlocklistService::GetURLBlocklistState(const GURL& url) const { ...@@ -44,53 +23,6 @@ PolicyBlocklistService::GetURLBlocklistState(const GURL& url) const {
return url_blocklist_manager_->GetURLBlocklistState(url); return url_blocklist_manager_->GetURLBlocklistState(url);
} }
bool PolicyBlocklistService::CheckSafeSearchURL(
const GURL& url,
CheckSafeSearchCallback callback) {
if (!safe_search_url_checker_) {
net::NetworkTrafficAnnotationTag traffic_annotation =
net::DefineNetworkTrafficAnnotation("policy_blacklist_service", R"(
semantics {
sender: "Cloud Policy"
description:
"Checks whether a given URL (or set of URLs) is considered safe "
"by Google SafeSearch."
trigger:
"If the policy for safe sites is enabled, this is sent for every "
"top-level navigation if the result isn't already cached."
data: "URL to be checked."
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: NO
setting:
"This feature is off by default and cannot be controlled in "
"settings."
chrome_policy {
SafeSitesFilterBehavior {
SafeSitesFilterBehavior: 0
}
}
})");
safe_search_url_checker_ = std::make_unique<safe_search_api::URLChecker>(
std::make_unique<safe_search_api::SafeSearchURLCheckerClient>(
content::BrowserContext::GetDefaultStoragePartition(
browser_context_)
->GetURLLoaderFactoryForBrowserProcess(),
traffic_annotation));
}
return safe_search_url_checker_->CheckURL(
policy::url_util::Normalize(url),
base::BindOnce(&OnCheckURLDone, std::move(callback)));
}
void PolicyBlocklistService::SetSafeSearchURLCheckerForTest(
std::unique_ptr<safe_search_api::URLChecker> safe_search_url_checker) {
safe_search_url_checker_ = std::move(safe_search_url_checker);
}
// static // static
PolicyBlocklistFactory* PolicyBlocklistFactory::GetInstance() { PolicyBlocklistFactory* PolicyBlocklistFactory::GetInstance() {
return base::Singleton<PolicyBlocklistFactory>::get(); return base::Singleton<PolicyBlocklistFactory>::get();
...@@ -115,7 +47,7 @@ KeyedService* PolicyBlocklistFactory::BuildServiceInstanceFor( ...@@ -115,7 +47,7 @@ KeyedService* PolicyBlocklistFactory::BuildServiceInstanceFor(
PrefService* pref_service = user_prefs::UserPrefs::Get(context); PrefService* pref_service = user_prefs::UserPrefs::Get(context);
auto url_blocklist_manager = auto url_blocklist_manager =
std::make_unique<policy::URLBlocklistManager>(pref_service); std::make_unique<policy::URLBlocklistManager>(pref_service);
return new PolicyBlocklistService(context, std::move(url_blocklist_manager)); return new PolicyBlocklistService(std::move(url_blocklist_manager));
} }
content::BrowserContext* PolicyBlocklistFactory::GetBrowserContextToUse( content::BrowserContext* PolicyBlocklistFactory::GetBrowserContextToUse(
......
...@@ -7,52 +7,35 @@ ...@@ -7,52 +7,35 @@
#include <memory> #include <memory>
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/singleton.h" #include "base/memory/singleton.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
#include "components/keyed_service/core/keyed_service.h" #include "components/keyed_service/core/keyed_service.h"
#include "components/policy/core/browser/url_blocklist_manager.h" #include "components/policy/core/browser/url_blocklist_manager.h"
namespace safe_search_api {
class URLChecker;
} // namespace safe_search_api
// PolicyBlocklistService and PolicyBlocklistFactory provide a way for // PolicyBlocklistService and PolicyBlocklistFactory provide a way for
// us to access URLBlocklistManager, a policy block list service based on // us to access URLBlocklistManager, a policy block list service based on
// the Preference Service. The URLBlocklistManager responds to permission // the Preference Service. The URLBlocklistManager responds to permission
// changes and is per-Profile. // changes and is per-Profile.
class PolicyBlocklistService : public KeyedService { class PolicyBlocklistService : public KeyedService {
public: public:
using CheckSafeSearchCallback = base::OnceCallback<void(bool is_safe)>; explicit PolicyBlocklistService(
PolicyBlocklistService(
content::BrowserContext* browser_context,
std::unique_ptr<policy::URLBlocklistManager> url_blocklist_manager); std::unique_ptr<policy::URLBlocklistManager> url_blocklist_manager);
PolicyBlocklistService(const PolicyBlocklistService&) = delete;
PolicyBlocklistService& operator=(const PolicyBlocklistService&) = delete;
~PolicyBlocklistService() override; ~PolicyBlocklistService() override;
policy::URLBlocklist::URLBlocklistState GetURLBlocklistState( policy::URLBlocklist::URLBlocklistState GetURLBlocklistState(
const GURL& url) const; const GURL& url) const;
// Starts a call to the Safe Search API for the given URL to determine whether
// the URL is "safe" (not porn). Returns whether |callback| was run
// synchronously.
bool CheckSafeSearchURL(const GURL& url, CheckSafeSearchCallback callback);
// Creates a SafeSearch URLChecker using a given URLLoaderFactory for testing.
void SetSafeSearchURLCheckerForTest(
std::unique_ptr<safe_search_api::URLChecker> safe_search_url_checker);
private: private:
content::BrowserContext* const browser_context_;
std::unique_ptr<policy::URLBlocklistManager> url_blocklist_manager_; std::unique_ptr<policy::URLBlocklistManager> url_blocklist_manager_;
std::unique_ptr<safe_search_api::URLChecker> safe_search_url_checker_;
DISALLOW_COPY_AND_ASSIGN(PolicyBlocklistService);
}; };
class PolicyBlocklistFactory : public BrowserContextKeyedServiceFactory { class PolicyBlocklistFactory : public BrowserContextKeyedServiceFactory {
public: public:
PolicyBlocklistFactory(const PolicyBlocklistFactory&) = delete;
PolicyBlocklistFactory& operator=(const PolicyBlocklistFactory&) = delete;
static PolicyBlocklistFactory* GetInstance(); static PolicyBlocklistFactory* GetInstance();
static PolicyBlocklistService* GetForBrowserContext( static PolicyBlocklistService* GetForBrowserContext(
content::BrowserContext* context); content::BrowserContext* context);
...@@ -70,7 +53,6 @@ class PolicyBlocklistFactory : public BrowserContextKeyedServiceFactory { ...@@ -70,7 +53,6 @@ class PolicyBlocklistFactory : public BrowserContextKeyedServiceFactory {
content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* GetBrowserContextToUse(
content::BrowserContext* context) const override; content::BrowserContext* context) const override;
DISALLOW_COPY_AND_ASSIGN(PolicyBlocklistFactory);
}; };
#endif // COMPONENTS_POLICY_CONTENT_POLICY_BLOCKLIST_SERVICE_H_ #endif // COMPONENTS_POLICY_CONTENT_POLICY_BLOCKLIST_SERVICE_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/policy/content/safe_search_service.h"
#include <utility>
#include "base/bind.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/policy/core/browser/url_util.h"
#include "components/safe_search_api/safe_search/safe_search_url_checker_client.h"
#include "components/safe_search_api/url_checker.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/storage_partition.h"
#include "net/base/net_errors.h"
namespace {
// Calls the SafeSearchService callback with the result of the Safe Search
// API check.
void OnCheckURLDone(SafeSearchService::CheckSafeSearchCallback callback,
const GURL& /* url */,
safe_search_api::Classification classification,
bool /* uncertain */) {
std::move(callback).Run(classification ==
safe_search_api::Classification::SAFE);
}
} // namespace
SafeSearchService::SafeSearchService(content::BrowserContext* browser_context)
: browser_context_(browser_context) {}
SafeSearchService::~SafeSearchService() = default;
bool SafeSearchService::CheckSafeSearchURL(const GURL& url,
CheckSafeSearchCallback callback) {
if (!safe_search_url_checker_) {
net::NetworkTrafficAnnotationTag traffic_annotation =
net::DefineNetworkTrafficAnnotation("safe_search_service", R"(
semantics {
sender: "Cloud Policy"
description:
"Checks whether a given URL (or set of URLs) is considered safe "
"by Google SafeSearch."
trigger:
"If the policy for safe sites is enabled, this is sent for every "
"top-level navigation if the result isn't already cached."
data: "URL to be checked."
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: NO
setting:
"This feature is off by default and cannot be controlled in "
"settings."
chrome_policy {
SafeSitesFilterBehavior {
SafeSitesFilterBehavior: 0
}
}
})");
safe_search_url_checker_ = std::make_unique<safe_search_api::URLChecker>(
std::make_unique<safe_search_api::SafeSearchURLCheckerClient>(
content::BrowserContext::GetDefaultStoragePartition(
browser_context_)
->GetURLLoaderFactoryForBrowserProcess(),
traffic_annotation));
}
return safe_search_url_checker_->CheckURL(
policy::url_util::Normalize(url),
base::BindOnce(&OnCheckURLDone, std::move(callback)));
}
void SafeSearchService::SetSafeSearchURLCheckerForTest(
std::unique_ptr<safe_search_api::URLChecker> safe_search_url_checker) {
safe_search_url_checker_ = std::move(safe_search_url_checker);
}
// static
SafeSearchFactory* SafeSearchFactory::GetInstance() {
return base::Singleton<SafeSearchFactory>::get();
}
// static
SafeSearchService* SafeSearchFactory::GetForBrowserContext(
content::BrowserContext* context) {
return static_cast<SafeSearchService*>(
GetInstance()->GetServiceForBrowserContext(context, true));
}
SafeSearchFactory::SafeSearchFactory()
: BrowserContextKeyedServiceFactory(
"SafeSearch",
BrowserContextDependencyManager::GetInstance()) {}
SafeSearchFactory::~SafeSearchFactory() = default;
KeyedService* SafeSearchFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
return new SafeSearchService(context);
}
content::BrowserContext* SafeSearchFactory::GetBrowserContextToUse(
content::BrowserContext* context) const {
return context;
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_POLICY_CONTENT_SAFE_SEARCH_SERVICE_H_
#define COMPONENTS_POLICY_CONTENT_SAFE_SEARCH_SERVICE_H_
#include <memory>
#include "base/callback_forward.h"
#include "base/memory/singleton.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
#include "components/keyed_service/core/keyed_service.h"
class GURL;
namespace safe_search_api {
class URLChecker;
} // namespace safe_search_api
// SafeSearchService and SafeSearchFactory provide a way for
// us to access a Context-specific instance of safe_search_api.
class SafeSearchService : public KeyedService {
public:
using CheckSafeSearchCallback = base::OnceCallback<void(bool is_safe)>;
explicit SafeSearchService(content::BrowserContext* browser_context);
SafeSearchService(const SafeSearchService&) = delete;
SafeSearchService& operator=(const SafeSearchService&) = delete;
~SafeSearchService() override;
// Starts a call to the Safe Search API for the given URL to determine whether
// the URL is "safe" (not porn). Returns whether |callback| was run
// synchronously.
bool CheckSafeSearchURL(const GURL& url, CheckSafeSearchCallback callback);
// Creates a SafeSearch URLChecker using a given URLLoaderFactory for testing.
void SetSafeSearchURLCheckerForTest(
std::unique_ptr<safe_search_api::URLChecker> safe_search_url_checker);
private:
content::BrowserContext* const browser_context_;
std::unique_ptr<safe_search_api::URLChecker> safe_search_url_checker_;
};
class SafeSearchFactory : public BrowserContextKeyedServiceFactory {
public:
SafeSearchFactory(const SafeSearchFactory&) = delete;
SafeSearchFactory& operator=(const SafeSearchFactory&) = delete;
static SafeSearchFactory* GetInstance();
static SafeSearchService* GetForBrowserContext(
content::BrowserContext* context);
private:
SafeSearchFactory();
~SafeSearchFactory() override;
friend struct base::DefaultSingletonTraits<SafeSearchFactory>;
// BrowserContextKeyedServiceFactory:
KeyedService* BuildServiceInstanceFor(
content::BrowserContext* context) const override;
// Finds which browser context (if any) to use.
content::BrowserContext* GetBrowserContextToUse(
content::BrowserContext* context) const override;
};
#endif // COMPONENTS_POLICY_CONTENT_SAFE_SEARCH_SERVICE_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/policy/content/safe_sites_navigation_throttle.h"
#include "base/bind.h"
#include "base/strings/string_piece.h"
#include "components/policy/content/safe_search_service.h"
#include "components/policy/core/browser/url_util.h"
#include "content/public/browser/navigation_handle.h"
#include "url/gurl.h"
SafeSitesNavigationThrottle::SafeSitesNavigationThrottle(
content::NavigationHandle* navigation_handle,
content::BrowserContext* context)
: SafeSitesNavigationThrottle(
navigation_handle,
context,
base::BindRepeating(&SafeSitesNavigationThrottle::OnDeferredResult,
base::Unretained(this))) {}
SafeSitesNavigationThrottle::SafeSitesNavigationThrottle(
content::NavigationHandle* navigation_handle,
content::BrowserContext* context,
DeferredResultCallback deferred_result_callback)
: NavigationThrottle(navigation_handle),
safe_seach_service_(SafeSearchFactory::GetForBrowserContext(context)),
deferred_result_callback_(std::move(deferred_result_callback)) {}
// Use of Unretained for is safe because it is called synchronously from this
// object.
SafeSitesNavigationThrottle::SafeSitesNavigationThrottle(
content::NavigationHandle* navigation_handle,
content::BrowserContext* context,
base::StringPiece safe_sites_error_page_content)
: NavigationThrottle(navigation_handle),
safe_seach_service_(SafeSearchFactory::GetForBrowserContext(context)),
deferred_result_callback_(
base::BindRepeating(&SafeSitesNavigationThrottle::OnDeferredResult,
base::Unretained(this))),
safe_sites_error_page_content_(
safe_sites_error_page_content.as_string()) {}
SafeSitesNavigationThrottle::~SafeSitesNavigationThrottle() = default;
content::NavigationThrottle::ThrottleCheckResult
SafeSitesNavigationThrottle::WillStartRequest() {
const GURL& url = navigation_handle()->GetURL();
// Ignore blob scheme because we may use it to deliver navigation responses
// to the renderer process.
if (url.SchemeIs(url::kBlobScheme))
return PROCEED;
// Safe Sites filter applies to top-level HTTP[S] requests.
if (!url.SchemeIsHTTPOrHTTPS())
return PROCEED;
GURL effective_url = policy::url_util::GetEmbeddedURL(url);
if (!effective_url.is_valid())
effective_url = url;
bool synchronous = safe_seach_service_->CheckSafeSearchURL(
effective_url,
base::BindOnce(&SafeSitesNavigationThrottle::CheckSafeSearchCallback,
weak_ptr_factory_.GetWeakPtr()));
if (!synchronous) {
deferred_ = true;
return DEFER;
}
if (should_cancel_)
return CreateCancelResult();
return PROCEED;
}
content::NavigationThrottle::ThrottleCheckResult
SafeSitesNavigationThrottle::WillRedirectRequest() {
return WillStartRequest();
}
const char* SafeSitesNavigationThrottle::GetNameForLogging() {
return "SafeSitesNavigationThrottle";
}
void SafeSitesNavigationThrottle::CheckSafeSearchCallback(bool is_safe) {
if (!deferred_) {
should_cancel_ = !is_safe;
return;
}
deferred_ = false;
deferred_result_callback_.Run(is_safe, CreateCancelResult());
}
void SafeSitesNavigationThrottle::OnDeferredResult(
bool is_safe,
ThrottleCheckResult cancel_result) {
if (is_safe) {
Resume();
} else {
CancelDeferredNavigation(cancel_result);
}
}
content::NavigationThrottle::ThrottleCheckResult
SafeSitesNavigationThrottle::CreateCancelResult() const {
return ThrottleCheckResult(CANCEL, net::ERR_BLOCKED_BY_ADMINISTRATOR,
safe_sites_error_page_content_);
}
\ No newline at end of file
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_POLICY_CONTENT_SAFE_SITES_NAVIGATION_THROTTLE_H_
#define COMPONENTS_POLICY_CONTENT_SAFE_SITES_NAVIGATION_THROTTLE_H_
#include "base/callback_forward.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/strings/string_piece_forward.h"
#include "content/public/browser/navigation_throttle.h"
class SafeSearchService;
namespace content {
class BrowserContext;
class NavigationHandle;
} // namespace content
// SafeSitesNavigationThrottle provides a simple way to block a navigation
// based on the Safe Search API. The URL is checked against the Safe Search API.
// The check may be asynchronous if the result hasn't been cached yet.
// This class does not check the SafeSitesFilterBehavior policy.
class SafeSitesNavigationThrottle : public content::NavigationThrottle {
public:
// Called when the SafeSearch result is available after being deferred.
// if !|is_safe|, |cancel_result| contains the result to pass to
// CancelDeferredNavigation(). Other NavigationThrottles using this object
// must handle resolving deferred navigation themselves due to checks in
// NavigationThrottleRunner.
using DeferredResultCallback =
base::RepeatingCallback<void(bool is_safe,
ThrottleCheckResult cancel_result)>;
SafeSitesNavigationThrottle(content::NavigationHandle* navigation_handle,
content::BrowserContext* context);
SafeSitesNavigationThrottle(content::NavigationHandle* navigation_handle,
content::BrowserContext* context,
DeferredResultCallback deferred_result_callback);
SafeSitesNavigationThrottle(content::NavigationHandle* navigation_handle,
content::BrowserContext* context,
base::StringPiece safe_sites_error_page_content);
SafeSitesNavigationThrottle(const SafeSitesNavigationThrottle&) = delete;
SafeSitesNavigationThrottle& operator=(const SafeSitesNavigationThrottle&) =
delete;
~SafeSitesNavigationThrottle() override;
// NavigationThrottle overrides.
ThrottleCheckResult WillStartRequest() override;
ThrottleCheckResult WillRedirectRequest() override;
const char* GetNameForLogging() override;
private:
// Callback from SafeSearchService.
void CheckSafeSearchCallback(bool is_safe);
// The default implementation DeferredResultCallback.
void OnDeferredResult(bool is_safe, ThrottleCheckResult cancel_result);
// Creates the result to be returned when navigation is canceled.
ThrottleCheckResult CreateCancelResult() const;
SafeSearchService* safe_seach_service_;
const DeferredResultCallback deferred_result_callback_;
// HTML to be displayed when navigation is canceled by the Safe Sites filter.
// If null, a default error page will be displayed.
const base::Optional<std::string> safe_sites_error_page_content_;
// Whether the request was deferred in order to check the Safe Search API.
bool deferred_ = false;
// Whether the Safe Search API callback determined the in-progress navigation
// should be canceled.
bool should_cancel_ = false;
base::WeakPtrFactory<SafeSitesNavigationThrottle> weak_ptr_factory_{this};
};
#endif // COMPONENTS_POLICY_CONTENT_SAFE_SITES_NAVIGATION_THROTTLE_H_
...@@ -231,7 +231,6 @@ Refer to README.md for content description and update process. ...@@ -231,7 +231,6 @@ Refer to README.md for content description and update process.
<item id="permission_request_creator" added_in_milestone="62" hash_code="43206794" type="0" deprecated="2019-07-30" content_hash_code="73571699" file_path=""/> <item id="permission_request_creator" added_in_milestone="62" hash_code="43206794" type="0" deprecated="2019-07-30" content_hash_code="73571699" file_path=""/>
<item id="persist_blob_to_indexed_db" added_in_milestone="62" hash_code="32030464" type="0" deprecated="2018-08-13" content_hash_code="35410079" file_path=""/> <item id="persist_blob_to_indexed_db" added_in_milestone="62" hash_code="32030464" type="0" deprecated="2018-08-13" content_hash_code="35410079" file_path=""/>
<item id="plugins_resource_service" added_in_milestone="62" hash_code="49601082" type="0" content_hash_code="6877335" os_list="linux,windows" file_path="chrome/browser/plugins/plugins_resource_service.cc"/> <item id="plugins_resource_service" added_in_milestone="62" hash_code="49601082" type="0" content_hash_code="6877335" os_list="linux,windows" file_path="chrome/browser/plugins/plugins_resource_service.cc"/>
<item id="policy_blacklist_service" added_in_milestone="70" hash_code="49799644" type="0" content_hash_code="57843386" os_list="linux,windows" file_path="components/policy/content/policy_blocklist_service.cc"/>
<item id="popular_sites_fetch" added_in_milestone="62" hash_code="50755044" type="0" content_hash_code="6910083" os_list="linux,windows" file_path="components/ntp_tiles/popular_sites_impl.cc"/> <item id="popular_sites_fetch" added_in_milestone="62" hash_code="50755044" type="0" content_hash_code="6910083" os_list="linux,windows" file_path="components/ntp_tiles/popular_sites_impl.cc"/>
<item id="port_forwarding_controller_socket" added_in_milestone="65" hash_code="95075845" type="0" content_hash_code="122163428" os_list="linux,windows" file_path="chrome/browser/devtools/device/port_forwarding_controller.cc"/> <item id="port_forwarding_controller_socket" added_in_milestone="65" hash_code="95075845" type="0" content_hash_code="122163428" os_list="linux,windows" file_path="chrome/browser/devtools/device/port_forwarding_controller.cc"/>
<item id="ppapi_download_request" added_in_milestone="62" hash_code="135967426" type="0" content_hash_code="110461402" os_list="linux,windows" file_path="chrome/browser/safe_browsing/download_protection/ppapi_download_request.cc"/> <item id="ppapi_download_request" added_in_milestone="62" hash_code="135967426" type="0" content_hash_code="110461402" os_list="linux,windows" file_path="chrome/browser/safe_browsing/download_protection/ppapi_download_request.cc"/>
...@@ -300,6 +299,7 @@ Refer to README.md for content description and update process. ...@@ -300,6 +299,7 @@ Refer to README.md for content description and update process.
<item id="safe_browsing_realtime_url_lookup" added_in_milestone="78" hash_code="119324658" type="0" content_hash_code="71236226" os_list="linux,windows" file_path="components/safe_browsing/core/realtime/url_lookup_service.cc"/> <item id="safe_browsing_realtime_url_lookup" added_in_milestone="78" hash_code="119324658" type="0" content_hash_code="71236226" os_list="linux,windows" file_path="components/safe_browsing/core/realtime/url_lookup_service.cc"/>
<item id="safe_browsing_v4_get_hash" added_in_milestone="62" hash_code="8561691" type="0" content_hash_code="132435617" os_list="linux,windows" file_path="components/safe_browsing/core/db/v4_get_hash_protocol_manager.cc"/> <item id="safe_browsing_v4_get_hash" added_in_milestone="62" hash_code="8561691" type="0" content_hash_code="132435617" os_list="linux,windows" file_path="components/safe_browsing/core/db/v4_get_hash_protocol_manager.cc"/>
<item id="safe_browsing_v4_update" added_in_milestone="70" hash_code="82509217" type="0" content_hash_code="5247849" os_list="linux,windows" file_path="components/safe_browsing/core/db/v4_update_protocol_manager.cc"/> <item id="safe_browsing_v4_update" added_in_milestone="70" hash_code="82509217" type="0" content_hash_code="5247849" os_list="linux,windows" file_path="components/safe_browsing/core/db/v4_update_protocol_manager.cc"/>
<item id="safe_search_service" added_in_milestone="70" hash_code="136386805" type="0" content_hash_code="127491095" os_list="linux,windows" file_path="components/policy/content/safe_search_service.cc"/>
<item id="safety_check_update_connectivity" added_in_milestone="84" hash_code="137724067" type="0" content_hash_code="30977369" os_list="linux,windows" file_path="components/safety_check/update_check_helper.cc"/> <item id="safety_check_update_connectivity" added_in_milestone="84" hash_code="137724067" type="0" content_hash_code="30977369" os_list="linux,windows" file_path="components/safety_check/update_check_helper.cc"/>
<item id="sanitized_image_source" added_in_milestone="86" hash_code="36944304" type="0" content_hash_code="39770427" os_list="linux,windows" file_path="chrome/browser/ui/webui/sanitized_image_source.cc"/> <item id="sanitized_image_source" added_in_milestone="86" hash_code="36944304" type="0" content_hash_code="39770427" os_list="linux,windows" file_path="chrome/browser/ui/webui/sanitized_image_source.cc"/>
<item id="save_file_manager" added_in_milestone="62" hash_code="56275203" type="0" content_hash_code="56692339" os_list="linux,windows" file_path="content/browser/download/save_file_manager.cc"/> <item id="save_file_manager" added_in_milestone="62" hash_code="56275203" type="0" content_hash_code="56692339" os_list="linux,windows" file_path="content/browser/download/save_file_manager.cc"/>
......
...@@ -242,9 +242,9 @@ hidden="true" so that these annotations don't show up in the document. ...@@ -242,9 +242,9 @@ hidden="true" so that these annotations don't show up in the document.
<traffic_annotation unique_id="gaia_oauth_client_get_tokens"/> <traffic_annotation unique_id="gaia_oauth_client_get_tokens"/>
<traffic_annotation unique_id="gaia_oauth_client_get_user_info"/> <traffic_annotation unique_id="gaia_oauth_client_get_user_info"/>
<traffic_annotation unique_id="gaia_oauth_client_refresh_token"/> <traffic_annotation unique_id="gaia_oauth_client_refresh_token"/>
<traffic_annotation unique_id="policy_blacklist_service"/>
<traffic_annotation unique_id="oauth2_access_token_fetcher"/> <traffic_annotation unique_id="oauth2_access_token_fetcher"/>
<traffic_annotation unique_id="oauth2_mint_token_flow"/> <traffic_annotation unique_id="oauth2_mint_token_flow"/>
<traffic_annotation unique_id="safe_search_service"/>
</sender> </sender>
<sender name="Payments"> <sender name="Payments">
<traffic_annotation unique_id="payments_sync_cards"/> <traffic_annotation unique_id="payments_sync_cards"/>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment