Commit 4e699456 authored by edchin's avatar edchin Committed by Chromium LUCI CQ

[ios][PhishGuard] Create PasswordProtectionServiceBase

This CL creates a base class that will hold cross-platform code.
The derived class PasswordProtectionService (in /content) will
have content-specific code.

This CL keeps the base class in the same file to make the review
easier. A followup CL will move the base class (and unittest) into
separate files.

* moves navigation throttle code to derived class.
* moves some content-specific functions to derived class.

Bug: 1147967
Change-Id: I1fa606f241225680bd33b7828fdfc6b588ad415d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2576079Reviewed-by: default avatarBettina Dea <bdea@chromium.org>
Reviewed-by: default avatarAli Juma <ajuma@chromium.org>
Commit-Queue: edchin <edchin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#835830}
parent f84561d6
......@@ -112,7 +112,7 @@ PasswordProtectionRequest::PasswordProtectionRequest(
matching_reused_credentials,
LoginReputationClientRequest::TriggerType type,
bool password_field_exists,
PasswordProtectionService* pps,
PasswordProtectionServiceBase* pps,
int request_timeout_in_ms)
: web_contents_(web_contents),
main_frame_url_(main_frame_url),
......@@ -526,7 +526,7 @@ void PasswordProtectionRequest::SendRequest() {
})");
auto resource_request = std::make_unique<network::ResourceRequest>();
resource_request->url =
PasswordProtectionService::GetPasswordProtectionRequestUrl();
PasswordProtectionServiceBase::GetPasswordProtectionRequestUrl();
resource_request->method = "POST";
resource_request->load_flags = net::LOAD_DISABLE_CACHE;
url_loader_ = network::SimpleURLLoader::Create(std::move(resource_request),
......@@ -593,7 +593,7 @@ void PasswordProtectionRequest::Finish(
DCHECK(CurrentlyOnThread(ThreadID::UI));
tracker_.TryCancelAll();
// If the request is canceled, the PasswordProtectionService is already
// If the request is canceled, the PasswordProtectionServiceBase is already
// partially destroyed, and we won't be able to log accurate metrics.
if (outcome != RequestOutcome::CANCELED) {
ReusedPasswordAccountType password_account_type =
......
......@@ -63,9 +63,9 @@ using DeleteOnUIThread =
// A request for checking if an unfamiliar login form or a password reuse event
// is safe. PasswordProtectionRequest objects are owned by
// PasswordProtectionService indicated by |password_protection_service_|.
// PasswordProtectionService is RefCountedThreadSafe such that it can post task
// safely between IO and UI threads. It can only be destroyed on UI thread.
// PasswordProtectionServiceBase indicated by |password_protection_service_|.
// PasswordProtectionServiceBase is RefCountedThreadSafe such that it can post
// task safely between IO and UI threads. It can only be destroyed on UI thread.
//
// PasswordProtectionRequest flow:
// Step| Thread | Task
......@@ -97,7 +97,7 @@ class PasswordProtectionRequest
matching_reused_credentials,
LoginReputationClientRequest::TriggerType type,
bool password_field_exists,
PasswordProtectionService* pps,
PasswordProtectionServiceBase* pps,
int request_timeout_in_ms);
// Not copyable or movable
......@@ -280,9 +280,9 @@ class PasswordProtectionRequest
// SimpleURLLoader instance for sending request and receiving response.
std::unique_ptr<network::SimpleURLLoader> url_loader_;
// The PasswordProtectionService instance owns |this|.
// The PasswordProtectionServiceBase instance owns |this|.
// Can only be accessed on UI thread.
PasswordProtectionService* password_protection_service_;
PasswordProtectionServiceBase* password_protection_service_;
// The outcome of the password protection request.
RequestOutcome request_outcome_;
......
......@@ -51,7 +51,7 @@ const char kPasswordProtectionRequestUrl[] =
} // namespace
PasswordProtectionService::PasswordProtectionService(
PasswordProtectionServiceBase::PasswordProtectionServiceBase(
const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
HistoryService* history_service)
......@@ -67,14 +67,15 @@ PasswordProtectionService::PasswordProtectionService(
"linkedin.com"};
}
PasswordProtectionService::~PasswordProtectionService() {
PasswordProtectionServiceBase::~PasswordProtectionServiceBase() {
tracker_.TryCancelAll();
CancelPendingRequests();
history_service_observation_.Reset();
weak_factory_.InvalidateWeakPtrs();
}
bool PasswordProtectionService::CanGetReputationOfURL(const GURL& url) {
// static
bool PasswordProtectionServiceBase::CanGetReputationOfURL(const GURL& url) {
if (!safe_browsing::CanGetReputationOfUrl(url)) {
return false;
}
......@@ -83,7 +84,7 @@ bool PasswordProtectionService::CanGetReputationOfURL(const GURL& url) {
}
#if defined(ON_FOCUS_PING_ENABLED)
void PasswordProtectionService::MaybeStartPasswordFieldOnFocusRequest(
void PasswordProtectionServiceBase::MaybeStartPasswordFieldOnFocusRequest(
WebContents* web_contents,
const GURL& main_frame_url,
const GURL& password_form_action,
......@@ -110,7 +111,7 @@ void PasswordProtectionService::MaybeStartPasswordFieldOnFocusRequest(
}
#endif
void PasswordProtectionService::MaybeStartProtectedPasswordEntryRequest(
void PasswordProtectionServiceBase::MaybeStartProtectedPasswordEntryRequest(
WebContents* web_contents,
const GURL& main_frame_url,
const std::string& username,
......@@ -162,7 +163,7 @@ void PasswordProtectionService::MaybeStartProtectedPasswordEntryRequest(
}
}
bool PasswordProtectionService::ShouldShowModalWarning(
bool PasswordProtectionServiceBase::ShouldShowModalWarning(
LoginReputationClientRequest::TriggerType trigger_type,
ReusedPasswordAccountType password_type,
LoginReputationClientResponse::VerdictType verdict_type) {
......@@ -176,27 +177,8 @@ bool PasswordProtectionService::ShouldShowModalWarning(
IsWarningEnabled(password_type);
}
void PasswordProtectionService::RemoveWarningRequestsByWebContents(
content::WebContents* web_contents) {
for (auto it = warning_requests_.begin(); it != warning_requests_.end();) {
if (it->get()->web_contents() == web_contents)
it = warning_requests_.erase(it);
else
++it;
}
}
bool PasswordProtectionService::IsModalWarningShowingInWebContents(
content::WebContents* web_contents) {
for (const auto& request : warning_requests_) {
if (request->web_contents() == web_contents)
return true;
}
return false;
}
LoginReputationClientResponse::VerdictType
PasswordProtectionService::GetCachedVerdict(
PasswordProtectionServiceBase::GetCachedVerdict(
const GURL& url,
LoginReputationClientRequest::TriggerType trigger_type,
ReusedPasswordAccountType password_type,
......@@ -204,14 +186,14 @@ PasswordProtectionService::GetCachedVerdict(
return LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED;
}
void PasswordProtectionService::CacheVerdict(
void PasswordProtectionServiceBase::CacheVerdict(
const GURL& url,
LoginReputationClientRequest::TriggerType trigger_type,
ReusedPasswordAccountType password_type,
const LoginReputationClientResponse& verdict,
const base::Time& receive_time) {}
void PasswordProtectionService::StartRequest(
void PasswordProtectionServiceBase::StartRequest(
WebContents* web_contents,
const GURL& main_frame_url,
const GURL& password_form_action,
......@@ -233,7 +215,7 @@ void PasswordProtectionService::StartRequest(
pending_requests_.insert(std::move(request));
}
bool PasswordProtectionService::CanSendPing(
bool PasswordProtectionServiceBase::CanSendPing(
LoginReputationClientRequest::TriggerType trigger_type,
const GURL& main_frame_url,
ReusedPasswordAccountType password_type) {
......@@ -242,7 +224,7 @@ bool PasswordProtectionService::CanSendPing(
!IsInExcludedCountry();
}
void PasswordProtectionService::RequestFinished(
void PasswordProtectionServiceBase::RequestFinished(
PasswordProtectionRequest* request,
RequestOutcome outcome,
std::unique_ptr<LoginReputationClientResponse> response) {
......@@ -287,7 +269,7 @@ void PasswordProtectionService::RequestFinished(
request->HandleDeferredNavigations();
// If the request is canceled, the PasswordProtectionService is already
// If the request is canceled, the PasswordProtectionServiceBase is already
// partially destroyed, and we won't be able to log accurate metrics.
if (outcome != RequestOutcome::CANCELED) {
auto verdict =
......@@ -325,7 +307,7 @@ void PasswordProtectionService::RequestFinished(
}
}
void PasswordProtectionService::CancelPendingRequests() {
void PasswordProtectionServiceBase::CancelPendingRequests() {
DCHECK(CurrentlyOnThread(ThreadID::UI));
for (auto it = pending_requests_.begin(); it != pending_requests_.end();) {
PasswordProtectionRequest* request = it->get();
......@@ -338,28 +320,30 @@ void PasswordProtectionService::CancelPendingRequests() {
DCHECK(pending_requests_.empty());
}
int PasswordProtectionService::GetStoredVerdictCount(
int PasswordProtectionServiceBase::GetStoredVerdictCount(
LoginReputationClientRequest::TriggerType trigger_type) {
return -1;
}
scoped_refptr<SafeBrowsingDatabaseManager>
PasswordProtectionService::database_manager() {
PasswordProtectionServiceBase::database_manager() {
return database_manager_;
}
GURL PasswordProtectionService::GetPasswordProtectionRequestUrl() {
// static
GURL PasswordProtectionServiceBase::GetPasswordProtectionRequestUrl() {
GURL url(kPasswordProtectionRequestUrl);
std::string api_key = google_apis::GetAPIKey();
DCHECK(!api_key.empty());
return url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true));
}
int PasswordProtectionService::GetRequestTimeoutInMS() {
// static
int PasswordProtectionServiceBase::GetRequestTimeoutInMS() {
return kRequestTimeoutMs;
}
void PasswordProtectionService::FillUserPopulation(
void PasswordProtectionServiceBase::FillUserPopulation(
LoginReputationClientRequest::TriggerType trigger_type,
LoginReputationClientRequest* request_proto) {
ChromeUserPopulation* user_population = request_proto->mutable_population();
......@@ -379,53 +363,25 @@ void PasswordProtectionService::FillUserPopulation(
user_population->set_is_mbb_enabled(IsUserMBBOptedIn());
}
void PasswordProtectionService::OnURLsDeleted(
void PasswordProtectionServiceBase::OnURLsDeleted(
history::HistoryService* history_service,
const history::DeletionInfo& deletion_info) {
GetTaskRunner(ThreadID::UI)
->PostTask(
FROM_HERE,
base::BindRepeating(&PasswordProtectionService::
base::BindRepeating(&PasswordProtectionServiceBase::
RemoveUnhandledSyncPasswordReuseOnURLsDeleted,
GetWeakPtr(), deletion_info.IsAllHistory(),
deletion_info.deleted_rows()));
}
void PasswordProtectionService::HistoryServiceBeingDeleted(
void PasswordProtectionServiceBase::HistoryServiceBeingDeleted(
history::HistoryService* history_service) {
DCHECK(history_service_observation_.IsObservingSource(history_service));
history_service_observation_.Reset();
}
std::unique_ptr<PasswordProtectionNavigationThrottle>
PasswordProtectionService::MaybeCreateNavigationThrottle(
content::NavigationHandle* navigation_handle) {
if (!navigation_handle->IsRendererInitiated())
return nullptr;
content::WebContents* web_contents = navigation_handle->GetWebContents();
for (scoped_refptr<PasswordProtectionRequest> request : pending_requests_) {
if (request->web_contents() == web_contents &&
request->trigger_type() ==
safe_browsing::LoginReputationClientRequest::PASSWORD_REUSE_EVENT &&
IsSupportedPasswordTypeForModalWarning(
GetPasswordProtectionReusedPasswordAccountType(
request->password_type(), username_for_last_shown_warning()))) {
return std::make_unique<PasswordProtectionNavigationThrottle>(
navigation_handle, request, /*is_warning_showing=*/false);
}
}
for (scoped_refptr<PasswordProtectionRequest> request : warning_requests_) {
if (request->web_contents() == web_contents) {
return std::make_unique<PasswordProtectionNavigationThrottle>(
navigation_handle, request, /*is_warning_showing=*/true);
}
}
return nullptr;
}
bool PasswordProtectionService::IsWarningEnabled(
bool PasswordProtectionServiceBase::IsWarningEnabled(
ReusedPasswordAccountType password_type) {
return GetPasswordProtectionWarningTriggerPref(password_type) ==
PHISHING_REUSE;
......@@ -433,7 +389,7 @@ bool PasswordProtectionService::IsWarningEnabled(
// static
ReusedPasswordType
PasswordProtectionService::GetPasswordProtectionReusedPasswordType(
PasswordProtectionServiceBase::GetPasswordProtectionReusedPasswordType(
password_manager::metrics_util::PasswordType password_type) {
switch (password_type) {
case PasswordType::SAVED_PASSWORD:
......@@ -454,7 +410,7 @@ PasswordProtectionService::GetPasswordProtectionReusedPasswordType(
}
ReusedPasswordAccountType
PasswordProtectionService::GetPasswordProtectionReusedPasswordAccountType(
PasswordProtectionServiceBase::GetPasswordProtectionReusedPasswordAccountType(
password_manager::metrics_util::PasswordType password_type,
const std::string& username) const {
ReusedPasswordAccountType reused_password_account_type;
......@@ -505,7 +461,7 @@ PasswordProtectionService::GetPasswordProtectionReusedPasswordAccountType(
// static
PasswordType
PasswordProtectionService::ConvertReusedPasswordAccountTypeToPasswordType(
PasswordProtectionServiceBase::ConvertReusedPasswordAccountTypeToPasswordType(
ReusedPasswordAccountType password_type) {
if (password_type.is_account_syncing()) {
return PasswordType::PRIMARY_ACCOUNT_PASSWORD;
......@@ -523,7 +479,7 @@ PasswordProtectionService::ConvertReusedPasswordAccountTypeToPasswordType(
}
}
bool PasswordProtectionService::IsSupportedPasswordTypeForPinging(
bool PasswordProtectionServiceBase::IsSupportedPasswordTypeForPinging(
PasswordType password_type) const {
switch (password_type) {
case PasswordType::SAVED_PASSWORD:
......@@ -543,9 +499,8 @@ bool PasswordProtectionService::IsSupportedPasswordTypeForPinging(
return false;
}
bool PasswordProtectionService::IsSupportedPasswordTypeForModalWarning(
bool PasswordProtectionServiceBase::IsSupportedPasswordTypeForModalWarning(
ReusedPasswordAccountType password_type) const {
if (password_type.account_type() ==
ReusedPasswordAccountType::SAVED_PASSWORD &&
base::FeatureList::IsEnabled(
......@@ -572,11 +527,58 @@ bool PasswordProtectionService::IsSupportedPasswordTypeForModalWarning(
}
#if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
void PasswordProtectionService::GetPhishingDetector(
void PasswordProtectionServiceBase::GetPhishingDetector(
service_manager::InterfaceProvider* provider,
mojo::Remote<mojom::PhishingDetector>* phishing_detector) {
provider->GetInterface(phishing_detector->BindNewPipeAndPassReceiver());
}
#endif
std::unique_ptr<PasswordProtectionNavigationThrottle>
PasswordProtectionService::MaybeCreateNavigationThrottle(
content::NavigationHandle* navigation_handle) {
if (!navigation_handle->IsRendererInitiated())
return nullptr;
content::WebContents* web_contents = navigation_handle->GetWebContents();
for (scoped_refptr<PasswordProtectionRequest> request : pending_requests_) {
if (request->web_contents() == web_contents &&
request->trigger_type() ==
safe_browsing::LoginReputationClientRequest::PASSWORD_REUSE_EVENT &&
IsSupportedPasswordTypeForModalWarning(
GetPasswordProtectionReusedPasswordAccountType(
request->password_type(), username_for_last_shown_warning()))) {
return std::make_unique<PasswordProtectionNavigationThrottle>(
navigation_handle, request, /*is_warning_showing=*/false);
}
}
for (scoped_refptr<PasswordProtectionRequest> request : warning_requests_) {
if (request->web_contents() == web_contents) {
return std::make_unique<PasswordProtectionNavigationThrottle>(
navigation_handle, request, /*is_warning_showing=*/true);
}
}
return nullptr;
}
void PasswordProtectionService::RemoveWarningRequestsByWebContents(
content::WebContents* web_contents) {
for (auto it = warning_requests_.begin(); it != warning_requests_.end();) {
if (it->get()->web_contents() == web_contents)
it = warning_requests_.erase(it);
else
++it;
}
}
bool PasswordProtectionService::IsModalWarningShowingInWebContents(
content::WebContents* web_contents) {
for (const auto& request : warning_requests_) {
if (request->web_contents() == web_contents)
return true;
}
return false;
}
} // namespace safe_browsing
......@@ -61,19 +61,19 @@ using ReusedPasswordType =
using password_manager::metrics_util::PasswordType;
// Manage password protection pings and verdicts. There is one instance of this
// class per profile. Therefore, every PasswordProtectionService instance is
// class per profile. Therefore, every PasswordProtectionServiceBase instance is
// associated with a unique HistoryService instance and a unique
// HostContentSettingsMap instance.
class PasswordProtectionService : public history::HistoryServiceObserver {
class PasswordProtectionServiceBase : public history::HistoryServiceObserver {
public:
PasswordProtectionService(
PasswordProtectionServiceBase(
const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
history::HistoryService* history_service);
~PasswordProtectionService() override;
~PasswordProtectionServiceBase() override;
base::WeakPtr<PasswordProtectionService> GetWeakPtr() {
base::WeakPtr<PasswordProtectionServiceBase> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
......@@ -186,12 +186,6 @@ class PasswordProtectionService : public history::HistoryServiceObserver {
virtual bool UserClickedThroughSBInterstitial(
PasswordProtectionRequest* request) = 0;
// Called when a new navigation is starting. Create throttle if there is a
// pending sync password reuse ping or if there is a modal warning dialog
// showing in the corresponding web contents.
std::unique_ptr<PasswordProtectionNavigationThrottle>
MaybeCreateNavigationThrottle(content::NavigationHandle* navigation_handle);
// Returns if the warning UI is enabled.
bool IsWarningEnabled(ReusedPasswordAccountType password_type);
......@@ -294,6 +288,9 @@ class PasswordProtectionService : public history::HistoryServiceObserver {
virtual AccountInfo GetAccountInfo() const = 0;
// Returns the URL where PasswordProtectionRequest instances send requests.
static GURL GetPasswordProtectionRequestUrl();
protected:
friend class PasswordProtectionRequest;
......@@ -336,9 +333,6 @@ class PasswordProtectionService : public history::HistoryServiceObserver {
return url_loader_factory_;
}
// Returns the URL where PasswordProtectionRequest instances send requests.
static GURL GetPasswordProtectionRequestUrl();
// Gets the request timeout in milliseconds.
static int GetRequestTimeoutInMS();
......@@ -405,10 +399,6 @@ class PasswordProtectionService : public history::HistoryServiceObserver {
PasswordType password_type,
const LoginReputationClientResponse*) = 0;
void RemoveWarningRequestsByWebContents(content::WebContents* web_contents);
bool IsModalWarningShowingInWebContents(content::WebContents* web_contents);
// Determines if we should show chrome://reset-password interstitial based on
// the reused |password_type| and the |main_frame_url|.
virtual bool CanShowInterstitial(ReusedPasswordAccountType password_type,
......@@ -437,6 +427,13 @@ class PasswordProtectionService : public history::HistoryServiceObserver {
return common_spoofed_domains_;
}
// Set of pending PasswordProtectionRequests that are still waiting for
// verdict.
std::set<scoped_refptr<PasswordProtectionRequest>> pending_requests_;
// Set of PasswordProtectionRequests that are triggering modal warnings.
std::set<scoped_refptr<PasswordProtectionRequest>> warning_requests_;
private:
friend class PasswordProtectionServiceTest;
friend class TestPasswordProtectionService;
......@@ -509,13 +506,6 @@ class PasswordProtectionService : public history::HistoryServiceObserver {
// cookie store.
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
// Set of pending PasswordProtectionRequests that are still waiting for
// verdict.
std::set<scoped_refptr<PasswordProtectionRequest>> pending_requests_;
// Set of PasswordProtectionRequests that are triggering modal warnings.
std::set<scoped_refptr<PasswordProtectionRequest>> warning_requests_;
// List of most commonly spoofed domains to default to on the password warning
// dialog.
std::list<std::string> common_spoofed_domains_;
......@@ -528,8 +518,24 @@ class PasswordProtectionService : public history::HistoryServiceObserver {
// we need CancelableTaskTracker to cancel tasks posted to IO thread.
base::CancelableTaskTracker tracker_;
base::WeakPtrFactory<PasswordProtectionService> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(PasswordProtectionService);
base::WeakPtrFactory<PasswordProtectionServiceBase> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(PasswordProtectionServiceBase);
};
class PasswordProtectionService : public PasswordProtectionServiceBase {
using PasswordProtectionServiceBase::PasswordProtectionServiceBase;
public:
// Called when a new navigation is starting. Create throttle if there is a
// pending sync password reuse ping or if there is a modal warning dialog
// showing in the corresponding web contents.
std::unique_ptr<PasswordProtectionNavigationThrottle>
MaybeCreateNavigationThrottle(content::NavigationHandle* navigation_handle);
protected:
void RemoveWarningRequestsByWebContents(content::WebContents* web_contents);
bool IsModalWarningShowingInWebContents(content::WebContents* web_contents);
};
} // namespace safe_browsing
......
......@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
......@@ -230,11 +231,88 @@ class TestPasswordProtectionService : public MockPasswordProtectionService {
DISALLOW_COPY_AND_ASSIGN(TestPasswordProtectionService);
};
class PasswordProtectionServiceTest : public ::testing::TestWithParam<bool> {
class PasswordProtectionServiceTest : public ::testing::Test {
public:
PasswordProtectionServiceTest()
: task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
protected:
void SetUp() override {
HostContentSettingsMap::RegisterProfilePrefs(test_pref_service_.registry());
content_setting_map_ = new HostContentSettingsMap(
&test_pref_service_, /*is_off_the_record=*/false,
/*store_last_modified=*/false, /*restore_session=*/false);
database_manager_ = new MockSafeBrowsingDatabaseManager();
password_protection_service_ =
std::make_unique<TestPasswordProtectionService>(
database_manager_,
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
&test_url_loader_factory_),
content_setting_map_);
web_contents_ =
base::WrapUnique(content::WebContentsTester::CreateTestWebContents(
content::WebContents::CreateParams(&browser_context_)));
const std::vector<password_manager::MatchingReusedCredential>
matching_reused_credentials = {};
request_ = base::MakeRefCounted<safe_browsing::PasswordProtectionRequest>(
web_contents_.get(), GURL(kTargetUrl), /*password_form_action=*/GURL(),
/*password_form_frame_url=*/GURL(),
web_contents_->GetContentsMimeType(), kUserName,
PasswordType::PASSWORD_TYPE_UNKNOWN, matching_reused_credentials,
LoginReputationClientRequest::PASSWORD_REUSE_EVENT,
/*password_field_exists=*/true, password_protection_service_.get(),
/*request_timeout_in_ms=*/10000);
}
void TearDown() override {
password_protection_service_.reset();
content_setting_map_->ShutdownOnUIThread();
}
size_t GetNumberOfNavigationThrottles() {
return request_ ? request_->throttles_.size() : 0u;
}
// |task_environment_| is needed here because this test involves both UI and
// IO threads.
content::BrowserTaskEnvironment task_environment_;
scoped_refptr<MockSafeBrowsingDatabaseManager> database_manager_;
sync_preferences::TestingPrefServiceSyncable test_pref_service_;
scoped_refptr<HostContentSettingsMap> content_setting_map_;
network::TestURLLoaderFactory test_url_loader_factory_;
std::unique_ptr<TestPasswordProtectionService> password_protection_service_;
content::TestBrowserContext browser_context_;
content::RenderViewHostTestEnabler rvh_test_enabler_;
std::unique_ptr<content::WebContents> web_contents_;
scoped_refptr<PasswordProtectionRequest> request_;
};
TEST_F(PasswordProtectionServiceTest,
VerifyNavigationThrottleNotRemovedWhenCanceledOnTimeout) {
request_->Start();
auto throttle = std::make_unique<PasswordProtectionNavigationThrottle>(
nullptr, request_, false);
EXPECT_EQ(1U, GetNumberOfNavigationThrottles());
request_->Cancel(/*timed_out=*/true);
EXPECT_EQ(1U, GetNumberOfNavigationThrottles());
}
TEST_F(PasswordProtectionServiceTest,
VerifyNavigationThrottleRemovedWhenCanceledNotOnTimeout) {
request_->Start();
auto throttle = std::make_unique<PasswordProtectionNavigationThrottle>(
nullptr, request_, false);
EXPECT_EQ(1U, GetNumberOfNavigationThrottles());
request_->Cancel(/*timed_out=*/false);
EXPECT_EQ(0U, GetNumberOfNavigationThrottles());
}
class PasswordProtectionServiceBaseTest
: public ::testing::TestWithParam<bool> {
public:
PasswordProtectionServiceBaseTest()
: task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
LoginReputationClientResponse CreateVerdictProto(
LoginReputationClientResponse::VerdictType verdict,
int cache_duration_sec,
......@@ -271,7 +349,7 @@ class PasswordProtectionServiceTest : public ::testing::TestWithParam<bool> {
.WillRepeatedly(Return(PASSWORD_PROTECTION_OFF));
EXPECT_CALL(*password_protection_service_, IsUserMBBOptedIn())
.WillRepeatedly(Return(true));
url_ = PasswordProtectionService::GetPasswordProtectionRequestUrl();
url_ = PasswordProtectionServiceBase::GetPasswordProtectionRequestUrl();
}
void TearDown() override {
......@@ -383,10 +461,6 @@ class PasswordProtectionServiceTest : public ::testing::TestWithParam<bool> {
}
#endif
size_t GetNumberOfNavigationThrottles() {
return request_ ? request_->throttles_.size() : 0u;
}
protected:
// |task_environment_| is needed here because this test involves both UI and
// IO threads.
......@@ -403,7 +477,7 @@ class PasswordProtectionServiceTest : public ::testing::TestWithParam<bool> {
content::RenderViewHostTestEnabler rvh_test_enabler_;
};
TEST_P(PasswordProtectionServiceTest, TestCachePasswordReuseVerdicts) {
TEST_P(PasswordProtectionServiceBaseTest, TestCachePasswordReuseVerdicts) {
ASSERT_EQ(0U, GetStoredVerdictCount(
LoginReputationClientRequest::PASSWORD_REUSE_EVENT));
EXPECT_CALL(*password_protection_service_, IsPrimaryAccountSignedIn())
......@@ -480,7 +554,8 @@ TEST_P(PasswordProtectionServiceTest, TestCachePasswordReuseVerdicts) {
LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE));
}
TEST_P(PasswordProtectionServiceTest, TestCachePasswordReuseVerdictsIncognito) {
TEST_P(PasswordProtectionServiceBaseTest,
TestCachePasswordReuseVerdictsIncognito) {
EXPECT_CALL(*password_protection_service_, IsIncognito())
.WillRepeatedly(Return(true));
ASSERT_EQ(0U, GetStoredVerdictCount(
......@@ -523,7 +598,7 @@ TEST_P(PasswordProtectionServiceTest, TestCachePasswordReuseVerdictsIncognito) {
LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE));
}
TEST_P(PasswordProtectionServiceTest, TestCacheUnfamiliarLoginVerdicts) {
TEST_P(PasswordProtectionServiceBaseTest, TestCacheUnfamiliarLoginVerdicts) {
ASSERT_EQ(0U, GetStoredVerdictCount(
LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE));
ReusedPasswordAccountType reused_password_account_type;
......@@ -565,7 +640,7 @@ TEST_P(PasswordProtectionServiceTest, TestCacheUnfamiliarLoginVerdicts) {
LoginReputationClientRequest::PASSWORD_REUSE_EVENT));
}
TEST_P(PasswordProtectionServiceTest,
TEST_P(PasswordProtectionServiceBaseTest,
TestCacheUnfamiliarLoginVerdictsIncognito) {
EXPECT_CALL(*password_protection_service_, IsIncognito())
.WillRepeatedly(Return(true));
......@@ -610,7 +685,7 @@ TEST_P(PasswordProtectionServiceTest,
LoginReputationClientRequest::PASSWORD_REUSE_EVENT));
}
TEST_P(PasswordProtectionServiceTest, TestGetCachedVerdicts) {
TEST_P(PasswordProtectionServiceBaseTest, TestGetCachedVerdicts) {
ASSERT_EQ(0U, GetStoredVerdictCount(
LoginReputationClientRequest::PASSWORD_REUSE_EVENT));
ASSERT_EQ(0U, GetStoredVerdictCount(
......@@ -721,7 +796,7 @@ TEST_P(PasswordProtectionServiceTest, TestGetCachedVerdicts) {
reused_password_account_type, &actual_verdict));
}
TEST_P(PasswordProtectionServiceTest, TestDoesNotCacheAboutBlank) {
TEST_P(PasswordProtectionServiceBaseTest, TestDoesNotCacheAboutBlank) {
ASSERT_EQ(0U, GetStoredVerdictCount(
LoginReputationClientRequest::PASSWORD_REUSE_EVENT));
ReusedPasswordAccountType reused_password_account_type;
......@@ -739,7 +814,7 @@ TEST_P(PasswordProtectionServiceTest, TestDoesNotCacheAboutBlank) {
LoginReputationClientRequest::PASSWORD_REUSE_EVENT));
}
TEST_P(PasswordProtectionServiceTest, VerifyCanGetReputationOfURL) {
TEST_P(PasswordProtectionServiceBaseTest, VerifyCanGetReputationOfURL) {
// Invalid main frame URL.
EXPECT_FALSE(PasswordProtectionService::CanGetReputationOfURL(GURL()));
......@@ -777,7 +852,7 @@ TEST_P(PasswordProtectionServiceTest, VerifyCanGetReputationOfURL) {
GURL("http://www.chromium.org")));
}
TEST_P(PasswordProtectionServiceTest, TestNoRequestSentForWhitelistedURL) {
TEST_P(PasswordProtectionServiceBaseTest, TestNoRequestSentForWhitelistedURL) {
histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogram, 0);
std::unique_ptr<content::WebContents> web_contents = GetWebContents();
content::WebContentsTester::For(web_contents.get())
......@@ -800,7 +875,7 @@ TEST_P(PasswordProtectionServiceTest, TestNoRequestSentForWhitelistedURL) {
#define MAYBE_TestNoRequestSentIfVerdictAlreadyCached \
TestNoRequestSentIfVerdictAlreadyCached
#endif
TEST_P(PasswordProtectionServiceTest,
TEST_P(PasswordProtectionServiceBaseTest,
MAYBE_TestNoRequestSentIfVerdictAlreadyCached) {
histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogram, 0);
ReusedPasswordAccountType reused_password_account_type;
......@@ -823,7 +898,7 @@ TEST_P(PasswordProtectionServiceTest,
password_protection_service_->latest_response()->verdict_type());
}
TEST_P(PasswordProtectionServiceTest, TestResponseFetchFailed) {
TEST_P(PasswordProtectionServiceBaseTest, TestResponseFetchFailed) {
histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogram, 0);
// Set up failed response.
network::URLLoaderCompletionStatus status(net::ERR_FAILED);
......@@ -841,7 +916,7 @@ TEST_P(PasswordProtectionServiceTest, TestResponseFetchFailed) {
ElementsAre(base::Bucket(9 /* FETCH_FAILED */, 1)));
}
TEST_P(PasswordProtectionServiceTest, TestMalformedResponse) {
TEST_P(PasswordProtectionServiceBaseTest, TestMalformedResponse) {
histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogram, 0);
// Set up malformed response.
test_url_loader_factory_.AddResponse(url_.spec(), "invalid response");
......@@ -857,7 +932,7 @@ TEST_P(PasswordProtectionServiceTest, TestMalformedResponse) {
ElementsAre(base::Bucket(10 /* RESPONSE_MALFORMED */, 1)));
}
TEST_P(PasswordProtectionServiceTest, TestRequestTimedout) {
TEST_P(PasswordProtectionServiceBaseTest, TestRequestTimedout) {
histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogram, 0);
std::unique_ptr<content::WebContents> web_contents = GetWebContents();
InitializeAndStartPasswordOnFocusRequest(/*match_whitelist=*/false,
......@@ -870,7 +945,7 @@ TEST_P(PasswordProtectionServiceTest, TestRequestTimedout) {
ElementsAre(base::Bucket(3 /* TIMEDOUT */, 1)));
}
TEST_P(PasswordProtectionServiceTest,
TEST_P(PasswordProtectionServiceBaseTest,
TestPasswordOnFocusRequestAndResponseSuccessfull) {
histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogram, 0);
// Set up valid response.
......@@ -899,7 +974,7 @@ TEST_P(PasswordProtectionServiceTest,
actual_response->cache_duration_sec());
}
TEST_P(PasswordProtectionServiceTest,
TEST_P(PasswordProtectionServiceBaseTest,
TestProtectedPasswordEntryRequestAndResponseSuccessfull) {
histograms_.ExpectTotalCount(kAnyPasswordEntryRequestOutcomeHistogram, 0);
histograms_.ExpectTotalCount(kSyncPasswordEntryRequestOutcomeHistogram, 0);
......@@ -946,7 +1021,7 @@ TEST_P(PasswordProtectionServiceTest,
ElementsAre(base::Bucket(3 /* PHISHING */, 1)));
}
TEST_P(PasswordProtectionServiceTest,
TEST_P(PasswordProtectionServiceBaseTest,
TestSyncPasswordEntryRequestAndResponseSuccessfull) {
histograms_.ExpectTotalCount(kAnyPasswordEntryRequestOutcomeHistogram, 0);
histograms_.ExpectTotalCount(kSyncPasswordEntryRequestOutcomeHistogram, 0);
......@@ -986,7 +1061,7 @@ TEST_P(PasswordProtectionServiceTest,
histograms_.ExpectTotalCount(kNonSyncPasswordEntryVerdictHistogram, 0);
}
TEST_P(PasswordProtectionServiceTest, TestTearDownWithPendingRequests) {
TEST_P(PasswordProtectionServiceBaseTest, TestTearDownWithPendingRequests) {
histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogram, 0);
GURL target_url(kTargetUrl);
EXPECT_CALL(*database_manager_, CheckCsdWhitelistUrl(target_url, _))
......@@ -1008,7 +1083,7 @@ TEST_P(PasswordProtectionServiceTest, TestTearDownWithPendingRequests) {
IsEmpty());
}
TEST_P(PasswordProtectionServiceTest, VerifyPasswordOnFocusRequestProto) {
TEST_P(PasswordProtectionServiceBaseTest, VerifyPasswordOnFocusRequestProto) {
// Set up valid response.
LoginReputationClientResponse expected_response =
CreateVerdictProto(LoginReputationClientResponse::PHISHING, 10 * kMinute,
......@@ -1038,7 +1113,7 @@ TEST_P(PasswordProtectionServiceTest, VerifyPasswordOnFocusRequestProto) {
#endif
}
TEST_P(PasswordProtectionServiceTest,
TEST_P(PasswordProtectionServiceBaseTest,
VerifyPasswordOnFocusRequestProtoForAllowlistMatch) {
// Set up valid response.
LoginReputationClientResponse expected_response =
......@@ -1062,7 +1137,7 @@ TEST_P(PasswordProtectionServiceTest,
EXPECT_EQ(kTargetUrl, actual_request->frames(0).url());
}
TEST_P(PasswordProtectionServiceTest,
TEST_P(PasswordProtectionServiceBaseTest,
VerifySyncPasswordProtectionRequestProto) {
// Set up valid response.
LoginReputationClientResponse expected_response =
......@@ -1096,7 +1171,7 @@ TEST_P(PasswordProtectionServiceTest,
#endif
}
TEST_P(PasswordProtectionServiceTest,
TEST_P(PasswordProtectionServiceBaseTest,
VerifySavePasswordProtectionRequestProto) {
// Set up valid response.
LoginReputationClientResponse expected_response =
......@@ -1137,7 +1212,7 @@ TEST_P(PasswordProtectionServiceTest,
#endif
}
TEST_P(PasswordProtectionServiceTest, VerifyShouldShowModalWarning) {
TEST_P(PasswordProtectionServiceBaseTest, VerifyShouldShowModalWarning) {
EXPECT_CALL(*password_protection_service_,
GetPasswordProtectionWarningTriggerPref(_))
.WillRepeatedly(Return(PHISHING_REUSE));
......@@ -1289,7 +1364,7 @@ TEST_P(PasswordProtectionServiceTest, VerifyShouldShowModalWarning) {
reused_password_account_type, LoginReputationClientResponse::PHISHING));
}
TEST_P(PasswordProtectionServiceTest, VerifyContentTypeIsPopulated) {
TEST_P(PasswordProtectionServiceBaseTest, VerifyContentTypeIsPopulated) {
LoginReputationClientResponse response =
CreateVerdictProto(LoginReputationClientResponse::SAFE, 10 * kMinute,
GURL(kTargetUrl).host());
......@@ -1312,7 +1387,8 @@ TEST_P(PasswordProtectionServiceTest, VerifyContentTypeIsPopulated) {
password_protection_service_->GetLatestRequestProto()->content_type());
}
TEST_P(PasswordProtectionServiceTest, VerifyIsSupportedPasswordTypeForPinging) {
TEST_P(PasswordProtectionServiceBaseTest,
VerifyIsSupportedPasswordTypeForPinging) {
EXPECT_CALL(*password_protection_service_, IsPrimaryAccountSignedIn())
.WillRepeatedly(Return(true));
AccountInfo account_info;
......@@ -1345,7 +1421,7 @@ TEST_P(PasswordProtectionServiceTest, VerifyIsSupportedPasswordTypeForPinging) {
}
}
TEST_P(PasswordProtectionServiceTest, TestPingsForAboutBlank) {
TEST_P(PasswordProtectionServiceBaseTest, TestPingsForAboutBlank) {
histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogram, 0);
LoginReputationClientResponse expected_response =
CreateVerdictProto(LoginReputationClientResponse::PHISHING, 10 * kMinute,
......@@ -1364,7 +1440,7 @@ TEST_P(PasswordProtectionServiceTest, TestPingsForAboutBlank) {
// DOM features and visual features are not supported on Android.
#if !defined(OS_ANDROID)
TEST_P(PasswordProtectionServiceTest,
TEST_P(PasswordProtectionServiceBaseTest,
TestVisualFeaturesPopulatedInOnFocusPing) {
LoginReputationClientResponse expected_response =
CreateVerdictProto(LoginReputationClientResponse::PHISHING, 10 * kMinute,
......@@ -1390,7 +1466,7 @@ TEST_P(PasswordProtectionServiceTest,
}
}
TEST_P(PasswordProtectionServiceTest, TestDomFeaturesPopulated) {
TEST_P(PasswordProtectionServiceBaseTest, TestDomFeaturesPopulated) {
LoginReputationClientResponse expected_response =
CreateVerdictProto(LoginReputationClientResponse::PHISHING, 10 * kMinute,
GURL("about:blank").host());
......@@ -1412,7 +1488,7 @@ TEST_P(PasswordProtectionServiceTest, TestDomFeaturesPopulated) {
->has_dom_features());
}
TEST_P(PasswordProtectionServiceTest, TestDomFeaturesTimeout) {
TEST_P(PasswordProtectionServiceBaseTest, TestDomFeaturesTimeout) {
password_protection_service_->SetDomFeatureCollectionTimeout(true);
LoginReputationClientResponse expected_response =
CreateVerdictProto(LoginReputationClientResponse::PHISHING, 10 * kMinute,
......@@ -1436,31 +1512,7 @@ TEST_P(PasswordProtectionServiceTest, TestDomFeaturesTimeout) {
}
#endif
TEST_P(PasswordProtectionServiceTest, TestRequestCancelOnTimeout) {
std::unique_ptr<content::WebContents> web_contents = GetWebContents();
InitializeAndStartPasswordOnFocusRequest(true /* match whitelist */,
10000 /* timeout in ms */,
web_contents.get());
auto throttle = std::make_unique<PasswordProtectionNavigationThrottle>(
nullptr, request_, false);
EXPECT_EQ(1U, GetNumberOfNavigationThrottles());
request_->Cancel(true /* timeout */);
EXPECT_EQ(1U, GetNumberOfNavigationThrottles());
}
TEST_P(PasswordProtectionServiceTest, TestRequestCancelNotOnTimeout) {
std::unique_ptr<content::WebContents> web_contents = GetWebContents();
InitializeAndStartPasswordOnFocusRequest(true /* match whitelist */,
10000 /* timeout in ms */,
web_contents.get());
auto throttle = std::make_unique<PasswordProtectionNavigationThrottle>(
nullptr, request_, false);
EXPECT_EQ(1U, GetNumberOfNavigationThrottles());
request_->Cancel(false /* timeout */);
EXPECT_EQ(0U, GetNumberOfNavigationThrottles());
}
TEST_P(PasswordProtectionServiceTest, TestWebContentsDestroyed) {
TEST_P(PasswordProtectionServiceBaseTest, TestWebContentsDestroyed) {
std::unique_ptr<content::WebContents> web_contents = GetWebContents();
InitializeAndStartPasswordOnFocusRequest(false /* match whitelist */,
10000 /* timeout in ms */,
......@@ -1470,9 +1522,9 @@ TEST_P(PasswordProtectionServiceTest, TestWebContentsDestroyed) {
}
INSTANTIATE_TEST_SUITE_P(Regular,
PasswordProtectionServiceTest,
PasswordProtectionServiceBaseTest,
::testing::Values(false));
INSTANTIATE_TEST_SUITE_P(SBER,
PasswordProtectionServiceTest,
PasswordProtectionServiceBaseTest,
::testing::Values(true));
} // namespace safe_browsing
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