Commit c258b7b6 authored by Ali Juma's avatar Ali Juma Committed by Commit Bot

[iOS] Create and use a RealTimeUrlLookupService

This CL adds a factory for creating RealTimeLookupService
instances on iOS, and uses a RealTimeLookupService with
SafeBrowsingUrlCheckerImpl when the kRealTimeLookupEnabled
feature is enabled. This means that when this feature is
enabled, real-time lookups work on iOS.

Change-Id: I7126a4224a20bd9fb45360ba2dc46f5d032f4a10
Bug: 1103220
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2317850
Commit-Queue: Ali Juma <ajuma@chromium.org>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Reviewed-by: default avatarVarun Khaneja <vakh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#793156}
parent fd6b9356
......@@ -115,6 +115,7 @@ source_set("browser_state_impl") {
"//ios/chrome/browser/prefs",
"//ios/chrome/browser/prefs:browser_prefs",
"//ios/chrome/browser/reading_list",
"//ios/chrome/browser/safe_browsing",
"//ios/chrome/browser/search_engines",
"//ios/chrome/browser/send_tab_to_self",
"//ios/chrome/browser/sessions",
......
......@@ -40,6 +40,8 @@
#import "ios/chrome/browser/policy/policy_features.h"
#include "ios/chrome/browser/policy_url_blocking/policy_url_blocking_service.h"
#include "ios/chrome/browser/reading_list/reading_list_model_factory.h"
#import "ios/chrome/browser/safe_browsing/real_time_url_lookup_service_factory.h"
#import "ios/chrome/browser/safe_browsing/verdict_cache_manager_factory.h"
#include "ios/chrome/browser/search_engines/template_url_service_factory.h"
#include "ios/chrome/browser/signin/about_signin_internals_factory.h"
#include "ios/chrome/browser/signin/account_consistency_service_factory.h"
......@@ -124,6 +126,7 @@ void EnsureBrowserStateKeyedServiceFactoriesBuilt() {
ModelTypeStoreServiceFactory::GetInstance();
ProfileSyncServiceFactory::GetInstance();
ReadingListModelFactory::GetInstance();
RealTimeUrlLookupServiceFactory::GetInstance();
SigninBrowserStateInfoUpdaterFactory::GetInstance();
SigninClientFactory::GetInstance();
SnapshotCacheFactory::GetInstance();
......@@ -132,6 +135,7 @@ void EnsureBrowserStateKeyedServiceFactoriesBuilt() {
TranslateAcceptLanguagesFactory::GetInstance();
UnifiedConsentServiceFactory::GetInstance();
UrlLanguageHistogramFactory::GetInstance();
VerdictCacheManagerFactory::GetInstance();
if (IsURLBlocklistEnabled()) {
PolicyBlocklistServiceFactory::GetInstance();
......
......@@ -9,6 +9,8 @@ source_set("safe_browsing") {
sources = [
"pending_unsafe_resource_storage.h",
"pending_unsafe_resource_storage.mm",
"real_time_url_lookup_service_factory.h",
"real_time_url_lookup_service_factory.mm",
"safe_browsing_blocking_page.h",
"safe_browsing_blocking_page.mm",
"safe_browsing_error.h",
......@@ -22,14 +24,19 @@ source_set("safe_browsing") {
"safe_browsing_unsafe_resource_container.mm",
"url_checker_delegate_impl.h",
"url_checker_delegate_impl.mm",
"verdict_cache_manager_factory.h",
"verdict_cache_manager_factory.mm",
]
deps = [
":util",
"//base",
"//build:branding_buildflags",
"//components/keyed_service/core",
"//components/keyed_service/ios",
"//components/prefs",
"//components/safe_browsing/core:features",
"//components/safe_browsing/core:verdict_cache_manager",
"//components/safe_browsing/core/browser",
"//components/safe_browsing/core/common",
"//components/safe_browsing/core/common:safe_browsing_prefs",
......@@ -37,12 +44,17 @@ source_set("safe_browsing") {
"//components/safe_browsing/core/db:database_manager",
"//components/safe_browsing/core/db:v4_local_database_manager",
"//components/safe_browsing/core/db:v4_protocol_manager_util",
"//components/safe_browsing/core/realtime:url_lookup_service",
"//components/safe_browsing/ios/browser:allow_list",
"//components/security_interstitials/core",
"//components/security_interstitials/core:unsafe_resource",
"//ios/chrome/browser",
"//ios/chrome/browser/browser_state",
"//ios/chrome/browser/content_settings",
"//ios/chrome/browser/history",
"//ios/chrome/browser/prerender",
"//ios/chrome/browser/signin",
"//ios/chrome/browser/sync",
"//ios/components/security_interstitials",
"//ios/net",
"//ios/web/public",
......@@ -70,6 +82,7 @@ source_set("test_support") {
"//components/safe_browsing/core/browser",
"//components/safe_browsing/core/db:test_database_manager",
"//ios/web/public",
"//services/network:test_support",
"//services/network/public/cpp",
]
......@@ -123,12 +136,14 @@ source_set("unit_tests") {
testonly = true
sources = [
"pending_unsafe_resource_storage_unittest.mm",
"real_time_url_lookup_service_factory_unittest.mm",
"safe_browsing_blocking_page_unittest.mm",
"safe_browsing_service_unittest.mm",
"safe_browsing_tab_helper_unittest.mm",
"safe_browsing_unsafe_resource_container_unittest.mm",
"safe_browsing_url_allow_list_unittest.mm",
"url_checker_delegate_impl_unittest.mm",
"verdict_cache_manager_factory_unittest.mm",
]
deps = [
......@@ -137,6 +152,8 @@ source_set("unit_tests") {
"//base/test:test_support",
"//components/prefs:test_support",
"//components/safe_browsing/core:features",
"//components/safe_browsing/core:realtimeapi_proto",
"//components/safe_browsing/core:verdict_cache_manager",
"//components/safe_browsing/core/browser",
"//components/safe_browsing/core/common",
"//components/safe_browsing/core/common:thread_utils",
......@@ -150,9 +167,13 @@ source_set("unit_tests") {
"//components/safe_browsing/core/db:v4_test_util",
"//components/safe_browsing/ios/browser:allow_list",
"//components/security_interstitials/core:unsafe_resource",
"//components/sync_preferences",
"//components/sync_preferences:test_support",
"//components/unified_consent",
"//ios/chrome/browser/browser_state:test_support",
"//ios/chrome/browser/prerender",
"//ios/chrome/browser/prerender:test_support",
"//ios/chrome/test:test_support",
"//ios/web/public",
"//ios/web/public/test",
"//services/network/public/cpp",
......
......@@ -8,6 +8,7 @@
#include <string>
#include "ios/chrome/browser/safe_browsing/safe_browsing_service.h"
#include "services/network/test/test_url_loader_factory.h"
// A fake SafeBrowsingService whose database treats URLs from host
// safe.browsing.unsafe.chromium.test as unsafe, and treats all other URLs as
......@@ -30,9 +31,13 @@ class FakeSafeBrowsingService : public SafeBrowsingService {
safe_browsing::ResourceType resource_type,
web::WebState* web_state) override;
bool CanCheckUrl(const GURL& url) const override;
scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
protected:
~FakeSafeBrowsingService() override;
private:
network::TestURLLoaderFactory url_loader_factory_;
};
#endif // IOS_CHROME_BROWSER_SAFE_BROWSING_FAKE_SAFE_BROWSING_SERVICE_H_
......@@ -9,6 +9,7 @@
#include "components/safe_browsing/core/db/test_database_manager.h"
#import "ios/chrome/browser/safe_browsing/url_checker_delegate_impl.h"
#include "ios/web/public/thread/web_thread.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
......@@ -78,3 +79,9 @@ bool FakeSafeBrowsingService::CanCheckUrl(const GURL& url) const {
return url.SchemeIsHTTPOrHTTPS() || url.SchemeIs(url::kFtpScheme) ||
url.SchemeIsWSOrWSS();
}
scoped_refptr<network::SharedURLLoaderFactory>
FakeSafeBrowsingService::GetURLLoaderFactory() {
return base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
&url_loader_factory_);
}
// 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 IOS_CHROME_BROWSER_SAFE_BROWSING_REAL_TIME_URL_LOOKUP_SERVICE_FACTORY_H_
#define IOS_CHROME_BROWSER_SAFE_BROWSING_REAL_TIME_URL_LOOKUP_SERVICE_FACTORY_H_
#include "base/no_destructor.h"
#include "components/keyed_service/ios/browser_state_keyed_service_factory.h"
class ChromeBrowserState;
class KeyedService;
namespace safe_browsing {
class RealTimeUrlLookupService;
}
namespace web {
class BrowserState;
}
// Singleton that owns RealTimeUrlLookupService objects, one for each active
// ChromeBrowserState. It returns nullptr for Incognito browser states.
class RealTimeUrlLookupServiceFactory : public BrowserStateKeyedServiceFactory {
public:
// Returns the instance of RealTimeUrlLookupService associated with this
// browser state, creating one if none exists and the given browser state is
// not in Incognito mode.
static safe_browsing::RealTimeUrlLookupService* GetForBrowserState(
ChromeBrowserState* browser_state);
// Returns the singleton instance of RealTimeUrlLookupServiceFactory.
static RealTimeUrlLookupServiceFactory* GetInstance();
private:
friend class base::NoDestructor<RealTimeUrlLookupServiceFactory>;
RealTimeUrlLookupServiceFactory();
~RealTimeUrlLookupServiceFactory() override = default;
// BrowserStateKeyedServiceFactory:
std::unique_ptr<KeyedService> BuildServiceInstanceFor(
web::BrowserState* browser_state) const override;
};
#endif // IOS_CHROME_BROWSER_SAFE_BROWSING_REAL_TIME_URL_LOOKUP_SERVICE_FACTORY_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 "ios/chrome/browser/safe_browsing/real_time_url_lookup_service_factory.h"
#include "components/keyed_service/ios/browser_state_dependency_manager.h"
#include "components/safe_browsing/core/common/utils.h"
#include "components/safe_browsing/core/realtime/url_lookup_service.h"
#include "components/safe_browsing/core/verdict_cache_manager.h"
#import "ios/chrome/browser/application_context.h"
#import "ios/chrome/browser/browser_state/chrome_browser_state.h"
#import "ios/chrome/browser/safe_browsing/safe_browsing_service.h"
#import "ios/chrome/browser/safe_browsing/verdict_cache_manager_factory.h"
#import "ios/chrome/browser/signin/identity_manager_factory.h"
#import "ios/chrome/browser/sync/profile_sync_service_factory.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
// static
safe_browsing::RealTimeUrlLookupService*
RealTimeUrlLookupServiceFactory::GetForBrowserState(
ChromeBrowserState* browser_state) {
return static_cast<safe_browsing::RealTimeUrlLookupService*>(
GetInstance()->GetServiceForBrowserState(browser_state, /*create=*/true));
}
// static
RealTimeUrlLookupServiceFactory*
RealTimeUrlLookupServiceFactory::GetInstance() {
static base::NoDestructor<RealTimeUrlLookupServiceFactory> instance;
return instance.get();
}
RealTimeUrlLookupServiceFactory::RealTimeUrlLookupServiceFactory()
: BrowserStateKeyedServiceFactory(
"RealTimeUrlLookupService",
BrowserStateDependencyManager::GetInstance()) {
DependsOn(IdentityManagerFactory::GetInstance());
DependsOn(ProfileSyncServiceFactory::GetInstance());
DependsOn(VerdictCacheManagerFactory::GetInstance());
}
std::unique_ptr<KeyedService>
RealTimeUrlLookupServiceFactory::BuildServiceInstanceFor(
web::BrowserState* browser_state) const {
SafeBrowsingService* safe_browsing_service =
GetApplicationContext()->GetSafeBrowsingService();
if (!safe_browsing_service) {
return nullptr;
}
ChromeBrowserState* chrome_browser_state =
ChromeBrowserState::FromBrowserState(browser_state);
return std::make_unique<safe_browsing::RealTimeUrlLookupService>(
safe_browsing_service->GetURLLoaderFactory(),
VerdictCacheManagerFactory::GetForBrowserState(chrome_browser_state),
IdentityManagerFactory::GetForBrowserState(chrome_browser_state),
ProfileSyncServiceFactory::GetForBrowserState(chrome_browser_state),
chrome_browser_state->GetPrefs(),
safe_browsing::ChromeUserPopulation::NOT_MANAGED,
/*is_under_advanced_protection=*/false,
chrome_browser_state->IsOffTheRecord(),
GetApplicationContext()->GetVariationsService());
}
// 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.
#import "ios/chrome/browser/safe_browsing/real_time_url_lookup_service_factory.h"
#include "base/test/scoped_feature_list.h"
#include "components/safe_browsing/core/features.h"
#import "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
#import "ios/web/public/test/web_task_environment.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
class RealTimeUrlLookupServiceFactoryTest : public PlatformTest {
protected:
RealTimeUrlLookupServiceFactoryTest()
: browser_state_(TestChromeBrowserState::Builder().Build()) {
feature_list_.InitAndEnableFeature(
safe_browsing::kSafeBrowsingAvailableOnIOS);
}
web::WebTaskEnvironment task_environment_;
std::unique_ptr<ChromeBrowserState> browser_state_;
base::test::ScopedFeatureList feature_list_;
};
// Checks that RealTimeUrlLookupServiceFactory returns a null for an
// off-the-record browser state, but returns a non-null instance for a regular
// browser state.
TEST_F(RealTimeUrlLookupServiceFactoryTest, OffTheRecordReturnsNull) {
// The factory should return null for an off-the-record browser state.
EXPECT_FALSE(RealTimeUrlLookupServiceFactory::GetForBrowserState(
browser_state_->GetOffTheRecordChromeBrowserState()));
// There should be a non-null instance for a regular browser state.
EXPECT_TRUE(RealTimeUrlLookupServiceFactory::GetForBrowserState(
browser_state_.get()));
}
......@@ -72,7 +72,6 @@ const char kMalwareWarningDetails[] =
- (AppLaunchConfiguration)appConfigurationForTestCase {
AppLaunchConfiguration config;
config.features_enabled.push_back(safe_browsing::kSafeBrowsingAvailableOnIOS);
config.features_enabled.push_back(web::features::kSSLCommittedInterstitials);
// Use commandline args to insert fake unsafe URLs into the Safe Browsing
// database.
......
......@@ -14,6 +14,10 @@ namespace base {
class FilePath;
}
namespace network {
class SharedURLLoaderFactory;
}
namespace safe_browsing {
enum class ResourceType;
class SafeBrowsingUrlCheckerImpl;
......@@ -50,6 +54,10 @@ class SafeBrowsingService
// Returns true if |url| has a scheme that is handled by Safe Browsing.
virtual bool CanCheckUrl(const GURL& url) const = 0;
// Returns the SharedURLLoaderFactory used for Safe Browsing network requests.
virtual scoped_refptr<network::SharedURLLoaderFactory>
GetURLLoaderFactory() = 0;
protected:
SafeBrowsingService() = default;
virtual ~SafeBrowsingService() = default;
......
......@@ -43,6 +43,7 @@ class SafeBrowsingServiceImpl : public SafeBrowsingService {
safe_browsing::ResourceType resource_type,
web::WebState* web_state) override;
bool CanCheckUrl(const GURL& url) const override;
scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
private:
// A helper class for enabling/disabling Safe Browsing and maintaining state
......@@ -120,9 +121,17 @@ class SafeBrowsingServiceImpl : public SafeBrowsingService {
// Enables or disables Safe Browsing, depending on the current state of
// preferences.
void UpdateSafeBrowsingEnabledState();
// This is the UI thread remote for IOThreadState's network context.
mojo::Remote<network::mojom::NetworkContext> network_context_client_;
// The URLLoaderFactory used for Safe Browsing network requests.
mojo::Remote<network::mojom::URLLoaderFactory> url_loader_factory_;
// A SharedURLLoaderFactory that wraps |url_loader_factory_|.
scoped_refptr<network::WeakWrapperSharedURLLoaderFactory>
shared_url_loader_factory_;
// Constructed on the UI thread, but otherwise its methods are only called on
// the IO thread.
scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
......
......@@ -15,6 +15,10 @@
#include "components/safe_browsing/core/browser/url_checker_delegate.h"
#include "components/safe_browsing/core/common/safebrowsing_constants.h"
#include "components/safe_browsing/core/db/v4_local_database_manager.h"
#include "components/safe_browsing/core/features.h"
#include "components/safe_browsing/core/realtime/url_lookup_service.h"
#import "ios/chrome/browser/browser_state/chrome_browser_state.h"
#import "ios/chrome/browser/safe_browsing/real_time_url_lookup_service_factory.h"
#import "ios/chrome/browser/safe_browsing/url_checker_delegate_impl.h"
#include "ios/web/public/thread/web_task_traits.h"
#include "ios/web/public/thread/web_thread.h"
......@@ -83,17 +87,30 @@ std::unique_ptr<safe_browsing::SafeBrowsingUrlCheckerImpl>
SafeBrowsingServiceImpl::CreateUrlChecker(
safe_browsing::ResourceType resource_type,
web::WebState* web_state) {
bool can_perform_full_url_lookup = false;
safe_browsing::RealTimeUrlLookupService* url_lookup_service = nullptr;
if (base::FeatureList::IsEnabled(safe_browsing::kRealTimeUrlLookupEnabled)) {
url_lookup_service = RealTimeUrlLookupServiceFactory::GetForBrowserState(
ChromeBrowserState::FromBrowserState(web_state->GetBrowserState()));
can_perform_full_url_lookup =
url_lookup_service && url_lookup_service->CanPerformFullURLLookup();
}
return std::make_unique<safe_browsing::SafeBrowsingUrlCheckerImpl>(
resource_type, url_checker_delegate_, web_state->CreateDefaultGetter(),
/*real_time_lookup_enabled=*/false,
can_perform_full_url_lookup,
/*can_rt_check_subresource_url=*/false,
/*url_lookup_service_on_ui=*/nullptr);
url_lookup_service ? url_lookup_service->GetWeakPtr() : nullptr);
}
bool SafeBrowsingServiceImpl::CanCheckUrl(const GURL& url) const {
return safe_browsing_db_manager_->CanCheckUrl(url);
}
scoped_refptr<network::SharedURLLoaderFactory>
SafeBrowsingServiceImpl::GetURLLoaderFactory() {
return shared_url_loader_factory_;
}
void SafeBrowsingServiceImpl::SetUpURLLoaderFactory(
mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
DCHECK_CURRENTLY_ON(web::WebThread::UI);
......@@ -102,7 +119,12 @@ void SafeBrowsingServiceImpl::SetUpURLLoaderFactory(
url_loader_factory_params->process_id = network::mojom::kBrowserProcessId;
url_loader_factory_params->is_corb_enabled = false;
network_context_client_->CreateURLLoaderFactory(
std::move(receiver), std::move(url_loader_factory_params));
url_loader_factory_.BindNewPipeAndPassReceiver(),
std::move(url_loader_factory_params));
url_loader_factory_->Clone(std::move(receiver));
shared_url_loader_factory_ =
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
url_loader_factory_.get());
}
void SafeBrowsingServiceImpl::UpdateSafeBrowsingEnabledState() {
......
......@@ -8,7 +8,8 @@
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/task/post_task.h"
#include "components/prefs/testing_pref_service.h"
#include "base/test/scoped_feature_list.h"
#include "components/prefs/pref_service.h"
#include "components/safe_browsing/core/browser/safe_browsing_url_checker_impl.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
#include "components/safe_browsing/core/common/safebrowsing_constants.h"
......@@ -19,11 +20,19 @@
#include "components/safe_browsing/core/db/v4_get_hash_protocol_manager.h"
#include "components/safe_browsing/core/db/v4_protocol_manager_util.h"
#include "components/safe_browsing/core/db/v4_test_util.h"
#include "components/safe_browsing/core/features.h"
#include "components/safe_browsing/core/proto/realtimeapi.pb.h"
#include "components/safe_browsing/core/verdict_cache_manager.h"
#import "components/safe_browsing/ios/browser/safe_browsing_url_allow_list.h"
#include "components/sync_preferences/pref_service_syncable.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "components/unified_consent/pref_names.h"
#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
#import "ios/chrome/browser/prerender/fake_prerender_service.h"
#import "ios/chrome/browser/prerender/prerender_service_factory.h"
#import "ios/chrome/browser/safe_browsing/safe_browsing_unsafe_resource_container.h"
#import "ios/chrome/browser/safe_browsing/verdict_cache_manager_factory.h"
#import "ios/chrome/test/testing_application_context.h"
#import "ios/web/public/test/fakes/test_web_state.h"
#include "ios/web/public/test/web_task_environment.h"
#include "ios/web/public/thread/web_task_traits.h"
......@@ -36,19 +45,19 @@
namespace {
const char kSafePage[] = "http://example.test/safe.html";
const char kMalwarePage[] = "http://example.test/malware.html";
const char kSafePage[] = "https://example.test/safe.html";
const char kMalwarePage[] = "https://unsafe.test/malware.html";
class TestUrlCheckerClient {
public:
TestUrlCheckerClient(SafeBrowsingService* safe_browsing_service)
: safe_browsing_service_(safe_browsing_service),
browser_state_(TestChromeBrowserState::Builder().Build()) {
TestUrlCheckerClient(SafeBrowsingService* safe_browsing_service,
web::BrowserState* browser_state)
: safe_browsing_service_(safe_browsing_service) {
SafeBrowsingUrlAllowList::CreateForWebState(&web_state_);
SafeBrowsingUnsafeResourceContainer::CreateForWebState(&web_state_);
web_state_.SetBrowserState(browser_state_.get());
web_state_.SetBrowserState(browser_state);
PrerenderServiceFactory::GetInstance()->SetTestingFactory(
browser_state_.get(),
browser_state,
base::BindRepeating(
[](web::BrowserState*) -> std::unique_ptr<KeyedService> {
return std::make_unique<FakePrerenderService>();
......@@ -108,7 +117,6 @@ class TestUrlCheckerClient {
bool result_pending_ = false;
bool url_is_unsafe_ = false;
SafeBrowsingService* safe_browsing_service_;
std::unique_ptr<ChromeBrowserState> browser_state_;
web::TestWebState web_state_;
std::unique_ptr<safe_browsing::SafeBrowsingUrlCheckerImpl> url_checker_;
};
......@@ -118,9 +126,8 @@ class TestUrlCheckerClient {
class SafeBrowsingServiceTest : public PlatformTest {
public:
SafeBrowsingServiceTest()
: task_environment_(web::WebTaskEnvironment::IO_MAINLOOP) {
safe_browsing::RegisterProfilePrefs(local_state_.registry());
: task_environment_(web::WebTaskEnvironment::IO_MAINLOOP),
browser_state_(TestChromeBrowserState::Builder().Build()) {
store_factory_ = new safe_browsing::TestV4StoreFactory();
safe_browsing::V4Database::RegisterStoreFactoryForTest(
base::WrapUnique(store_factory_));
......@@ -137,7 +144,8 @@ class SafeBrowsingServiceTest : public PlatformTest {
safe_browsing_service_ = base::MakeRefCounted<SafeBrowsingServiceImpl>();
CHECK(temp_dir_.CreateUniqueTempDir());
safe_browsing_service_->Initialize(&local_state_, temp_dir_.GetPath());
safe_browsing_service_->Initialize(browser_state_->GetPrefs(),
temp_dir_.GetPath());
base::RunLoop().RunUntilIdle();
}
......@@ -156,10 +164,37 @@ class SafeBrowsingServiceTest : public PlatformTest {
base::Unretained(this), bad_url));
}
// Adds the given |safe_url| to the allowlist used by real-time checks.
void MarkUrlAsRealTimeSafe(const GURL& safe_url) {
base::PostTask(
FROM_HERE, {web::WebThread::IO},
base::BindOnce(&SafeBrowsingServiceTest::MarkUrlAsSafeOnIOThread,
base::Unretained(this), safe_url));
}
// Caches the given |bad_url| as unsafe in the VerdictCacheManager used by
// real-time checks.
void MarkUrlAsRealTimeUnsafe(const GURL& bad_url) {
safe_browsing::RTLookupResponse response;
safe_browsing::RTLookupResponse::ThreatInfo* threat_info =
response.add_threat_info();
threat_info->set_verdict_type(
safe_browsing::RTLookupResponse::ThreatInfo::DANGEROUS);
threat_info->set_threat_type(
safe_browsing::RTLookupResponse::ThreatInfo::SOCIAL_ENGINEERING);
threat_info->set_cache_duration_sec(100);
threat_info->set_cache_expression_using_match_type(bad_url.host() + "/");
threat_info->set_cache_expression_match_type(
safe_browsing::RTLookupResponse::ThreatInfo::COVERING_MATCH);
VerdictCacheManagerFactory::GetForBrowserState(browser_state_.get())
->CacheRealTimeUrlVerdict(bad_url, response, base::Time::Now(),
/*store_old_cache=*/false);
}
protected:
web::WebTaskEnvironment task_environment_;
TestingPrefServiceSimple local_state_;
scoped_refptr<SafeBrowsingService> safe_browsing_service_;
std::unique_ptr<TestChromeBrowserState> browser_state_;
private:
void MarkUrlAsMalwareOnIOThread(const GURL& bad_url) {
......@@ -172,6 +207,17 @@ class SafeBrowsingServiceTest : public PlatformTest {
v4_get_hash_factory_->AddToFullHashCache(full_hash_info);
}
void MarkUrlAsSafeOnIOThread(const GURL& bad_url) {
safe_browsing::FullHashInfo full_hash_info =
safe_browsing::GetFullHashInfoWithMetadata(
bad_url, safe_browsing::GetUrlMalwareId(),
safe_browsing::ThreatMetadata());
v4_db_factory_->MarkPrefixAsBad(
safe_browsing::GetUrlHighConfidenceAllowlistId(),
full_hash_info.full_hash);
v4_get_hash_factory_->AddToFullHashCache(full_hash_info);
}
base::ScopedTempDir temp_dir_;
// Owned by V4Database.
......@@ -187,7 +233,8 @@ class SafeBrowsingServiceTest : public PlatformTest {
TEST_F(SafeBrowsingServiceTest, SafeAndUnsafePages) {
// Verify that queries to the Safe Browsing database owned by
// SafeBrowsingService receive responses.
TestUrlCheckerClient client(safe_browsing_service_.get());
TestUrlCheckerClient client(safe_browsing_service_.get(),
browser_state_.get());
GURL safe_url = GURL(kSafePage);
client.CheckUrl(safe_url);
EXPECT_TRUE(client.result_pending());
......@@ -204,8 +251,50 @@ TEST_F(SafeBrowsingServiceTest, SafeAndUnsafePages) {
EXPECT_TRUE(client.url_is_unsafe());
// Disable Safe Browsing, and ensure that unsafe URLs are no longer flagged.
local_state_.SetUserPref(prefs::kSafeBrowsingEnabled,
std::make_unique<base::Value>(false));
browser_state_->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnabled, false);
client.CheckUrl(unsafe_url);
EXPECT_TRUE(client.result_pending());
client.WaitForResult();
EXPECT_FALSE(client.result_pending());
EXPECT_FALSE(client.url_is_unsafe());
}
// Verifies that safe and unsafe URLs are identified correctly when real-time
// lookups are enabled, and that opting out of real-time checks works as
// expected.
TEST_F(SafeBrowsingServiceTest, RealTimeSafeAndUnsafePages) {
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures({safe_browsing::kSafeBrowsingAvailableOnIOS,
safe_browsing::kRealTimeUrlLookupEnabled},
{});
TestingApplicationContext::GetGlobal();
// Opt into real-time checks.
browser_state_->GetPrefs()->SetBoolean(
unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled, true);
GURL safe_url(kSafePage);
MarkUrlAsRealTimeSafe(safe_url);
TestUrlCheckerClient client(safe_browsing_service_.get(),
browser_state_.get());
client.CheckUrl(safe_url);
EXPECT_TRUE(client.result_pending());
client.WaitForResult();
EXPECT_FALSE(client.result_pending());
EXPECT_FALSE(client.url_is_unsafe());
GURL unsafe_url(kMalwarePage);
MarkUrlAsRealTimeUnsafe(unsafe_url);
client.CheckUrl(unsafe_url);
EXPECT_TRUE(client.result_pending());
client.WaitForResult();
EXPECT_FALSE(client.result_pending());
EXPECT_TRUE(client.url_is_unsafe());
// Opt out of real-time checks, and ensure that unsafe URLs are no longer
// flagged.
browser_state_->GetPrefs()->SetBoolean(
unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled, false);
client.CheckUrl(unsafe_url);
EXPECT_TRUE(client.result_pending());
client.WaitForResult();
......
// 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 IOS_CHROME_BROWSER_SAFE_BROWSING_VERDICT_CACHE_MANAGER_FACTORY_H_
#define IOS_CHROME_BROWSER_SAFE_BROWSING_VERDICT_CACHE_MANAGER_FACTORY_H_
#include "base/no_destructor.h"
#include "components/keyed_service/ios/browser_state_keyed_service_factory.h"
class ChromeBrowserState;
class KeyedService;
namespace safe_browsing {
class VerdictCacheManager;
}
namespace web {
class BrowserState;
}
// Singleton that owns VerdictCacheManager objects, one for each active
// ChromeBrowserState.
class VerdictCacheManagerFactory : public BrowserStateKeyedServiceFactory {
public:
// Returns the instance of VerdictCacheManager associated with this browser
// state, creating one if none exists.
static safe_browsing::VerdictCacheManager* GetForBrowserState(
ChromeBrowserState* browser_state);
// Returns the singleton instance of VerdictCacheManagerFactory.
static VerdictCacheManagerFactory* GetInstance();
private:
friend class base::NoDestructor<VerdictCacheManagerFactory>;
VerdictCacheManagerFactory();
~VerdictCacheManagerFactory() override = default;
// BrowserStateKeyedServiceFactory:
std::unique_ptr<KeyedService> BuildServiceInstanceFor(
web::BrowserState* browser_state) const override;
web::BrowserState* GetBrowserStateToUse(
web::BrowserState* browser_state) const override;
};
#endif // IOS_CHROME_BROWSER_SAFE_BROWSING_VERDICT_CACHE_MANAGER_FACTORY_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.
#import "ios/chrome/browser/safe_browsing/verdict_cache_manager_factory.h"
#include "components/keyed_service/core/service_access_type.h"
#include "components/keyed_service/ios/browser_state_dependency_manager.h"
#include "components/safe_browsing/core/verdict_cache_manager.h"
#import "ios/chrome/browser/browser_state/browser_state_otr_helper.h"
#import "ios/chrome/browser/browser_state/chrome_browser_state.h"
#import "ios/chrome/browser/content_settings/host_content_settings_map_factory.h"
#import "ios/chrome/browser/history/history_service_factory.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
// static
safe_browsing::VerdictCacheManager*
VerdictCacheManagerFactory::GetForBrowserState(
ChromeBrowserState* browser_state) {
return static_cast<safe_browsing::VerdictCacheManager*>(
GetInstance()->GetServiceForBrowserState(browser_state, /*create=*/true));
}
// static
VerdictCacheManagerFactory* VerdictCacheManagerFactory::GetInstance() {
static base::NoDestructor<VerdictCacheManagerFactory> instance;
return instance.get();
}
VerdictCacheManagerFactory::VerdictCacheManagerFactory()
: BrowserStateKeyedServiceFactory(
"VerdictCacheManager",
BrowserStateDependencyManager::GetInstance()) {
DependsOn(ios::HistoryServiceFactory::GetInstance());
DependsOn(ios::HostContentSettingsMapFactory::GetInstance());
}
std::unique_ptr<KeyedService>
VerdictCacheManagerFactory::BuildServiceInstanceFor(
web::BrowserState* browser_state) const {
ChromeBrowserState* chrome_browser_state =
ChromeBrowserState::FromBrowserState(browser_state);
return std::make_unique<safe_browsing::VerdictCacheManager>(
ios::HistoryServiceFactory::GetForBrowserState(
chrome_browser_state, ServiceAccessType::EXPLICIT_ACCESS),
ios::HostContentSettingsMapFactory::GetForBrowserState(
chrome_browser_state));
}
web::BrowserState* VerdictCacheManagerFactory::GetBrowserStateToUse(
web::BrowserState* browser_state) const {
return GetBrowserStateOwnInstanceInIncognito(browser_state);
}
// 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.
#import "ios/chrome/browser/safe_browsing/verdict_cache_manager_factory.h"
#import "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
#import "ios/web/public/test/web_task_environment.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
using VerdictCacheManagerFactoryTest = PlatformTest;
// Checks that VerdictCacheManagerFactory returns different instances
// for an off-the-record browser state and a regular browser state.
TEST_F(VerdictCacheManagerFactoryTest, OffTheRecordUsesDifferentInstance) {
web::WebTaskEnvironment task_environment;
TestChromeBrowserState::Builder builder;
std::unique_ptr<TestChromeBrowserState> browser_state = builder.Build();
// There should be a non-null instance for an off-the-record browser state.
EXPECT_TRUE(VerdictCacheManagerFactory::GetForBrowserState(
browser_state->GetOffTheRecordChromeBrowserState()));
EXPECT_NE(VerdictCacheManagerFactory::GetForBrowserState(browser_state.get()),
VerdictCacheManagerFactory::GetForBrowserState(
browser_state->GetOffTheRecordChromeBrowserState()));
}
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