Skip to content

Commit

Permalink
Added api to allow scripts once to be loaded in a page
Browse files Browse the repository at this point in the history
  • Loading branch information
spylogsster committed Feb 17, 2023
1 parent 67d73b3 commit 344cbb4
Show file tree
Hide file tree
Showing 14 changed files with 267 additions and 27 deletions.
37 changes: 33 additions & 4 deletions browser/brave_shields/brave_shields_web_contents_observer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,44 @@ void BraveShieldsWebContentsObserver::DispatchBlockedEventForWebContents(
return;
shields_data_ctrlr->HandleItemBlocked(block_type, subresource);
}
// static
void BraveShieldsWebContentsObserver::DispatchAllowedOnceEventForWebContents(
const std::string& block_type,
const std::string& subresource,
WebContents* web_contents) {
if (!web_contents) {
return;
}
auto* shields_data_ctrlr =
brave_shields::BraveShieldsDataController::FromWebContents(web_contents);
// |shields_data_ctrlr| can be null if the |web_contents| is generated in
// component layer - We don't attach any tab helpers in this case.
if (!shields_data_ctrlr) {
return;
}
shields_data_ctrlr->HandleItemAllowedOnce(block_type, subresource);
}
#endif

void BraveShieldsWebContentsObserver::OnJavaScriptBlocked(
void BraveShieldsWebContentsObserver::OnJavaScriptAllowedOnce(
const std::u16string& details) {
#if !BUILDFLAG(IS_ANDROID)
WebContents* web_contents =
WebContents::FromRenderFrameHost(receivers_.GetCurrentTargetFrame());
if (!web_contents)
return;
DispatchAllowedOnceEventForWebContents(
brave_shields::kJavaScript, base::UTF16ToUTF8(details), web_contents);
#endif
}

void BraveShieldsWebContentsObserver::OnJavaScriptBlocked(
const std::u16string& details) {
WebContents* web_contents =
WebContents::FromRenderFrameHost(receivers_.GetCurrentTargetFrame());
if (!web_contents) {
return;
}
DispatchBlockedEventForWebContents(brave_shields::kJavaScript,
base::UTF16ToUTF8(details), web_contents);
}
Expand Down Expand Up @@ -227,9 +256,9 @@ void BraveShieldsWebContentsObserver::ReadyToCommitNavigation(
}

void BraveShieldsWebContentsObserver::AllowScriptsOnce(
const std::vector<std::string>& origins,
WebContents* contents) {
allowed_script_origins_ = std::move(origins);
const std::vector<std::string>& origins) {
allowed_script_origins_.insert(std::end(allowed_script_origins_),
std::begin(origins), std::end(origins));
}

// static
Expand Down
8 changes: 6 additions & 2 deletions browser/brave_shields/brave_shields_web_contents_observer.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,15 @@ class BraveShieldsWebContentsObserver
const std::string& block_type,
const std::string& subresource,
content::WebContents* web_contents);
static void DispatchAllowedOnceEventForWebContents(
const std::string& block_type,
const std::string& subresource,
content::WebContents* web_contents);
static void DispatchBlockedEvent(const GURL& request_url,
int frame_tree_node_id,
const std::string& block_type);
static GURL GetTabURLFromRenderFrameInfo(int render_frame_tree_node_id);
void AllowScriptsOnce(const std::vector<std::string>& origins,
content::WebContents* web_contents);
void AllowScriptsOnce(const std::vector<std::string>& origins);
bool IsBlockedSubresource(const std::string& subresource);
void AddBlockedSubresource(const std::string& subresource);

Expand All @@ -68,6 +71,7 @@ class BraveShieldsWebContentsObserver

// brave_shields::mojom::BraveShieldsHost.
void OnJavaScriptBlocked(const std::u16string& details) override;
void OnJavaScriptAllowedOnce(const std::u16string& details) override;

private:
friend class content::WebContentsUserData<BraveShieldsWebContentsObserver>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "base/memory/raw_ptr.h"
#include "base/path_service.h"
#include "brave/browser/brave_shields/brave_shields_web_contents_observer.h"
#include "brave/browser/ui/brave_shields_data_controller.h"
#include "brave/components/constants/brave_paths.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/profiles/profile.h"
Expand Down Expand Up @@ -79,6 +80,24 @@ class BraveShieldsWebContentsObserverBrowserTest : public InProcessBrowserTest {
brave_shields_web_contents_observer_);
}

std::vector<GURL> GetBlockedJsList() {
return brave_shields::BraveShieldsDataController::FromWebContents(
GetWebContents())
->GetBlockedJsList();
}

std::vector<GURL> GetAllowedJsList() {
return brave_shields::BraveShieldsDataController::FromWebContents(
GetWebContents())
->GetAllowedJsList();
}

void ClearAllResourcesList() {
return brave_shields::BraveShieldsDataController::FromWebContents(
GetWebContents())
->ClearAllResourcesList();
}

void TearDownOnMainThread() override {
BraveShieldsWebContentsObserver::SetReceiverImplForTesting(nullptr);
}
Expand Down Expand Up @@ -114,7 +133,7 @@ IN_PROC_BROWSER_TEST_F(BraveShieldsWebContentsObserverBrowserTest,
browser(), embedded_test_server()->GetURL("a.com", "/load_js.html")));
EXPECT_TRUE(WaitForLoadStop(GetWebContents()));
EXPECT_EQ(brave_shields_web_contents_observer()->block_javascript_count(), 0);

EXPECT_EQ(GetBlockedJsList().size(), 0u);
// Enable JavaScript blocking globally now.
content_settings()->SetContentSettingCustomScope(
ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(),
Expand All @@ -128,6 +147,7 @@ IN_PROC_BROWSER_TEST_F(BraveShieldsWebContentsObserverBrowserTest,
GetWebContents()->GetController().Reload(content::ReloadType::NORMAL, true);
EXPECT_TRUE(WaitForLoadStop(GetWebContents()));
EXPECT_GT(brave_shields_web_contents_observer()->block_javascript_count(), 0);
EXPECT_EQ(GetBlockedJsList().size(), 3u);

// Disable JavaScript blocking again now.
content_settings()->SetContentSettingCustomScope(
Expand All @@ -148,6 +168,7 @@ IN_PROC_BROWSER_TEST_F(BraveShieldsWebContentsObserverBrowserTest,
GetWebContents()->GetController().Reload(content::ReloadType::NORMAL, true);
EXPECT_TRUE(WaitForLoadStop(GetWebContents()));
EXPECT_EQ(brave_shields_web_contents_observer()->block_javascript_count(), 0);
EXPECT_EQ(GetBlockedJsList().size(), 0u);
}

IN_PROC_BROWSER_TEST_F(BraveShieldsWebContentsObserverBrowserTest,
Expand All @@ -162,6 +183,81 @@ IN_PROC_BROWSER_TEST_F(BraveShieldsWebContentsObserverBrowserTest,
browser(), embedded_test_server()->GetURL("a.com", "/embedded_js.html")));
EXPECT_TRUE(WaitForLoadStop(GetWebContents()));
EXPECT_GT(brave_shields_web_contents_observer()->block_javascript_count(), 0);
EXPECT_EQ(GetBlockedJsList().size(), 1u);
}

IN_PROC_BROWSER_TEST_F(BraveShieldsWebContentsObserverBrowserTest,
JavaScriptAllowedEvents) {
const GURL& url = GURL("a.com");

// Start with JavaScript blocking initially disabled.
ContentSetting block_javascript_setting =
content_settings()->GetContentSetting(url, url,
ContentSettingsType::JAVASCRIPT);
EXPECT_EQ(CONTENT_SETTING_ALLOW, block_javascript_setting);

// Load a simple HTML that attempts to load some JavaScript without blocking.
EXPECT_TRUE(ui_test_utils::NavigateToURL(
browser(), embedded_test_server()->GetURL("a.com", "/load_js.html")));
EXPECT_TRUE(WaitForLoadStop(GetWebContents()));
EXPECT_EQ(brave_shields_web_contents_observer()->block_javascript_count(), 0);

// Enable JavaScript blocking globally now.
content_settings()->SetContentSettingCustomScope(
ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(),
ContentSettingsType::JAVASCRIPT, CONTENT_SETTING_BLOCK);
block_javascript_setting = content_settings()->GetContentSetting(
url, url, ContentSettingsType::JAVASCRIPT);
EXPECT_EQ(CONTENT_SETTING_BLOCK, block_javascript_setting);

// Reload the test page now that JavaScript has been blocked.
brave_shields_web_contents_observer()->Reset();
GetWebContents()->GetController().Reload(content::ReloadType::NORMAL, true);
EXPECT_TRUE(WaitForLoadStop(GetWebContents()));
EXPECT_GT(brave_shields_web_contents_observer()->block_javascript_count(), 0);
auto blocked_list = GetBlockedJsList();
EXPECT_EQ(blocked_list.size(), 3u);

// Allow One Script
brave_shields_web_contents_observer()->AllowScriptsOnce(
std::vector<std::string>({blocked_list.back().spec()}));
ClearAllResourcesList();
GetWebContents()->GetController().Reload(content::ReloadType::NORMAL, true);
EXPECT_TRUE(WaitForLoadStop(GetWebContents()));
EXPECT_EQ(GetBlockedJsList().size(), 2u);
EXPECT_EQ(GetAllowedJsList().size(), 1u);

blocked_list.pop_back();
EXPECT_EQ(blocked_list.size(), 2u);

// Allow Second Script
brave_shields_web_contents_observer()->AllowScriptsOnce(
std::vector<std::string>({blocked_list.back().spec()}));
ClearAllResourcesList();
GetWebContents()->GetController().Reload(content::ReloadType::NORMAL, true);
EXPECT_TRUE(WaitForLoadStop(GetWebContents()));
EXPECT_EQ(GetBlockedJsList().size(), 1u);
EXPECT_EQ(GetAllowedJsList().size(), 2u);

// Disable JavaScript blocking again now.
content_settings()->SetContentSettingCustomScope(
ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(),
ContentSettingsType::JAVASCRIPT, CONTENT_SETTING_ALLOW);
block_javascript_setting = content_settings()->GetContentSetting(
url, url, ContentSettingsType::JAVASCRIPT);
EXPECT_EQ(CONTENT_SETTING_ALLOW, block_javascript_setting);

// Reload the test page now that JavaScript has been allowed again.
// Do it twice, because first reload will still trigger blocked events as
// renderer caches AllowScript results in
// ContentSettingsAgentImpl::cached_script_permissions_.
GetWebContents()->GetController().Reload(content::ReloadType::NORMAL, true);
EXPECT_TRUE(WaitForLoadStop(GetWebContents()));

brave_shields_web_contents_observer()->Reset();
GetWebContents()->GetController().Reload(content::ReloadType::NORMAL, true);
EXPECT_TRUE(WaitForLoadStop(GetWebContents()));
EXPECT_EQ(brave_shields_web_contents_observer()->block_javascript_count(), 0);
}

} // namespace brave_shields
36 changes: 35 additions & 1 deletion browser/ui/brave_shields_data_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <string>

#include "brave/browser/brave_shields/brave_shields_web_contents_observer.h"
#include "brave/components/brave_shields/browser/brave_shields_util.h"
#include "brave/components/brave_shields/common/brave_shield_constants.h"
#include "chrome/browser/browser_process.h"
Expand Down Expand Up @@ -91,6 +92,7 @@ void BraveShieldsDataController::ClearAllResourcesList() {
resource_list_http_redirects_.clear();
resource_list_blocked_js_.clear();
resource_list_blocked_fingerprints_.clear();
resource_list_allowed_once_js_.clear();

for (Observer& obs : observer_list_)
obs.OnResourcesChanged();
Expand Down Expand Up @@ -129,10 +131,15 @@ std::vector<GURL> BraveShieldsDataController::GetHttpRedirectsList() {
return http_redirects;
}

std::vector<GURL> BraveShieldsDataController::GetJsList() {
std::vector<GURL> BraveShieldsDataController::GetBlockedJsList() {
std::vector<GURL> js_list(resource_list_blocked_js_.begin(),
resource_list_blocked_js_.end());
return js_list;
}

std::vector<GURL> BraveShieldsDataController::GetAllowedJsList() {
std::vector<GURL> js_list(resource_list_allowed_once_js_.begin(),
resource_list_allowed_once_js_.end());
return js_list;
}

Expand Down Expand Up @@ -376,6 +383,17 @@ void BraveShieldsDataController::SetIsHTTPSEverywhereEnabled(bool is_enabled) {
ReloadWebContents();
}

void BraveShieldsDataController::AllowScriptsOnce(
const std::vector<std::string>& origins) {
BraveShieldsWebContentsObserver* observer =
BraveShieldsWebContentsObserver::FromWebContents(web_contents());
if (observer) {
observer->AllowScriptsOnce(origins);
}

ReloadWebContents();
}

bool BraveShieldsDataController::IsBraveShieldsManaged() {
PrefService* profile_prefs =
Profile::FromBrowserContext(web_contents()->GetBrowserContext())
Expand Down Expand Up @@ -405,6 +423,22 @@ void BraveShieldsDataController::HandleItemBlocked(
obs.OnResourcesChanged();
}

void BraveShieldsDataController::HandleItemAllowedOnce(
const std::string& allowed_once_type,
const std::string& subresource) {
auto subres = GURL(subresource);
if (allowed_once_type == kJavaScript) {
if (resource_list_allowed_once_js_.contains(subres)) {
return;
}
resource_list_allowed_once_js_.insert(GURL(subresource));
}

for (Observer& obs : observer_list_) {
obs.OnResourcesChanged();
}
}

WEB_CONTENTS_USER_DATA_KEY_IMPL(BraveShieldsDataController);

} // namespace brave_shields
7 changes: 6 additions & 1 deletion browser/ui/brave_shields_data_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,14 @@ class BraveShieldsDataController

void HandleItemBlocked(const std::string& block_type,
const std::string& subresource);
void HandleItemAllowedOnce(const std::string& allowed_once_type,
const std::string& subresource);
void ClearAllResourcesList();
int GetTotalBlockedCount();
std::vector<GURL> GetBlockedAdsList();
std::vector<GURL> GetHttpRedirectsList();
std::vector<GURL> GetJsList();
std::vector<GURL> GetBlockedJsList();
std::vector<GURL> GetAllowedJsList();
std::vector<GURL> GetFingerprintsList();
bool GetBraveShieldsEnabled();
void SetBraveShieldsEnabled(bool is_enabled);
Expand All @@ -74,6 +77,7 @@ class BraveShieldsDataController
void SetHttpsUpgradeMode(HttpsUpgradeMode mode);
void SetIsNoScriptEnabled(bool is_enabled);
void SetIsHTTPSEverywhereEnabled(bool is_enabled);
void AllowScriptsOnce(const std::vector<std::string>& origins);

void AddObserver(Observer* obs);
void RemoveObserver(Observer* obs);
Expand Down Expand Up @@ -108,6 +112,7 @@ class BraveShieldsDataController
std::set<GURL> resource_list_blocked_ads_;
std::set<GURL> resource_list_http_redirects_;
std::set<GURL> resource_list_blocked_js_;
std::set<GURL> resource_list_allowed_once_js_;
std::set<GURL> resource_list_blocked_fingerprints_;
base::ScopedObservation<HostContentSettingsMap, content_settings::Observer>
observation_{this};
Expand Down
23 changes: 23 additions & 0 deletions browser/ui/brave_shields_data_controller_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -401,3 +401,26 @@ TEST_F(BraveShieldsDataControllerTest, SetBraveShieldsEnabledAsDefaultValue) {
->GetDict("profile.content_settings.exceptions.braveShields")
.empty());
}

TEST_F(BraveShieldsDataControllerTest, AllowedOnceScripts) {
EXPECT_EQ(GetShieldsDataController()->GetAllowedJsList().size(), 0u);
GetShieldsDataController()->HandleItemAllowedOnce(
brave_shields::kJavaScript, "https://url1.com/script.js");
EXPECT_EQ(GetShieldsDataController()->GetAllowedJsList().size(), 1u);
GetShieldsDataController()->HandleItemAllowedOnce(
brave_shields::kJavaScript, "https://url2.com/script.js");
EXPECT_EQ(GetShieldsDataController()->GetAllowedJsList().size(), 2u);
GetShieldsDataController()->HandleItemAllowedOnce(
brave_shields::kJavaScript, "https://url3.com/script.js");
EXPECT_EQ(GetShieldsDataController()->GetAllowedJsList().size(), 3u);

// Making sure we exclude duplicates
GetShieldsDataController()->HandleItemAllowedOnce(
brave_shields::kJavaScript, "https://url2.com/script.js");
GetShieldsDataController()->HandleItemAllowedOnce(
brave_shields::kJavaScript, "https://url3.com/script.js");
EXPECT_EQ(GetShieldsDataController()->GetAllowedJsList().size(), 3u);

GetShieldsDataController()->ClearAllResourcesList();
EXPECT_EQ(GetShieldsDataController()->GetAllowedJsList().size(), 0u);
}
12 changes: 11 additions & 1 deletion browser/ui/webui/brave_shields/shields_panel_data_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,15 @@ void ShieldsPanelDataHandler::SetIsNoScriptsEnabled(bool is_enabled) {
active_shields_data_controller_->SetIsNoScriptEnabled(is_enabled);
}

void ShieldsPanelDataHandler::AllowScriptsOnce(
const std::vector<std::string>& origins) {
if (!active_shields_data_controller_) {
return;
}

active_shields_data_controller_->AllowScriptsOnce(origins);
}

void ShieldsPanelDataHandler::SetHTTPSEverywhereEnabled(bool is_enabled) {
if (!active_shields_data_controller_)
return;
Expand Down Expand Up @@ -160,7 +169,8 @@ void ShieldsPanelDataHandler::UpdateSiteBlockInfo() {
active_shields_data_controller_->GetTotalBlockedCount();
site_block_info_.ads_list =
active_shields_data_controller_->GetBlockedAdsList();
site_block_info_.js_list = active_shields_data_controller_->GetJsList();
site_block_info_.js_list =
active_shields_data_controller_->GetBlockedJsList();
site_block_info_.fingerprints_list =
active_shields_data_controller_->GetFingerprintsList();
site_block_info_.http_redirects_list =
Expand Down
Loading

0 comments on commit 344cbb4

Please sign in to comment.