// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/components/security_interstitials/safe_browsing/fake_safe_browsing_service.h"
#import "base/functional/callback_helpers.h"
#import "components/safe_browsing/core/browser/db/test_database_manager.h"
#import "components/safe_browsing/core/browser/safe_browsing_url_checker_impl.h"
#import "components/safe_browsing/core/common/features.h"
#import "ios/components/security_interstitials/safe_browsing/url_checker_delegate_impl.h"
#import "ios/web/public/thread/web_task_traits.h"
#import "ios/web/public/thread/web_thread.h"
#import "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
namespace {
// A SafeBrowsingUrlCheckerImpl that treats all URLs as safe, unless they have
// host safe.browsing.unsafe.chromium.test.
class FakeSafeBrowsingUrlCheckerImpl
: public safe_browsing::SafeBrowsingUrlCheckerImpl {
public:
explicit FakeSafeBrowsingUrlCheckerImpl(
network::mojom::RequestDestination request_destination)
: SafeBrowsingUrlCheckerImpl(
/*headers=*/net::HttpRequestHeaders(),
/*load_flags=*/0,
/*has_user_gesture=*/false,
base::MakeRefCounted<UrlCheckerDelegateImpl>(
/*database_manager=*/nullptr,
/*client=*/nullptr), /*web_contents_getter=*/
base::RepeatingCallback<content::WebContents*()>(),
base::WeakPtr<web::WebState>(),
/*render_process_id=*/
security_interstitials::UnsafeResource::kNoRenderProcessId,
/*render_frame_token=*/std::nullopt,
/*frame_tree_node_id=*/
security_interstitials::UnsafeResource::kNoFrameTreeNodeId,
/*navigation_id=*/std::nullopt,
/*url_real_time_lookup_enabled=*/false,
/*can_check_db=*/true,
/*can_check_high_confidence_allowlist=*/true,
/*url_lookup_service_metric_suffix=*/"",
web::GetUIThreadTaskRunner({}),
/*url_lookup_service_on_ui=*/nullptr,
/*hash_realtime_service_on_ui=*/nullptr,
safe_browsing::hash_realtime_utils::HashRealTimeSelection::kNone,
/*is_async_check=*/false,
SessionID::InvalidValue()) {}
~FakeSafeBrowsingUrlCheckerImpl() override = default;
// SafeBrowsingUrlCheckerImpl:
void CheckUrl(
const GURL& url,
const std::string& method,
safe_browsing::SafeBrowsingUrlCheckerImpl::NativeCheckUrlCallback
callback) override {
if (IsUrlUnsafe(url)) {
std::move(callback).Run(
/*proceed=*/false,
/*showed_interstitial=*/true,
/*has_post_commit_interstitial_skipped=*/false,
/*did_perform_url_real_time_check=*/
safe_browsing::SafeBrowsingUrlCheckerImpl::PerformedCheck::
kHashDatabaseCheck);
return;
}
std::move(callback).Run(/*proceed=*/true,
/*showed_interstitial=*/false,
/*has_post_commit_interstitial_skipped=*/false,
/*did_perform_url_real_time_check=*/
safe_browsing::SafeBrowsingUrlCheckerImpl::
PerformedCheck::kHashDatabaseCheck);
}
protected:
// Returns true if the given `url` should be deemed unsafe.
virtual bool IsUrlUnsafe(const GURL& url) {
return url.host() == FakeSafeBrowsingService::kUnsafeHost;
}
};
// A SafeBrowsingUrlCheckerImpl that treats all URLs as safe, unless they have
// host safe.browsing.unsafe.chromium.test or
// safe.browsing.async.unsafe.chromium.test.
class FakeAsyncSafeBrowsingUrlCheckerImpl
: public FakeSafeBrowsingUrlCheckerImpl {
public:
explicit FakeAsyncSafeBrowsingUrlCheckerImpl(
network::mojom::RequestDestination request_destination)
: FakeSafeBrowsingUrlCheckerImpl(request_destination) {}
protected:
bool IsUrlUnsafe(const GURL& url) override {
if (url.host() == FakeSafeBrowsingService::kAsyncUnsafeHost) {
return true;
}
return FakeSafeBrowsingUrlCheckerImpl::IsUrlUnsafe(url);
}
};
} // namespace
// static
const std::string FakeSafeBrowsingService::kUnsafeHost =
"safe.browsing.unsafe.chromium.test";
const std::string FakeSafeBrowsingService::kAsyncUnsafeHost =
"safe.browsing.async.unsafe.chromium.test";
FakeSafeBrowsingService::FakeSafeBrowsingService() = default;
FakeSafeBrowsingService::~FakeSafeBrowsingService() = default;
void FakeSafeBrowsingService::Initialize(
PrefService* prefs,
const base::FilePath& user_data_path,
safe_browsing::SafeBrowsingMetricsCollector*
safe_browsing_metrics_collector) {
DCHECK_CURRENTLY_ON(web::WebThread::UI);
}
void FakeSafeBrowsingService::ShutDown() {
DCHECK_CURRENTLY_ON(web::WebThread::UI);
}
std::unique_ptr<safe_browsing::SafeBrowsingUrlCheckerImpl>
FakeSafeBrowsingService::CreateUrlChecker(
network::mojom::RequestDestination request_destination,
web::WebState* web_state,
SafeBrowsingClient* client) {
return std::make_unique<FakeSafeBrowsingUrlCheckerImpl>(request_destination);
}
std::unique_ptr<safe_browsing::SafeBrowsingUrlCheckerImpl>
FakeSafeBrowsingService::CreateSyncChecker(
network::mojom::RequestDestination request_destination,
web::WebState* web_state,
SafeBrowsingClient* client) {
return std::make_unique<FakeSafeBrowsingUrlCheckerImpl>(request_destination);
}
std::unique_ptr<safe_browsing::SafeBrowsingUrlCheckerImpl>
FakeSafeBrowsingService::CreateAsyncChecker(
network::mojom::RequestDestination request_destination,
web::WebState* web_state,
SafeBrowsingClient* client) {
return std::make_unique<FakeAsyncSafeBrowsingUrlCheckerImpl>(
request_destination);
}
bool FakeSafeBrowsingService::ShouldCreateAsyncChecker(
web::WebState* web_state,
SafeBrowsingClient* client) {
if (!base::FeatureList::IsEnabled(
safe_browsing::kSafeBrowsingAsyncRealTimeCheck)) {
return false;
}
return true;
}
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_);
}
scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
FakeSafeBrowsingService::GetDatabaseManager() {
return nullptr;
}
network::mojom::NetworkContext* FakeSafeBrowsingService::GetNetworkContext() {
return nullptr;
}
void FakeSafeBrowsingService::ClearCookies(
const net::CookieDeletionInfo::TimeRange& creation_range,
base::OnceClosure callback) {
DCHECK_CURRENTLY_ON(web::WebThread::UI);
std::move(callback).Run();
}