Commit 842ceac0 authored by edchin's avatar edchin Committed by Chromium LUCI CQ

[ios][PhishGuard] Create PasswordProtectionRequestContent

Extracts web_contents from PasswordProtectionRequest into a derived
class. The base class will be moved to /core in a future CL.

Bug: 1147967
Change-Id: I011f1a853168ce6c40108bc5d0fb1dd78e1321fe
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2638775
Commit-Queue: edchin <edchin@chromium.org>
Reviewed-by: default avatarAli Juma <ajuma@chromium.org>
Reviewed-by: default avatarBettina Dea <bdea@chromium.org>
Cr-Commit-Position: refs/heads/master@{#845535}
parent 7d10c7b3
......@@ -387,7 +387,9 @@ void ChromePasswordProtectionService::ShowModalWarning(
ReusedPasswordAccountType::SAVED_PASSWORD &&
base::FeatureList::IsEnabled(
safe_browsing::kPasswordProtectionForSavedPasswords)));
content::WebContents* web_contents = request->web_contents();
PasswordProtectionRequestContent* request_content =
static_cast<PasswordProtectionRequestContent*>(request);
content::WebContents* web_contents = request_content->web_contents();
RequestOutcome outcome = request->request_outcome();
// Don't show warning again if there is already a modal warning showing.
if (IsModalWarningShowingInWebContents(web_contents))
......@@ -1235,9 +1237,11 @@ void ChromePasswordProtectionService::MaybeReportPasswordReuseDetected(
extensions::SafeBrowsingPrivateEventRouterFactory::GetForProfile(
profile_);
if (router) {
PasswordProtectionRequestContent* request_content =
static_cast<PasswordProtectionRequestContent*>(request);
router->OnPolicySpecifiedPasswordReuseDetected(
request->web_contents()->GetLastCommittedURL(), username_or_email,
is_phishing_url);
request_content->web_contents()->GetLastCommittedURL(),
username_or_email, is_phishing_url);
}
}
}
......@@ -1627,7 +1631,9 @@ void ChromePasswordProtectionService::
bool ChromePasswordProtectionService::UserClickedThroughSBInterstitial(
PasswordProtectionRequest* request) {
content::WebContents* web_contents = request->web_contents();
PasswordProtectionRequestContent* request_content =
static_cast<PasswordProtectionRequestContent*>(request);
content::WebContents* web_contents = request_content->web_contents();
SBThreatType current_threat_type;
if (!ui_manager_->IsUrlWhitelistedOrPendingForWebContents(
web_contents->GetLastCommittedURL().GetWithEmptyPath(),
......
......@@ -330,7 +330,7 @@ class ChromePasswordProtectionServiceTest
std::vector<password_manager::MatchingReusedCredential> credentials = {
{"somedomain.com"}};
if (trigger_type == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE) {
request_ = new PasswordProtectionRequest(
request_ = new PasswordProtectionRequestContent(
web_contents(), GURL(kPhishingURL), GURL(), GURL(),
web_contents()->GetContentsMimeType(), kUserName,
PasswordType::PASSWORD_TYPE_UNKNOWN, credentials, trigger_type, true,
......@@ -338,7 +338,7 @@ class ChromePasswordProtectionServiceTest
} else {
ASSERT_EQ(LoginReputationClientRequest::PASSWORD_REUSE_EVENT,
trigger_type);
request_ = new PasswordProtectionRequest(
request_ = new PasswordProtectionRequestContent(
web_contents(), GURL(kPhishingURL), GURL(), GURL(),
web_contents()->GetContentsMimeType(), kUserName,
reused_password_type, credentials, trigger_type,
......
......@@ -53,7 +53,7 @@ class PasswordProtectionNavigationThrottleTest
std::make_unique<safe_browsing::MockPasswordProtectionService>();
scoped_refptr<PasswordProtectionRequest> request =
new PasswordProtectionRequest(
new PasswordProtectionRequestContent(
RenderViewHostTestHarness::web_contents(), GURL(), GURL(), GURL(),
RenderViewHostTestHarness::web_contents()->GetContentsMimeType(),
"username", PasswordType::PASSWORD_TYPE_UNKNOWN, credentials,
......
......@@ -101,7 +101,6 @@ bool IsClientSideDetectionEnabled() {
} // namespace
PasswordProtectionRequest::PasswordProtectionRequest(
content::WebContents* web_contents,
const GURL& main_frame_url,
const GURL& password_form_action,
const GURL& password_form_frame_url,
......@@ -114,7 +113,7 @@ PasswordProtectionRequest::PasswordProtectionRequest(
bool password_field_exists,
PasswordProtectionServiceBase* pps,
int request_timeout_in_ms)
: web_contents_(web_contents),
: request_proto_(std::make_unique<LoginReputationClientRequest>()),
main_frame_url_(main_frame_url),
password_form_action_(password_form_action),
password_form_frame_url_(password_form_frame_url),
......@@ -127,7 +126,6 @@ PasswordProtectionRequest::PasswordProtectionRequest(
password_field_exists_(password_field_exists),
password_protection_service_(pps),
request_timeout_in_ms_(request_timeout_in_ms),
request_proto_(std::make_unique<LoginReputationClientRequest>()),
is_modal_warning_showing_(false) {
DCHECK(CurrentlyOnThread(ThreadID::UI));
......@@ -139,9 +137,6 @@ PasswordProtectionRequest::PasswordProtectionRequest(
request_proto_->set_trigger_type(trigger_type_);
*request_proto_->mutable_url_display_experiment() =
pps->GetUrlDisplayExperiment();
request_canceler_ =
RequestCanceler::CreateRequestCanceler(GetWeakPtr(), web_contents);
}
PasswordProtectionRequest::~PasswordProtectionRequest() {
......@@ -346,140 +341,6 @@ void PasswordProtectionRequest::FillRequestProto(bool is_sampled_ping) {
}
}
#if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
void PasswordProtectionRequest::GetDomFeatures() {
content::RenderFrameHost* rfh = web_contents_->GetMainFrame();
password_protection_service_->GetPhishingDetector(rfh->GetRemoteInterfaces(),
&phishing_detector_);
dom_features_collection_complete_ = false;
phishing_detector_->StartPhishingDetection(
main_frame_url_,
base::BindRepeating(&PasswordProtectionRequest::OnGetDomFeatures,
GetWeakPtr()));
GetTaskRunner(ThreadID::UI)
->PostDelayedTask(
FROM_HERE,
base::BindOnce(&PasswordProtectionRequest::OnGetDomFeatureTimeout,
GetWeakPtr()),
base::TimeDelta::FromMilliseconds(kDomFeatureTimeoutMs));
dom_feature_start_time_ = base::TimeTicks::Now();
}
void PasswordProtectionRequest::OnGetDomFeatures(
mojom::PhishingDetectorResult result,
const std::string& verdict) {
DCHECK(CurrentlyOnThread(ThreadID::UI));
if (dom_features_collection_complete_)
return;
UMA_HISTOGRAM_ENUMERATION("PasswordProtection.RendererDomFeatureResult",
result);
if (result != mojom::PhishingDetectorResult::SUCCESS &&
result != mojom::PhishingDetectorResult::INVALID_SCORE)
return;
dom_features_collection_complete_ = true;
ClientPhishingRequest dom_features_request;
if (dom_features_request.ParseFromString(verdict)) {
for (const ClientPhishingRequest::Feature& feature :
dom_features_request.feature_map()) {
DomFeatures::Feature* new_feature =
request_proto_->mutable_dom_features()->add_feature_map();
new_feature->set_name(feature.name());
new_feature->set_value(feature.value());
}
for (const ClientPhishingRequest::Feature& feature :
dom_features_request.non_model_feature_map()) {
DomFeatures::Feature* new_feature =
request_proto_->mutable_dom_features()->add_feature_map();
new_feature->set_name(feature.name());
new_feature->set_value(feature.value());
}
request_proto_->mutable_dom_features()->mutable_shingle_hashes()->Swap(
dom_features_request.mutable_shingle_hashes());
request_proto_->mutable_dom_features()->set_model_version(
dom_features_request.model_version());
}
UMA_HISTOGRAM_TIMES("PasswordProtection.DomFeatureExtractionDuration",
base::TimeTicks::Now() - dom_feature_start_time_);
MaybeCollectVisualFeatures();
}
void PasswordProtectionRequest::OnGetDomFeatureTimeout() {
DCHECK(CurrentlyOnThread(ThreadID::UI));
if (!dom_features_collection_complete_) {
dom_features_collection_complete_ = true;
MaybeCollectVisualFeatures();
}
}
void PasswordProtectionRequest::MaybeCollectVisualFeatures() {
#if BUILDFLAG(SAFE_BROWSING_DB_REMOTE)
SendRequest();
#else
// Once the DOM features are collected, either collect visual features, or go
// straight to sending the ping.
if (trigger_type_ == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE &&
password_protection_service_->IsExtendedReporting() &&
zoom::ZoomController::GetZoomLevelForWebContents(web_contents_) <=
kMaxZoomForVisualFeatures &&
request_proto_->content_area_width() >= kMinWidthForVisualFeatures &&
request_proto_->content_area_height() >= kMinHeightForVisualFeatures) {
CollectVisualFeatures();
} else {
SendRequest();
}
#endif // BUILDFLAG(SAFE_BROWSING_DB_REMOTE)
}
#endif // BUILDFLAG(SAFE_BROWSING_AVAILABLE)
#if BUILDFLAG(FULL_SAFE_BROWSING)
void PasswordProtectionRequest::CollectVisualFeatures() {
content::RenderWidgetHostView* view =
web_contents_ ? web_contents_->GetRenderWidgetHostView() : nullptr;
if (!view) {
SendRequest();
return;
}
visual_feature_start_time_ = base::TimeTicks::Now();
view->CopyFromSurface(
gfx::Rect(), gfx::Size(),
base::BindOnce(&PasswordProtectionRequest::OnScreenshotTaken,
GetWeakPtr()));
}
void PasswordProtectionRequest::OnScreenshotTaken(const SkBitmap& screenshot) {
// Do the feature extraction on a worker thread, to avoid blocking the UI.
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE,
{base::MayBlock(), base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::BindOnce(&ExtractVisualFeatures, screenshot),
base::BindOnce(&PasswordProtectionRequest::OnVisualFeatureCollectionDone,
GetWeakPtr()));
}
void PasswordProtectionRequest::OnVisualFeatureCollectionDone(
std::unique_ptr<VisualFeatures> visual_features) {
DCHECK(CurrentlyOnThread(ThreadID::UI));
request_proto_->mutable_visual_features()->Swap(visual_features.get());
UMA_HISTOGRAM_TIMES("PasswordProtection.VisualFeatureExtractionDuration",
base::TimeTicks::Now() - visual_feature_start_time_);
SendRequest();
}
#endif // BUILDFLAG(FULL_SAFE_BROWSING)
void PasswordProtectionRequest::SendRequest() {
DCHECK(CurrentlyOnThread(ThreadID::UI));
......@@ -604,8 +465,7 @@ void PasswordProtectionRequest::Finish(
LogPasswordEntryRequestOutcome(outcome, password_account_type);
if (password_type_ == PasswordType::PRIMARY_ACCOUNT_PASSWORD) {
password_protection_service_->MaybeLogPasswordReuseLookupEvent(
web_contents_, outcome, password_type_, response.get());
MaybeLogPasswordReuseLookupEvent(outcome, response.get());
}
}
......@@ -641,10 +501,186 @@ void PasswordProtectionRequest::HandleDeferredNavigations() {
throttles_.clear();
}
PasswordProtectionRequestContent::PasswordProtectionRequestContent(
content::WebContents* web_contents,
const GURL& main_frame_url,
const GURL& password_form_action,
const GURL& password_form_frame_url,
const std::string& mime_type,
const std::string& username,
PasswordType password_type,
const std::vector<password_manager::MatchingReusedCredential>&
matching_reused_credentials,
LoginReputationClientRequest::TriggerType type,
bool password_field_exists,
PasswordProtectionServiceBase* pps,
int request_timeout_in_ms)
: PasswordProtectionRequest(main_frame_url,
password_form_action,
password_form_frame_url,
mime_type,
username,
password_type,
matching_reused_credentials,
type,
password_field_exists,
pps,
request_timeout_in_ms),
web_contents_(web_contents) {
request_canceler_ =
RequestCanceler::CreateRequestCanceler(GetWeakPtr(), web_contents);
}
PasswordProtectionRequestContent::~PasswordProtectionRequestContent() = default;
void PasswordProtectionRequestContent::MaybeLogPasswordReuseLookupEvent(
RequestOutcome outcome,
const LoginReputationClientResponse* response) {
password_protection_service()->MaybeLogPasswordReuseLookupEvent(
web_contents_, outcome, password_type(), response);
}
#if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
void PasswordProtectionRequestContent::GetDomFeatures() {
content::RenderFrameHost* rfh = web_contents_->GetMainFrame();
password_protection_service()->GetPhishingDetector(rfh->GetRemoteInterfaces(),
&phishing_detector_);
dom_features_collection_complete_ = false;
phishing_detector_->StartPhishingDetection(
main_frame_url(),
base::BindRepeating(&PasswordProtectionRequestContent::OnGetDomFeatures,
GetWeakPtr()));
GetTaskRunner(ThreadID::UI)
->PostDelayedTask(
FROM_HERE,
base::BindOnce(
&PasswordProtectionRequestContent::OnGetDomFeatureTimeout,
GetWeakPtr()),
base::TimeDelta::FromMilliseconds(kDomFeatureTimeoutMs));
dom_feature_start_time_ = base::TimeTicks::Now();
}
void PasswordProtectionRequestContent::OnGetDomFeatures(
mojom::PhishingDetectorResult result,
const std::string& verdict) {
DCHECK(CurrentlyOnThread(ThreadID::UI));
if (dom_features_collection_complete_)
return;
UMA_HISTOGRAM_ENUMERATION("PasswordProtection.RendererDomFeatureResult",
result);
if (result != mojom::PhishingDetectorResult::SUCCESS &&
result != mojom::PhishingDetectorResult::INVALID_SCORE)
return;
dom_features_collection_complete_ = true;
ClientPhishingRequest dom_features_request;
if (dom_features_request.ParseFromString(verdict)) {
for (const ClientPhishingRequest::Feature& feature :
dom_features_request.feature_map()) {
DomFeatures::Feature* new_feature =
request_proto_->mutable_dom_features()->add_feature_map();
new_feature->set_name(feature.name());
new_feature->set_value(feature.value());
}
for (const ClientPhishingRequest::Feature& feature :
dom_features_request.non_model_feature_map()) {
DomFeatures::Feature* new_feature =
request_proto_->mutable_dom_features()->add_feature_map();
new_feature->set_name(feature.name());
new_feature->set_value(feature.value());
}
request_proto_->mutable_dom_features()->mutable_shingle_hashes()->Swap(
dom_features_request.mutable_shingle_hashes());
request_proto_->mutable_dom_features()->set_model_version(
dom_features_request.model_version());
}
UMA_HISTOGRAM_TIMES("PasswordProtection.DomFeatureExtractionDuration",
base::TimeTicks::Now() - dom_feature_start_time_);
MaybeCollectVisualFeatures();
}
void PasswordProtectionRequestContent::OnGetDomFeatureTimeout() {
DCHECK(CurrentlyOnThread(ThreadID::UI));
if (!dom_features_collection_complete_) {
dom_features_collection_complete_ = true;
MaybeCollectVisualFeatures();
}
}
void PasswordProtectionRequestContent::MaybeCollectVisualFeatures() {
#if BUILDFLAG(SAFE_BROWSING_DB_REMOTE)
SendRequest();
#else
// Once the DOM features are collected, either collect visual features, or go
// straight to sending the ping.
if (trigger_type() == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE &&
password_protection_service()->IsExtendedReporting() &&
zoom::ZoomController::GetZoomLevelForWebContents(web_contents_) <=
kMaxZoomForVisualFeatures &&
request_proto_->content_area_width() >= kMinWidthForVisualFeatures &&
request_proto_->content_area_height() >= kMinHeightForVisualFeatures) {
CollectVisualFeatures();
} else {
SendRequest();
}
#endif // BUILDFLAG(SAFE_BROWSING_DB_REMOTE)
}
#endif // BUILDFLAG(SAFE_BROWSING_AVAILABLE)
#if BUILDFLAG(FULL_SAFE_BROWSING)
void PasswordProtectionRequestContent::CollectVisualFeatures() {
content::RenderWidgetHostView* view =
web_contents_ ? web_contents_->GetRenderWidgetHostView() : nullptr;
if (!view) {
SendRequest();
return;
}
visual_feature_start_time_ = base::TimeTicks::Now();
view->CopyFromSurface(
gfx::Rect(), gfx::Size(),
base::BindOnce(&PasswordProtectionRequestContent::OnScreenshotTaken,
GetWeakPtr()));
}
void PasswordProtectionRequestContent::OnScreenshotTaken(
const SkBitmap& screenshot) {
// Do the feature extraction on a worker thread, to avoid blocking the UI.
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE,
{base::MayBlock(), base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::BindOnce(&ExtractVisualFeatures, screenshot),
base::BindOnce(
&PasswordProtectionRequestContent::OnVisualFeatureCollectionDone,
GetWeakPtr()));
}
void PasswordProtectionRequestContent::OnVisualFeatureCollectionDone(
std::unique_ptr<VisualFeatures> visual_features) {
DCHECK(CurrentlyOnThread(ThreadID::UI));
request_proto_->mutable_visual_features()->Swap(visual_features.get());
UMA_HISTOGRAM_TIMES("PasswordProtection.VisualFeatureExtractionDuration",
base::TimeTicks::Now() - visual_feature_start_time_);
SendRequest();
}
#endif // BUILDFLAG(FULL_SAFE_BROWSING)
#if defined(OS_ANDROID)
void PasswordProtectionRequest::SetReferringAppInfo() {
void PasswordProtectionRequestContent::SetReferringAppInfo() {
LoginReputationClientRequest::ReferringAppInfo referring_app_info =
password_protection_service_->GetReferringAppInfo(web_contents_);
password_protection_service()->GetReferringAppInfo(web_contents_);
UMA_HISTOGRAM_ENUMERATION(
"PasswordProtection.RequestReferringAppSource",
referring_app_info.referring_app_source(),
......
......@@ -85,21 +85,6 @@ class PasswordProtectionRequest
public base::RefCountedThreadSafe<PasswordProtectionRequest,
DeleteOnUIThread> {
public:
PasswordProtectionRequest(
content::WebContents* web_contents,
const GURL& main_frame_url,
const GURL& password_form_action,
const GURL& password_form_frame_url,
const std::string& mime_type,
const std::string& username,
PasswordType password_type,
const std::vector<password_manager::MatchingReusedCredential>&
matching_reused_credentials,
LoginReputationClientRequest::TriggerType type,
bool password_field_exists,
PasswordProtectionServiceBase* pps,
int request_timeout_in_ms);
// Not copyable or movable
PasswordProtectionRequest(const PasswordProtectionRequest&) = delete;
PasswordProtectionRequest& operator=(const PasswordProtectionRequest&) =
......@@ -125,8 +110,6 @@ class PasswordProtectionRequest
return request_proto_.get();
}
content::WebContents* web_contents() const { return web_contents_; }
LoginReputationClientRequest::TriggerType trigger_type() const {
return trigger_type_;
}
......@@ -171,12 +154,44 @@ class PasswordProtectionRequest
protected:
friend class base::RefCountedThreadSafe<PasswordProtectionRequest>;
PasswordProtectionRequest(
const GURL& main_frame_url,
const GURL& password_form_action,
const GURL& password_form_frame_url,
const std::string& mime_type,
const std::string& username,
PasswordType password_type,
const std::vector<password_manager::MatchingReusedCredential>&
matching_reused_credentials,
LoginReputationClientRequest::TriggerType type,
bool password_field_exists,
PasswordProtectionServiceBase* pps,
int request_timeout_in_ms);
~PasswordProtectionRequest() override;
// Initiates network request to Safe Browsing backend.
void SendRequest();
// Records an event for the result of the URL reputation lookup if the user
// enters their password on a website.
virtual void MaybeLogPasswordReuseLookupEvent(
RequestOutcome outcome,
const LoginReputationClientResponse* response) = 0;
// The PasswordProtectionServiceBase instance owns |this|.
// Can only be accessed on UI thread.
PasswordProtectionServiceBase* password_protection_service() {
return password_protection_service_;
}
std::unique_ptr<LoginReputationClientRequest> request_proto_;
private:
friend DeleteOnUIThread;
friend class base::DeleteHelper<PasswordProtectionRequest>;
friend class PasswordProtectionServiceTest;
friend class ChromePasswordProtectionServiceTest;
~PasswordProtectionRequest() override;
// Start checking the whitelist.
void CheckWhitelist();
......@@ -198,40 +213,14 @@ class PasswordProtectionRequest
#if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
// Extracts DOM features.
void GetDomFeatures();
// Called when the DOM feature extraction is complete.
void OnGetDomFeatures(mojom::PhishingDetectorResult result,
const std::string& verdict);
// Called when the DOM feature extraction times out.
void OnGetDomFeatureTimeout();
// If appropriate, collects visual features, otherwise continues on to sending
// the request.
void MaybeCollectVisualFeatures();
virtual void GetDomFeatures() = 0;
#endif // BUILDFLAG(SAFE_BROWSING_AVAILABLE)
#if BUILDFLAG(FULL_SAFE_BROWSING)
// Collects visual features from the current login page.
void CollectVisualFeatures();
// Processes the screenshot of the login page into visual features.
void OnScreenshotTaken(const SkBitmap& bitmap);
// Called when the visual feature extraction is complete.
void OnVisualFeatureCollectionDone(
std::unique_ptr<VisualFeatures> visual_features);
#endif // BUILDFLAG(FULL_SAFE_BROWSING)
#if defined(OS_ANDROID)
// Sets the referring app info.
void SetReferringAppInfo();
virtual void SetReferringAppInfo() = 0;
#endif // defined(OS_ANDROID)
// Initiates network request to Safe Browsing backend.
void SendRequest();
// Start a timer to cancel the request if it takes too long.
void StartTimeout();
......@@ -239,9 +228,6 @@ class PasswordProtectionRequest
void Finish(RequestOutcome outcome,
std::unique_ptr<LoginReputationClientResponse> response);
// WebContents of the password protection event.
content::WebContents* web_contents_;
// Main frame URL of the login form.
const GURL main_frame_url_;
......@@ -296,8 +282,6 @@ class PasswordProtectionRequest
// request.
const int request_timeout_in_ms_;
std::unique_ptr<LoginReputationClientRequest> request_proto_;
// Needed for canceling tasks posted to different threads.
base::CancelableTaskTracker tracker_;
......@@ -312,6 +296,77 @@ class PasswordProtectionRequest
// If a request is sent, this is the token returned by the WebUI.
int web_ui_token_;
base::WeakPtrFactory<PasswordProtectionRequest> weakptr_factory_{this};
};
class PasswordProtectionRequestContent : public PasswordProtectionRequest {
public:
PasswordProtectionRequestContent(
content::WebContents* web_contents,
const GURL& main_frame_url,
const GURL& password_form_action,
const GURL& password_form_frame_url,
const std::string& mime_type,
const std::string& username,
PasswordType password_type,
const std::vector<password_manager::MatchingReusedCredential>&
matching_reused_credentials,
LoginReputationClientRequest::TriggerType type,
bool password_field_exists,
PasswordProtectionServiceBase* pps,
int request_timeout_in_ms);
content::WebContents* web_contents() const { return web_contents_; }
base::WeakPtr<PasswordProtectionRequestContent> GetWeakPtr() {
return weakptr_factory_.GetWeakPtr();
}
private:
~PasswordProtectionRequestContent() override;
void MaybeLogPasswordReuseLookupEvent(
RequestOutcome outcome,
const LoginReputationClientResponse* response) override;
#if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
// Extracts DOM features.
void GetDomFeatures() override;
// Called when the DOM feature extraction is complete.
void OnGetDomFeatures(mojom::PhishingDetectorResult result,
const std::string& verdict);
// Called when the DOM feature extraction times out.
void OnGetDomFeatureTimeout();
// If appropriate, collects visual features, otherwise continues on to sending
// the request.
void MaybeCollectVisualFeatures();
#endif // BUILDFLAG(SAFE_BROWSING_AVAILABLE)
#if BUILDFLAG(FULL_SAFE_BROWSING)
// Collects visual features from the current login page.
void CollectVisualFeatures();
// Processes the screenshot of the login page into visual features.
void OnScreenshotTaken(const SkBitmap& bitmap);
// Called when the visual feature extraction is complete.
void OnVisualFeatureCollectionDone(
std::unique_ptr<VisualFeatures> visual_features);
#endif // BUILDFLAG(FULL_SAFE_BROWSING)
#if defined(OS_ANDROID)
void SetReferringAppInfo() override;
#endif // defined(OS_ANDROID)
// WebContents of the password protection event.
content::WebContents* web_contents_;
// Cancels the request when it is no longer valid.
std::unique_ptr<RequestCanceler> request_canceler_;
#if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
// When we start extracting visual features.
base::TimeTicks visual_feature_start_time_;
......@@ -329,10 +384,7 @@ class PasswordProtectionRequest
bool dom_features_collection_complete_;
#endif // BUILDFLAG(SAFE_BROWSING_AVAILABLE)
// Cancels the request when it is no longer valid.
std::unique_ptr<RequestCanceler> request_canceler_;
base::WeakPtrFactory<PasswordProtectionRequest> weakptr_factory_{this};
base::WeakPtrFactory<PasswordProtectionRequestContent> weakptr_factory_{this};
};
} // namespace safe_browsing
......
......@@ -206,7 +206,7 @@ void PasswordProtectionServiceBase::StartRequest(
bool password_field_exists) {
DCHECK(CurrentlyOnThread(ThreadID::UI));
scoped_refptr<PasswordProtectionRequest> request(
new PasswordProtectionRequest(
new PasswordProtectionRequestContent(
web_contents, main_frame_url, password_form_action,
password_form_frame_url, web_contents->GetContentsMimeType(),
username, password_type, matching_reused_credentials, trigger_type,
......@@ -541,7 +541,9 @@ PasswordProtectionService::MaybeCreateNavigationThrottle(
content::WebContents* web_contents = navigation_handle->GetWebContents();
for (scoped_refptr<PasswordProtectionRequest> request : pending_requests_) {
if (request->web_contents() == web_contents &&
PasswordProtectionRequestContent* request_content =
static_cast<PasswordProtectionRequestContent*>(request.get());
if (request_content->web_contents() == web_contents &&
request->trigger_type() ==
safe_browsing::LoginReputationClientRequest::PASSWORD_REUSE_EVENT &&
IsSupportedPasswordTypeForModalWarning(
......@@ -553,7 +555,9 @@ PasswordProtectionService::MaybeCreateNavigationThrottle(
}
for (scoped_refptr<PasswordProtectionRequest> request : warning_requests_) {
if (request->web_contents() == web_contents) {
PasswordProtectionRequestContent* request_content =
static_cast<PasswordProtectionRequestContent*>(request.get());
if (request_content->web_contents() == web_contents) {
return std::make_unique<PasswordProtectionNavigationThrottle>(
navigation_handle, request, /*is_warning_showing=*/true);
}
......@@ -564,7 +568,9 @@ PasswordProtectionService::MaybeCreateNavigationThrottle(
void PasswordProtectionService::RemoveWarningRequestsByWebContents(
content::WebContents* web_contents) {
for (auto it = warning_requests_.begin(); it != warning_requests_.end();) {
if (it->get()->web_contents() == web_contents)
PasswordProtectionRequestContent* request_content =
static_cast<PasswordProtectionRequestContent*>(it->get());
if (request_content->web_contents() == web_contents)
it = warning_requests_.erase(it);
else
++it;
......@@ -574,7 +580,9 @@ void PasswordProtectionService::RemoveWarningRequestsByWebContents(
bool PasswordProtectionService::IsModalWarningShowingInWebContents(
content::WebContents* web_contents) {
for (const auto& request : warning_requests_) {
if (request->web_contents() == web_contents)
PasswordProtectionRequestContent* request_content =
static_cast<PasswordProtectionRequestContent*>(request.get());
if (request_content->web_contents() == web_contents)
return true;
}
return false;
......
......@@ -292,6 +292,7 @@ class PasswordProtectionServiceBase : public history::HistoryServiceObserver {
protected:
friend class PasswordProtectionRequest;
friend class PasswordProtectionRequestContent;
// Chrome can send password protection ping if it is allowed by for the
// |trigger_type| and |password_type| and if Safe Browsing can compute
......
......@@ -254,14 +254,16 @@ class PasswordProtectionServiceTest : public ::testing::Test {
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);
request_ =
base::MakeRefCounted<safe_browsing::PasswordProtectionRequestContent>(
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 {
......@@ -367,7 +369,7 @@ class PasswordProtectionServiceBaseTest
.WillRepeatedly(
Return(match_whitelist ? AsyncMatch::MATCH : AsyncMatch::NO_MATCH));
request_ = new PasswordProtectionRequest(
request_ = new PasswordProtectionRequestContent(
web_contents, target_url, GURL(kFormActionUrl), GURL(kPasswordFrameUrl),
web_contents->GetContentsMimeType(), kUserName,
PasswordType::PASSWORD_TYPE_UNKNOWN, {},
......@@ -388,7 +390,7 @@ class PasswordProtectionServiceBaseTest
.WillRepeatedly(
Return(match_whitelist ? AsyncMatch::MATCH : AsyncMatch::NO_MATCH));
request_ = new PasswordProtectionRequest(
request_ = new PasswordProtectionRequestContent(
web_contents, target_url, GURL(), GURL(),
web_contents->GetContentsMimeType(), kUserName, type,
matching_reused_credentials,
......
......@@ -9,13 +9,13 @@
namespace safe_browsing {
scoped_refptr<PasswordProtectionRequest> CreateDummyRequest(
scoped_refptr<PasswordProtectionRequestContent> CreateDummyRequest(
content::WebContents* web_contents) {
std::unique_ptr<safe_browsing::MockPasswordProtectionService>
password_protection_service =
std::make_unique<safe_browsing::MockPasswordProtectionService>();
scoped_refptr<PasswordProtectionRequest> request =
base::MakeRefCounted<PasswordProtectionRequest>(
scoped_refptr<PasswordProtectionRequestContent> request =
base::MakeRefCounted<PasswordProtectionRequestContent>(
web_contents, GURL(), GURL(), GURL(),
web_contents->GetContentsMimeType(), "",
PasswordType::PASSWORD_TYPE_UNKNOWN,
......
......@@ -16,7 +16,7 @@ namespace safe_browsing {
// Returns a request object with |web_contents|. Other request options are set
// to some default value and potentially nonsensical.
scoped_refptr<PasswordProtectionRequest> CreateDummyRequest(
scoped_refptr<PasswordProtectionRequestContent> CreateDummyRequest(
content::WebContents* web_contents);
} // 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