Commit 34ee95d5 authored by yilkal's avatar yilkal Committed by Commit Bot

Prevent multiple requests on the same tab.

This CL prevents users from making multiple requests
from the same tab for the same host address.

The requests can be repeated by opening a new tab.
The requests can be repeated in the next session.

Bug: 1045155
Change-Id: If0a7549fe7509ff6ece8c1701e449294a85c56aa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2020543Reviewed-by: default avatarAga Wronska <agawronska@chromium.org>
Commit-Queue: Yilkal Abe <yilkal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#736221}
parent 892f7d50
...@@ -42,11 +42,11 @@ ...@@ -42,11 +42,11 @@
</div> </div>
</div> </div>
<div class="button-container"> <div class="button-container">
<button id="request-access-button" class="ask-permission-button"> <button id="request-access-button" class="ask-permission-button" hidden>
$i18n{requestAccessButton} $i18n{requestAccessButton}
</button> </button>
<div id="details-button-container"> <div id="details-button-container">
<button id="show-details-link" class="details-button small-link"> <button id="show-details-link" class="details-button small-link" hidden>
$i18n{showDetailsLink} $i18n{showDetailsLink}
</button> </button>
<button id="hide-details-link" class="details-button small-link" hidden> <button id="hide-details-link" class="details-button small-link" hidden>
......
...@@ -38,14 +38,6 @@ function makeImageSet(url1x, url2x) { ...@@ -38,14 +38,6 @@ function makeImageSet(url1x, url2x) {
function initialize() { function initialize() {
var allowAccessRequests = loadTimeData.getBoolean('allowAccessRequests'); var allowAccessRequests = loadTimeData.getBoolean('allowAccessRequests');
if (allowAccessRequests) {
$('request-access-button').onclick = function(event) {
$('request-access-button').hidden = true;
sendCommand('request');
};
} else {
$('request-access-button').hidden = true;
}
var avatarURL1x = loadTimeData.getString('avatarURL1x'); var avatarURL1x = loadTimeData.getString('avatarURL1x');
var avatarURL2x = loadTimeData.getString('avatarURL2x'); var avatarURL2x = loadTimeData.getString('avatarURL2x');
var custodianName = loadTimeData.getString('custodianName'); var custodianName = loadTimeData.getString('custodianName');
...@@ -72,10 +64,30 @@ function initialize() { ...@@ -72,10 +64,30 @@ function initialize() {
'secondCustodianEmail'); 'secondCustodianEmail');
} }
} }
var already_requested_access = loadTimeData.getBoolean('alreadySentRequest');
if (already_requested_access) {
var is_main_frame = loadTimeData.getBoolean('isMainFrame');
requestCreated(true, is_main_frame);
return;
}
if (allowAccessRequests) {
$('request-access-button').hidden = false;
$('request-access-button').onclick = function(event) {
$('request-access-button').hidden = true;
sendCommand('request');
};
} else {
$('request-access-button').hidden = true;
}
$('back-button').onclick = function(event) { $('back-button').onclick = function(event) {
sendCommand('back'); sendCommand('back');
}; };
if (loadTimeData.getBoolean('showFeedbackLink')) { if (loadTimeData.getBoolean('showFeedbackLink')) {
$('show-details-link').hidden = false;
$('show-details-link').onclick = function(event) { $('show-details-link').onclick = function(event) {
showDetails = true; showDetails = true;
$('show-details-link').hidden = true; $('show-details-link').hidden = true;
...@@ -105,6 +117,16 @@ function initialize() { ...@@ -105,6 +117,16 @@ function initialize() {
*/ */
function setRequestStatus(isSuccessful, isMainFrame) { function setRequestStatus(isSuccessful, isMainFrame) {
console.log('setRequestStatus(' + isSuccessful +')'); console.log('setRequestStatus(' + isSuccessful +')');
requestCreated(isSuccessful, isMainFrame)
}
/**
* Updates the interstitial to show that the request failed or was sent.
* @param {boolean} isSuccessful Whether the request was successful or not.
* @param {boolean} isMainFrame Whether the interstitial is being shown in main
* frame.
*/
function requestCreated(isSuccessful, isMainFrame) {
$('block-page-header').hidden = true; $('block-page-header').hidden = true;
$('block-page-message').hidden = true; $('block-page-message').hidden = true;
$('hide-details-link').hidden = true; $('hide-details-link').hidden = true;
......
...@@ -81,6 +81,26 @@ std::string BuildHtml(bool allow_access_requests, ...@@ -81,6 +81,26 @@ std::string BuildHtml(bool allow_access_requests,
bool is_deprecated, bool is_deprecated,
FilteringBehaviorReason reason, FilteringBehaviorReason reason,
const std::string& app_locale) { const std::string& app_locale) {
return BuildHtml(allow_access_requests, profile_image_url, profile_image_url2,
custodian, custodian_email, second_custodian,
second_custodian_email, is_child_account, is_deprecated,
reason, app_locale, /* already_sent_request */ false,
/* is_main_frame */ true);
}
std::string BuildHtml(bool allow_access_requests,
const std::string& profile_image_url,
const std::string& profile_image_url2,
const std::string& custodian,
const std::string& custodian_email,
const std::string& second_custodian,
const std::string& second_custodian_email,
bool is_child_account,
bool is_deprecated,
FilteringBehaviorReason reason,
const std::string& app_locale,
bool already_sent_request,
bool is_main_frame) {
base::DictionaryValue strings; base::DictionaryValue strings;
strings.SetString("blockPageTitle", strings.SetString("blockPageTitle",
l10n_util::GetStringUTF16(IDS_BLOCK_INTERSTITIAL_TITLE)); l10n_util::GetStringUTF16(IDS_BLOCK_INTERSTITIAL_TITLE));
...@@ -97,6 +117,8 @@ std::string BuildHtml(bool allow_access_requests, ...@@ -97,6 +117,8 @@ std::string BuildHtml(bool allow_access_requests,
strings.SetString("custodianEmail", custodian_email); strings.SetString("custodianEmail", custodian_email);
strings.SetString("secondCustodianName", second_custodian); strings.SetString("secondCustodianName", second_custodian);
strings.SetString("secondCustodianEmail", second_custodian_email); strings.SetString("secondCustodianEmail", second_custodian_email);
strings.SetBoolean("alreadySentRequest", already_sent_request);
strings.SetBoolean("isMainFrame", is_main_frame);
base::string16 custodian16 = base::UTF8ToUTF16(custodian); base::string16 custodian16 = base::UTF8ToUTF16(custodian);
base::string16 block_header; base::string16 block_header;
......
...@@ -26,6 +26,9 @@ int GetBlockMessageID( ...@@ -26,6 +26,9 @@ int GetBlockMessageID(
bool is_child_account, bool is_child_account,
bool single_parent); bool single_parent);
// This function assumes that the error page will be displayed in the main
// frame. It also assumes that there was no request already sent to access the
// blocked url.
std::string BuildHtml(bool allow_access_requests, std::string BuildHtml(bool allow_access_requests,
const std::string& profile_image_url, const std::string& profile_image_url,
const std::string& profile_image_url2, const std::string& profile_image_url2,
...@@ -38,6 +41,20 @@ std::string BuildHtml(bool allow_access_requests, ...@@ -38,6 +41,20 @@ std::string BuildHtml(bool allow_access_requests,
FilteringBehaviorReason reason, FilteringBehaviorReason reason,
const std::string& app_locale); const std::string& app_locale);
std::string BuildHtml(bool allow_access_requests,
const std::string& profile_image_url,
const std::string& profile_image_url2,
const std::string& custodian,
const std::string& custodian_email,
const std::string& second_custodian,
const std::string& second_custodian_email,
bool is_child_account,
bool is_deprecated,
FilteringBehaviorReason reason,
const std::string& app_locale,
bool already_sent_request,
bool is_main_frame);
} // namespace supervised_user_error_page } // namespace supervised_user_error_page
#endif // CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_ERROR_PAGE_SUPERVISED_USER_ERROR_PAGE_H_ #endif // CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_ERROR_PAGE_SUPERVISED_USER_ERROR_PAGE_H_
...@@ -180,7 +180,9 @@ SupervisedUserInterstitial::~SupervisedUserInterstitial() {} ...@@ -180,7 +180,9 @@ SupervisedUserInterstitial::~SupervisedUserInterstitial() {}
// static // static
std::string SupervisedUserInterstitial::GetHTMLContents( std::string SupervisedUserInterstitial::GetHTMLContents(
Profile* profile, Profile* profile,
supervised_user_error_page::FilteringBehaviorReason reason) { supervised_user_error_page::FilteringBehaviorReason reason,
bool already_sent_request,
bool is_main_frame) {
bool is_child_account = profile->IsChild(); bool is_child_account = profile->IsChild();
bool is_deprecated = !is_child_account; bool is_deprecated = !is_child_account;
...@@ -206,7 +208,8 @@ std::string SupervisedUserInterstitial::GetHTMLContents( ...@@ -206,7 +208,8 @@ std::string SupervisedUserInterstitial::GetHTMLContents(
allow_access_requests, profile_image_url, profile_image_url2, custodian, allow_access_requests, profile_image_url, profile_image_url2, custodian,
custodian_email, second_custodian, second_custodian_email, custodian_email, second_custodian, second_custodian_email,
is_child_account, is_deprecated, reason, is_child_account, is_deprecated, reason,
g_browser_process->GetApplicationLocale()); g_browser_process->GetApplicationLocale(), already_sent_request,
is_main_frame);
} }
void SupervisedUserInterstitial::GoBack() { void SupervisedUserInterstitial::GoBack() {
......
...@@ -37,7 +37,9 @@ class SupervisedUserInterstitial { ...@@ -37,7 +37,9 @@ class SupervisedUserInterstitial {
static std::string GetHTMLContents( static std::string GetHTMLContents(
Profile* profile, Profile* profile,
supervised_user_error_page::FilteringBehaviorReason reason); supervised_user_error_page::FilteringBehaviorReason reason,
bool already_sent_request,
bool is_main_frame);
void GoBack(); void GoBack();
void RequestPermission(base::OnceCallback<void(bool)> callback); void RequestPermission(base::OnceCallback<void(bool)> callback);
......
...@@ -77,15 +77,15 @@ void SupervisedUserNavigationObserver::OnRequestBlocked( ...@@ -77,15 +77,15 @@ void SupervisedUserNavigationObserver::OnRequestBlocked(
supervised_user_error_page::FilteringBehaviorReason reason, supervised_user_error_page::FilteringBehaviorReason reason,
int64_t navigation_id, int64_t navigation_id,
int frame_id, int frame_id,
const base::Callback< const OnInterstitialResultCallback& callback) {
void(SupervisedUserNavigationThrottle::CallbackActions)>& callback) {
SupervisedUserNavigationObserver* navigation_observer = SupervisedUserNavigationObserver* navigation_observer =
SupervisedUserNavigationObserver::FromWebContents(web_contents); SupervisedUserNavigationObserver::FromWebContents(web_contents);
// Cancel the navigation if there is no navigation observer. // Cancel the navigation if there is no navigation observer.
if (!navigation_observer) { if (!navigation_observer) {
callback.Run( callback.Run(
SupervisedUserNavigationThrottle::CallbackActions::kCancelNavigation); SupervisedUserNavigationThrottle::CallbackActions::kCancelNavigation,
/* already_requested_permission */ false, /* is_main_frame */ false);
return; return;
} }
...@@ -172,6 +172,8 @@ void SupervisedUserNavigationObserver::OnURLFilterChanged() { ...@@ -172,6 +172,8 @@ void SupervisedUserNavigationObserver::OnURLFilterChanged() {
web_contents()->GetLastCommittedURL(), web_contents()->GetLastCommittedURL(),
main_frame_process_id, routing_id)); main_frame_process_id, routing_id));
MaybeUpdateRequestedHosts();
Profile* profile = Profile* profile =
Profile::FromBrowserContext(web_contents()->GetBrowserContext()); Profile::FromBrowserContext(web_contents()->GetBrowserContext());
SupervisedUserService* service = SupervisedUserService* service =
...@@ -194,8 +196,7 @@ void SupervisedUserNavigationObserver::OnRequestBlockedInternal( ...@@ -194,8 +196,7 @@ void SupervisedUserNavigationObserver::OnRequestBlockedInternal(
supervised_user_error_page::FilteringBehaviorReason reason, supervised_user_error_page::FilteringBehaviorReason reason,
int64_t navigation_id, int64_t navigation_id,
int frame_id, int frame_id,
const base::Callback< const OnInterstitialResultCallback& callback) {
void(SupervisedUserNavigationThrottle::CallbackActions)>& callback) {
// TODO(bauerb): Use SaneTime when available. // TODO(bauerb): Use SaneTime when available.
base::Time timestamp = base::Time::Now(); base::Time timestamp = base::Time::Now();
// Create a history entry for the attempt and mark it as such. This history // Create a history entry for the attempt and mark it as such. This history
...@@ -273,16 +274,20 @@ void SupervisedUserNavigationObserver::MaybeShowInterstitial( ...@@ -273,16 +274,20 @@ void SupervisedUserNavigationObserver::MaybeShowInterstitial(
bool initial_page_load, bool initial_page_load,
int64_t navigation_id, int64_t navigation_id,
int frame_id, int frame_id,
const base::Callback< const OnInterstitialResultCallback& callback) {
void(SupervisedUserNavigationThrottle::CallbackActions)>& callback) {
std::unique_ptr<SupervisedUserInterstitial> interstitial = std::unique_ptr<SupervisedUserInterstitial> interstitial =
SupervisedUserInterstitial::Create(web_contents(), url, reason, frame_id, SupervisedUserInterstitial::Create(web_contents(), url, reason, frame_id,
navigation_id); navigation_id);
supervised_user_interstitials_[frame_id] = std::move(interstitial); supervised_user_interstitials_[frame_id] = std::move(interstitial);
bool already_requested = base::Contains(requested_hosts_, url.host());
bool is_main_frame =
frame_id == web_contents()->GetMainFrame()->GetFrameTreeNodeId();
callback.Run(SupervisedUserNavigationThrottle::CallbackActions:: callback.Run(SupervisedUserNavigationThrottle::CallbackActions::
kCancelWithInterstitial); kCancelWithInterstitial,
already_requested, is_main_frame);
} }
void SupervisedUserNavigationObserver::FilterRenderFrame( void SupervisedUserNavigationObserver::FilterRenderFrame(
...@@ -321,8 +326,15 @@ void SupervisedUserNavigationObserver::RequestPermission( ...@@ -321,8 +326,15 @@ void SupervisedUserNavigationObserver::RequestPermission(
auto* render_frame_host = receiver_.GetCurrentTargetFrame(); auto* render_frame_host = receiver_.GetCurrentTargetFrame();
int id = render_frame_host->GetFrameTreeNodeId(); int id = render_frame_host->GetFrameTreeNodeId();
if (base::Contains(supervised_user_interstitials_, id)) if (base::Contains(supervised_user_interstitials_, id)) {
supervised_user_interstitials_[id]->RequestPermission(std::move(callback)); SupervisedUserInterstitial* interstitial =
supervised_user_interstitials_[id].get();
interstitial->RequestPermission(
base::BindOnce(&SupervisedUserNavigationObserver::RequestCreated,
weak_ptr_factory_.GetWeakPtr(), std::move(callback),
interstitial->url().host()));
}
} }
void SupervisedUserNavigationObserver::Feedback() { void SupervisedUserNavigationObserver::Feedback() {
...@@ -333,4 +345,29 @@ void SupervisedUserNavigationObserver::Feedback() { ...@@ -333,4 +345,29 @@ void SupervisedUserNavigationObserver::Feedback() {
supervised_user_interstitials_[id]->ShowFeedback(); supervised_user_interstitials_[id]->ShowFeedback();
} }
void SupervisedUserNavigationObserver::RequestCreated(
RequestPermissionCallback callback,
const std::string& host,
bool successfully_created_request) {
if (successfully_created_request)
requested_hosts_.insert(host);
std::move(callback).Run(successfully_created_request);
}
void SupervisedUserNavigationObserver::MaybeUpdateRequestedHosts() {
SupervisedUserURLFilter::FilteringBehavior filtering_behavior;
for (auto iter = requested_hosts_.begin(); iter != requested_hosts_.end();) {
bool is_manual = url_filter_->GetManualFilteringBehaviorForURL(
GURL(*iter), &filtering_behavior);
if (is_manual && filtering_behavior ==
SupervisedUserURLFilter::FilteringBehavior::ALLOW) {
iter = requested_hosts_.erase(iter);
} else {
iter++;
}
}
}
WEB_CONTENTS_USER_DATA_KEY_IMPL(SupervisedUserNavigationObserver) WEB_CONTENTS_USER_DATA_KEY_IMPL(SupervisedUserNavigationObserver)
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
#ifndef CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_NAVIGATION_OBSERVER_H_ #ifndef CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_NAVIGATION_OBSERVER_H_
#define CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_NAVIGATION_OBSERVER_H_ #define CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_NAVIGATION_OBSERVER_H_
#include <map>
#include <memory> #include <memory>
#include <set>
#include <vector> #include <vector>
#include "base/macros.h" #include "base/macros.h"
...@@ -29,6 +31,9 @@ class RenderFrameHost; ...@@ -29,6 +31,9 @@ class RenderFrameHost;
class WebContents; class WebContents;
} // namespace content } // namespace content
using OnInterstitialResultCallback = base::RepeatingCallback<
void(SupervisedUserNavigationThrottle::CallbackActions, bool, bool)>;
class SupervisedUserNavigationObserver class SupervisedUserNavigationObserver
: public content::WebContentsUserData<SupervisedUserNavigationObserver>, : public content::WebContentsUserData<SupervisedUserNavigationObserver>,
public content::WebContentsObserver, public content::WebContentsObserver,
...@@ -53,8 +58,7 @@ class SupervisedUserNavigationObserver ...@@ -53,8 +58,7 @@ class SupervisedUserNavigationObserver
supervised_user_error_page::FilteringBehaviorReason reason, supervised_user_error_page::FilteringBehaviorReason reason,
int64_t navigation_id, int64_t navigation_id,
int frame_id, int frame_id,
const base::Callback< const OnInterstitialResultCallback& callback);
void(SupervisedUserNavigationThrottle::CallbackActions)>& callback);
void UpdateMainFrameFilteringStatus( void UpdateMainFrameFilteringStatus(
SupervisedUserURLFilter::FilteringBehavior behavior, SupervisedUserURLFilter::FilteringBehavior behavior,
...@@ -85,10 +89,14 @@ class SupervisedUserNavigationObserver ...@@ -85,10 +89,14 @@ class SupervisedUserNavigationObserver
void OnInterstitialDone(int frame_id); void OnInterstitialDone(int frame_id);
const std::map<int, std::unique_ptr<SupervisedUserInterstitial>>& const std::map<int, std::unique_ptr<SupervisedUserInterstitial>>&
interstitials_for_test() { interstitials_for_test() const {
return supervised_user_interstitials_; return supervised_user_interstitials_;
} }
const std::set<std::string>& requested_hosts_for_test() const {
return requested_hosts_;
}
private: private:
friend class content::WebContentsUserData<SupervisedUserNavigationObserver>; friend class content::WebContentsUserData<SupervisedUserNavigationObserver>;
...@@ -99,8 +107,7 @@ class SupervisedUserNavigationObserver ...@@ -99,8 +107,7 @@ class SupervisedUserNavigationObserver
supervised_user_error_page::FilteringBehaviorReason reason, supervised_user_error_page::FilteringBehaviorReason reason,
int64_t navigation_id, int64_t navigation_id,
int frame_id, int frame_id,
const base::Callback< const OnInterstitialResultCallback& callback);
void(SupervisedUserNavigationThrottle::CallbackActions)>& callback);
void URLFilterCheckCallback( void URLFilterCheckCallback(
const GURL& url, const GURL& url,
...@@ -116,8 +123,7 @@ class SupervisedUserNavigationObserver ...@@ -116,8 +123,7 @@ class SupervisedUserNavigationObserver
bool initial_page_load, bool initial_page_load,
int64_t navigation_id, int64_t navigation_id,
int frame_id, int frame_id,
const base::Callback< const OnInterstitialResultCallback& callback);
void(SupervisedUserNavigationThrottle::CallbackActions)>& callback);
// Filters the render frame host if render frame is live. // Filters the render frame host if render frame is live.
void FilterRenderFrame(content::RenderFrameHost* render_frame_host); void FilterRenderFrame(content::RenderFrameHost* render_frame_host);
...@@ -129,6 +135,16 @@ class SupervisedUserNavigationObserver ...@@ -129,6 +135,16 @@ class SupervisedUserNavigationObserver
void RequestPermission(RequestPermissionCallback callback) override; void RequestPermission(RequestPermissionCallback callback) override;
void Feedback() override; void Feedback() override;
// When a request is successfully created, this method is called
// asynchronously.
void RequestCreated(RequestPermissionCallback callback,
const std::string& host,
bool successfully_created_request);
// Called when the url filter changes i.e. whitelist or blacklist change to
// clear up entries in |requested_hosts_| which have been whitelisted.
void MaybeUpdateRequestedHosts();
// Owned by SupervisedUserService. // Owned by SupervisedUserService.
const SupervisedUserURLFilter* url_filter_; const SupervisedUserURLFilter* url_filter_;
...@@ -140,6 +156,8 @@ class SupervisedUserNavigationObserver ...@@ -140,6 +156,8 @@ class SupervisedUserNavigationObserver
std::map<int, std::unique_ptr<SupervisedUserInterstitial>> std::map<int, std::unique_ptr<SupervisedUserInterstitial>>
supervised_user_interstitials_; supervised_user_interstitials_;
std::set<std::string> requested_hosts_;
SupervisedUserURLFilter::FilteringBehavior main_frame_filtering_behavior_ = SupervisedUserURLFilter::FilteringBehavior main_frame_filtering_behavior_ =
SupervisedUserURLFilter::FilteringBehavior::ALLOW; SupervisedUserURLFilter::FilteringBehavior::ALLOW;
supervised_user_error_page::FilteringBehaviorReason supervised_user_error_page::FilteringBehaviorReason
......
...@@ -251,7 +251,9 @@ void SupervisedUserNavigationThrottle::OnCheckDone( ...@@ -251,7 +251,9 @@ void SupervisedUserNavigationThrottle::OnCheckDone(
} }
void SupervisedUserNavigationThrottle::OnInterstitialResult( void SupervisedUserNavigationThrottle::OnInterstitialResult(
CallbackActions action) { CallbackActions action,
bool already_sent_request,
bool is_main_frame) {
switch (action) { switch (action) {
case kCancelNavigation: { case kCancelNavigation: {
CancelDeferredNavigation(CANCEL); CancelDeferredNavigation(CANCEL);
...@@ -262,7 +264,7 @@ void SupervisedUserNavigationThrottle::OnInterstitialResult( ...@@ -262,7 +264,7 @@ void SupervisedUserNavigationThrottle::OnInterstitialResult(
SupervisedUserInterstitial::GetHTMLContents( SupervisedUserInterstitial::GetHTMLContents(
Profile::FromBrowserContext( Profile::FromBrowserContext(
navigation_handle()->GetWebContents()->GetBrowserContext()), navigation_handle()->GetWebContents()->GetBrowserContext()),
reason_); reason_, already_sent_request, is_main_frame);
CancelDeferredNavigation(content::NavigationThrottle::ThrottleCheckResult( CancelDeferredNavigation(content::NavigationThrottle::ThrottleCheckResult(
CANCEL, net::ERR_BLOCKED_BY_CLIENT, interstitial_html)); CANCEL, net::ERR_BLOCKED_BY_CLIENT, interstitial_html));
} }
......
...@@ -52,7 +52,9 @@ class SupervisedUserNavigationThrottle : public content::NavigationThrottle { ...@@ -52,7 +52,9 @@ class SupervisedUserNavigationThrottle : public content::NavigationThrottle {
supervised_user_error_page::FilteringBehaviorReason reason, supervised_user_error_page::FilteringBehaviorReason reason,
bool uncertain); bool uncertain);
void OnInterstitialResult(CallbackActions continue_request); void OnInterstitialResult(CallbackActions continue_request,
bool already_requested_permission,
bool is_main_frame);
const SupervisedUserURLFilter* url_filter_; const SupervisedUserURLFilter* url_filter_;
bool deferred_; bool deferred_;
......
...@@ -285,6 +285,7 @@ class SupervisedUserIframeFilterTest ...@@ -285,6 +285,7 @@ class SupervisedUserIframeFilterTest
std::vector<int> GetBlockedFrames(); std::vector<int> GetBlockedFrames();
const GURL& GetBlockedFrameURL(int frame_id); const GURL& GetBlockedFrameURL(int frame_id);
bool IsInterstitialBeingShownInFrame(int frame_id); bool IsInterstitialBeingShownInFrame(int frame_id);
bool IsAskPermissionButtonBeingShown(int frame_id);
void RequestPermissionFromFrame(int frame_id); void RequestPermissionFromFrame(int frame_id);
void WaitForNavigationFinished(int frame_id, const GURL& url); void WaitForNavigationFinished(int frame_id, const GURL& url);
...@@ -295,6 +296,9 @@ class SupervisedUserIframeFilterTest ...@@ -295,6 +296,9 @@ class SupervisedUserIframeFilterTest
RenderFrameTracker* tracker() { return tracker_.get(); } RenderFrameTracker* tracker() { return tracker_.get(); }
private: private:
bool RunCommandAndGetBooleanFromFrame(int frame_id,
const std::string& command);
std::unique_ptr<RenderFrameTracker> tracker_; std::unique_ptr<RenderFrameTracker> tracker_;
PermissionRequestCreatorMock* permission_creator_; PermissionRequestCreatorMock* permission_creator_;
...@@ -354,30 +358,20 @@ const GURL& SupervisedUserIframeFilterTest::GetBlockedFrameURL(int frame_id) { ...@@ -354,30 +358,20 @@ const GURL& SupervisedUserIframeFilterTest::GetBlockedFrameURL(int frame_id) {
bool SupervisedUserIframeFilterTest::IsInterstitialBeingShownInFrame( bool SupervisedUserIframeFilterTest::IsInterstitialBeingShownInFrame(
int frame_id) { int frame_id) {
// First check that SupervisedUserNavigationObserver believes that there is
// an error page in the frame hosted by |rfh|.
WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
auto* navigation_observer =
SupervisedUserNavigationObserver::FromWebContents(tab);
auto& interstitials = navigation_observer->interstitials_for_test();
if (!base::Contains(interstitials, frame_id))
return false;
// Then check that an error page has actually been loaded in the frame.
std::string command = std::string command =
"domAutomationController.send(" "domAutomationController.send("
"(document.getElementsByClassName('supervised-user-block') != null) " "(document.getElementsByClassName('supervised-user-block') != null) "
"? (true) : (false));"; "? (true) : (false));";
return RunCommandAndGetBooleanFromFrame(frame_id, command);
}
auto* render_frame_host = tracker()->GetHost(frame_id); bool SupervisedUserIframeFilterTest::IsAskPermissionButtonBeingShown(
DCHECK(render_frame_host->IsRenderFrameLive()); int frame_id) {
std::string command =
bool value = false; "domAutomationController.send("
auto target = content::ToRenderFrameHost(render_frame_host); "(document.getElementById('request-access-button').hidden"
EXPECT_TRUE(content::ExecuteScriptWithoutUserGestureAndExtractBool( "? (false) : (true)));";
target, command, &value)); return RunCommandAndGetBooleanFromFrame(frame_id, command);
return value;
} }
void SupervisedUserIframeFilterTest::RequestPermissionFromFrame(int frame_id) { void SupervisedUserIframeFilterTest::RequestPermissionFromFrame(int frame_id) {
...@@ -397,6 +391,29 @@ void SupervisedUserIframeFilterTest::WaitForNavigationFinished( ...@@ -397,6 +391,29 @@ void SupervisedUserIframeFilterTest::WaitForNavigationFinished(
waiter.Wait(); waiter.Wait();
} }
bool SupervisedUserIframeFilterTest::RunCommandAndGetBooleanFromFrame(
int frame_id,
const std::string& command) {
// First check that SupervisedUserNavigationObserver believes that there is
// an error page in the frame with frame tree node id |frame_id|.
WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
auto* navigation_observer =
SupervisedUserNavigationObserver::FromWebContents(tab);
auto& interstitials = navigation_observer->interstitials_for_test();
if (!base::Contains(interstitials, frame_id))
return false;
auto* render_frame_host = tracker()->GetHost(frame_id);
DCHECK(render_frame_host->IsRenderFrameLive());
bool value = false;
auto target = content::ToRenderFrameHost(render_frame_host);
EXPECT_TRUE(content::ExecuteScriptWithoutUserGestureAndExtractBool(
target, command, &value));
return value;
}
IN_PROC_BROWSER_TEST_F(SupervisedUserIframeFilterTest, BlockSubFrame) { IN_PROC_BROWSER_TEST_F(SupervisedUserIframeFilterTest, BlockSubFrame) {
BlockHost(kIframeHost2); BlockHost(kIframeHost2);
GURL allowed_url_with_iframes = embedded_test_server()->GetURL( GURL allowed_url_with_iframes = embedded_test_server()->GetURL(
...@@ -548,6 +565,64 @@ IN_PROC_BROWSER_TEST_F(SupervisedUserIframeFilterTest, ...@@ -548,6 +565,64 @@ IN_PROC_BROWSER_TEST_F(SupervisedUserIframeFilterTest,
EXPECT_EQ(kIframeHost1, GetBlockedFrameURL(blocked[0]).host()); EXPECT_EQ(kIframeHost1, GetBlockedFrameURL(blocked[0]).host());
} }
IN_PROC_BROWSER_TEST_F(SupervisedUserIframeFilterTest,
RememberAlreadyRequestedHosts) {
BlockHost(kExampleHost);
GURL blocked_url = embedded_test_server()->GetURL(
kExampleHost, "/supervised_user/with_frames.html");
ui_test_utils::NavigateToURL(browser(), blocked_url);
EXPECT_TRUE(IsInterstitialBeingShownInMainFrame(browser()));
auto blocked_frames = GetBlockedFrames();
EXPECT_EQ(blocked_frames.size(), 1u);
// Expect that request permission button is shown.
EXPECT_TRUE(IsAskPermissionButtonBeingShown(blocked_frames[0]));
// Delay approval/denial by parent.
permission_creator()->SetPermissionResult(true);
permission_creator()->DelayHandlingForNextRequests();
// Request permission.
RequestPermissionFromFrame(blocked_frames[0]);
// Navigate to another allowed url.
GURL allowed_url = embedded_test_server()->GetURL(
kExampleHost2, "/supervised_user/with_frames.html");
ui_test_utils::NavigateToURL(browser(), allowed_url);
EXPECT_FALSE(IsInterstitialBeingShownInMainFrame(browser()));
ui_test_utils::NavigateToURL(browser(), blocked_url);
EXPECT_TRUE(IsInterstitialBeingShownInMainFrame(browser()));
// Navigate back to the blocked url.
EXPECT_TRUE(IsInterstitialBeingShownInMainFrame(browser()));
// Error page is being shown, but "Ask Permission" button is not being shown.
EXPECT_FALSE(IsAskPermissionButtonBeingShown(blocked_frames[0]));
content::WebContents* active_contents =
browser()->tab_strip_model()->GetActiveWebContents();
SupervisedUserNavigationObserver* navigation_observer =
SupervisedUserNavigationObserver::FromWebContents(active_contents);
ASSERT_NE(navigation_observer, nullptr);
EXPECT_TRUE(base::Contains(navigation_observer->requested_hosts_for_test(),
kExampleHost));
NavigationFinishedWaiter waiter(
active_contents, active_contents->GetMainFrame()->GetFrameTreeNodeId(),
blocked_url);
permission_creator()->HandleDelayedRequests();
waiter.Wait();
EXPECT_FALSE(base::Contains(navigation_observer->requested_hosts_for_test(),
kExampleHost));
EXPECT_FALSE(IsInterstitialBeingShownInMainFrame(browser()));
}
class SupervisedUserNavigationThrottleNotSupervisedTest class SupervisedUserNavigationThrottleNotSupervisedTest
: public SupervisedUserNavigationThrottleTest { : public SupervisedUserNavigationThrottleTest {
protected: protected:
......
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