| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <memory> |
| |
| #include "base/command_line.h" |
| #include "base/files/file_path.h" |
| #include "base/path_service.h" |
| #include "base/run_loop.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/values.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/profiles/profile_key.h" |
| #include "chrome/browser/supervised_user/logged_in_user_mixin.h" |
| #include "chrome/browser/supervised_user/navigation_finished_waiter.h" |
| #include "chrome/browser/supervised_user/permission_request_creator_mock.h" |
| #include "chrome/browser/supervised_user/supervised_user_constants.h" |
| #include "chrome/browser/supervised_user/supervised_user_features.h" |
| #include "chrome/browser/supervised_user/supervised_user_interstitial.h" |
| #include "chrome/browser/supervised_user/supervised_user_navigation_observer.h" |
| #include "chrome/browser/supervised_user/supervised_user_service.h" |
| #include "chrome/browser/supervised_user/supervised_user_service_factory.h" |
| #include "chrome/browser/supervised_user/supervised_user_settings_service.h" |
| #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h" |
| #include "chrome/browser/supervised_user/supervised_user_url_filter.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/common/webui_url_constants.h" |
| #include "chrome/test/base/ui_test_utils.h" |
| #include "content/public/browser/navigation_controller.h" |
| #include "content/public/browser/navigation_entry.h" |
| #include "content/public/browser/navigation_handle.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/common/content_paths.h" |
| #include "content/public/common/page_type.h" |
| #include "content/public/test/browser_test.h" |
| #include "content/public/test/browser_test_utils.h" |
| #include "content/public/test/test_navigation_observer.h" |
| #include "net/dns/mock_host_resolver.h" |
| #include "net/test/embedded_test_server/embedded_test_server.h" |
| |
| using content::NavigationController; |
| using content::WebContents; |
| |
| namespace { |
| |
| static const char* kExampleHost = "www.example.com"; |
| static const char* kExampleHost2 = "www.example2.com"; |
| static const char* kIframeHost1 = "www.iframe1.com"; |
| static const char* kIframeHost2 = "www.iframe2.com"; |
| |
| // Class to keep track of iframes created and destroyed. |
| class RenderFrameTracker : public content::WebContentsObserver { |
| public: |
| explicit RenderFrameTracker(content::WebContents* web_contents) |
| : content::WebContentsObserver(web_contents) {} |
| ~RenderFrameTracker() override = default; |
| |
| // content::WebContentsObserver: |
| void RenderFrameHostChanged(content::RenderFrameHost* old_host, |
| content::RenderFrameHost* new_host) override; |
| void FrameDeleted(content::RenderFrameHost* host) override; |
| |
| content::RenderFrameHost* GetHost(int frame_id) { |
| if (!base::Contains(render_frame_hosts_, frame_id)) |
| return nullptr; |
| return render_frame_hosts_[frame_id]; |
| } |
| |
| private: |
| std::map<int, content::RenderFrameHost*> render_frame_hosts_; |
| }; |
| |
| void RenderFrameTracker::RenderFrameHostChanged( |
| content::RenderFrameHost* old_host, |
| content::RenderFrameHost* new_host) { |
| render_frame_hosts_[new_host->GetFrameTreeNodeId()] = new_host; |
| } |
| |
| void RenderFrameTracker::FrameDeleted(content::RenderFrameHost* host) { |
| if (!base::Contains(render_frame_hosts_, host->GetFrameTreeNodeId())) |
| return; |
| |
| render_frame_hosts_.erase(host->GetFrameTreeNodeId()); |
| } |
| |
| class InnerWebContentsAttachedWaiter : public content::WebContentsObserver { |
| public: |
| explicit InnerWebContentsAttachedWaiter(content::WebContents* contents) |
| : content::WebContentsObserver(contents) {} |
| InnerWebContentsAttachedWaiter(const InnerWebContentsAttachedWaiter&) = |
| delete; |
| InnerWebContentsAttachedWaiter& operator=( |
| const InnerWebContentsAttachedWaiter&) = delete; |
| ~InnerWebContentsAttachedWaiter() override = default; |
| |
| // content::WebContentsObserver: |
| void InnerWebContentsAttached(content::WebContents* inner_web_contents, |
| content::RenderFrameHost* render_frame_host, |
| bool is_full_page) override; |
| |
| void WaitForInnerWebContentsAttached(); |
| |
| private: |
| base::RunLoop run_loop_{base::RunLoop::Type::kNestableTasksAllowed}; |
| }; |
| |
| void InnerWebContentsAttachedWaiter::InnerWebContentsAttached( |
| content::WebContents* inner_web_contents, |
| content::RenderFrameHost* render_frame_host, |
| bool is_full_page) { |
| run_loop_.Quit(); |
| } |
| |
| void InnerWebContentsAttachedWaiter::WaitForInnerWebContentsAttached() { |
| if (web_contents()->GetInnerWebContents().size() > 0u) |
| return; |
| run_loop_.Run(); |
| } |
| |
| } // namespace |
| |
| class SupervisedUserNavigationThrottleTest |
| : public MixinBasedInProcessBrowserTest { |
| protected: |
| SupervisedUserNavigationThrottleTest() = default; |
| ~SupervisedUserNavigationThrottleTest() override = default; |
| |
| void SetUp() override; |
| void SetUpOnMainThread() override; |
| |
| void BlockHost(const std::string& host) { |
| SetManualFilterForHost(host, /* allowlist */ false); |
| } |
| |
| void AllowlistHost(const std::string& host) { |
| SetManualFilterForHost(host, /* allowlist */ true); |
| } |
| |
| bool IsInterstitialBeingShownInMainFrame(Browser* browser); |
| |
| virtual chromeos::LoggedInUserMixin::LogInType GetLogInType() { |
| return chromeos::LoggedInUserMixin::LogInType::kChild; |
| } |
| |
| private: |
| void SetManualFilterForHost(const std::string& host, bool allowlist) { |
| Profile* profile = browser()->profile(); |
| SupervisedUserSettingsService* settings_service = |
| SupervisedUserSettingsServiceFactory::GetForKey( |
| profile->GetProfileKey()); |
| |
| const base::DictionaryValue* local_settings = |
| settings_service->LocalSettingsForTest(); |
| std::unique_ptr<base::DictionaryValue> dict_to_insert; |
| |
| if (local_settings->HasKey( |
| supervised_users::kContentPackManualBehaviorHosts)) { |
| const base::DictionaryValue* dict_value; |
| |
| local_settings->GetDictionary( |
| supervised_users::kContentPackManualBehaviorHosts, &dict_value); |
| |
| std::unique_ptr<base::Value> clone = |
| std::make_unique<base::Value>(dict_value->Clone()); |
| |
| dict_to_insert = base::DictionaryValue::From(std::move(clone)); |
| } else { |
| dict_to_insert = std::make_unique<base::DictionaryValue>(); |
| } |
| |
| dict_to_insert->SetKey(host, base::Value(allowlist)); |
| settings_service->SetLocalSetting( |
| supervised_users::kContentPackManualBehaviorHosts, |
| std::move(dict_to_insert)); |
| } |
| |
| std::unique_ptr<chromeos::LoggedInUserMixin> logged_in_user_mixin_; |
| }; |
| |
| bool SupervisedUserNavigationThrottleTest::IsInterstitialBeingShownInMainFrame( |
| Browser* browser) { |
| WebContents* tab = browser->tab_strip_model()->GetActiveWebContents(); |
| base::string16 title; |
| ui_test_utils::GetCurrentTabTitle(browser, &title); |
| return tab->GetController().GetLastCommittedEntry()->GetPageType() == |
| content::PAGE_TYPE_ERROR && |
| title == base::ASCIIToUTF16("Site blocked"); |
| } |
| |
| void SupervisedUserNavigationThrottleTest::SetUp() { |
| // Polymorphically initiate logged_in_user_mixin_. |
| logged_in_user_mixin_ = std::make_unique<chromeos::LoggedInUserMixin>( |
| &mixin_host_, GetLogInType(), embedded_test_server(), this); |
| MixinBasedInProcessBrowserTest::SetUp(); |
| } |
| |
| void SupervisedUserNavigationThrottleTest::SetUpOnMainThread() { |
| MixinBasedInProcessBrowserTest::SetUpOnMainThread(); |
| // Resolve everything to localhost. |
| host_resolver()->AddIPLiteralRule("*", "127.0.0.1", "localhost"); |
| |
| ASSERT_TRUE(embedded_test_server()->Started()); |
| |
| logged_in_user_mixin_->LogInUser(); |
| } |
| |
| // Tests that navigating to a blocked page simply fails if there is no |
| // SupervisedUserNavigationObserver. |
| IN_PROC_BROWSER_TEST_F(SupervisedUserNavigationThrottleTest, |
| NoNavigationObserverBlock) { |
| Profile* profile = browser()->profile(); |
| SupervisedUserSettingsService* supervised_user_settings_service = |
| SupervisedUserSettingsServiceFactory::GetForKey(profile->GetProfileKey()); |
| supervised_user_settings_service->SetLocalSetting( |
| supervised_users::kContentPackDefaultFilteringBehavior, |
| std::unique_ptr<base::Value>( |
| new base::Value(SupervisedUserURLFilter::BLOCK))); |
| |
| std::unique_ptr<WebContents> web_contents( |
| WebContents::Create(WebContents::CreateParams(profile))); |
| NavigationController& controller = web_contents->GetController(); |
| content::TestNavigationObserver observer(web_contents.get()); |
| controller.LoadURL(GURL("http://www.example.com"), content::Referrer(), |
| ui::PAGE_TRANSITION_TYPED, std::string()); |
| observer.Wait(); |
| content::NavigationEntry* entry = controller.GetVisibleEntry(); |
| ASSERT_TRUE(entry); |
| EXPECT_EQ(content::PAGE_TYPE_NORMAL, entry->GetPageType()); |
| EXPECT_FALSE(observer.last_navigation_succeeded()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SupervisedUserNavigationThrottleTest, |
| BlockMainFrameWithInterstitial) { |
| BlockHost(kExampleHost2); |
| |
| GURL allowed_url = embedded_test_server()->GetURL( |
| kExampleHost, "/supervised_user/simple.html"); |
| ui_test_utils::NavigateToURL(browser(), allowed_url); |
| EXPECT_FALSE(IsInterstitialBeingShownInMainFrame(browser())); |
| |
| GURL blocked_url = embedded_test_server()->GetURL( |
| kExampleHost2, "/supervised_user/simple.html"); |
| ui_test_utils::NavigateToURL(browser(), blocked_url); |
| EXPECT_TRUE(IsInterstitialBeingShownInMainFrame(browser())); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SupervisedUserNavigationThrottleTest, |
| DontBlockSubFrame) { |
| BlockHost(kExampleHost2); |
| BlockHost(kIframeHost2); |
| |
| WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); |
| |
| GURL allowed_url_with_iframes = embedded_test_server()->GetURL( |
| kExampleHost, "/supervised_user/with_iframes.html"); |
| ui_test_utils::NavigateToURL(browser(), allowed_url_with_iframes); |
| EXPECT_FALSE(IsInterstitialBeingShownInMainFrame(browser())); |
| |
| // Both iframes (from allowed host iframe1.com as well as from blocked host |
| // iframe2.com) should be loaded normally, since we don't filter iframes |
| // (yet) - see crbug.com/651115. |
| bool loaded1 = false; |
| ASSERT_TRUE(content::ExecuteScriptAndExtractBool(tab, "loaded1()", &loaded1)); |
| EXPECT_TRUE(loaded1); |
| bool loaded2 = false; |
| ASSERT_TRUE(content::ExecuteScriptAndExtractBool(tab, "loaded2()", &loaded2)); |
| EXPECT_TRUE(loaded2); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SupervisedUserNavigationThrottleTest, |
| AllowEDUCoexistenceInnerWebContents) { |
| BlockHost(kExampleHost2); |
| GURL manually_blocked_url = embedded_test_server()->GetURL( |
| kExampleHost2, "/supervised_user/with_iframes.html"); |
| |
| ui_test_utils::NavigateToURL(browser(), |
| GURL(chrome::kChromeUIEDUCoexistenceLoginURL)); |
| // Get the top level WebContents. |
| content::WebContents* contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| EXPECT_EQ(contents->GetURL(), GURL(chrome::kChromeUIEDUCoexistenceLoginURL)); |
| |
| InnerWebContentsAttachedWaiter web_contents_attached_waiter( |
| browser()->tab_strip_model()->GetActiveWebContents()); |
| web_contents_attached_waiter.WaitForInnerWebContentsAttached(); |
| |
| // Get the inner WebContents. |
| std::vector<content::WebContents*> inner_web_contents = |
| contents->GetInnerWebContents(); |
| |
| // There is only one inner web content in EDUCoexistence flow. |
| EXPECT_EQ(inner_web_contents.size(), 1u); |
| |
| content::WebContents* webview_element = inner_web_contents[0]; |
| NavigationFinishedWaiter waiter(webview_element, manually_blocked_url); |
| webview_element->GetController().LoadURLWithParams( |
| NavigationController::LoadURLParams(manually_blocked_url)); |
| waiter.Wait(); |
| |
| // Make sure that there is no error page in the inner web content. |
| EXPECT_NE( |
| webview_element->GetController().GetLastCommittedEntry()->GetPageType(), |
| content::PAGE_TYPE_ERROR); |
| } |
| |
| class SupervisedUserIframeFilterTest |
| : public SupervisedUserNavigationThrottleTest { |
| protected: |
| SupervisedUserIframeFilterTest() = default; |
| ~SupervisedUserIframeFilterTest() override = default; |
| |
| void SetUp() override; |
| void SetUpOnMainThread() override; |
| void TearDownOnMainThread() override; |
| |
| std::vector<int> GetBlockedFrames(); |
| const GURL& GetBlockedFrameURL(int frame_id); |
| bool IsInterstitialBeingShownInFrame(int frame_id); |
| bool IsAskPermissionButtonBeingShown(int frame_id); |
| void RequestPermissionFromFrame(int frame_id); |
| void WaitForNavigationFinished(int frame_id, const GURL& url); |
| |
| PermissionRequestCreatorMock* permission_creator() { |
| return permission_creator_; |
| } |
| |
| RenderFrameTracker* tracker() { return tracker_.get(); } |
| |
| private: |
| bool RunCommandAndGetBooleanFromFrame(int frame_id, |
| const std::string& command); |
| |
| std::unique_ptr<RenderFrameTracker> tracker_; |
| PermissionRequestCreatorMock* permission_creator_; |
| |
| base::test::ScopedFeatureList scoped_feature_list_; |
| }; |
| |
| void SupervisedUserIframeFilterTest::SetUp() { |
| scoped_feature_list_.InitAndEnableFeature( |
| supervised_users::kSupervisedUserIframeFilter); |
| SupervisedUserNavigationThrottleTest::SetUp(); |
| } |
| |
| void SupervisedUserIframeFilterTest::SetUpOnMainThread() { |
| SupervisedUserNavigationThrottleTest::SetUpOnMainThread(); |
| |
| SupervisedUserService* service = |
| SupervisedUserServiceFactory::GetForProfile(browser()->profile()); |
| std::unique_ptr<PermissionRequestCreator> creator = |
| std::make_unique<PermissionRequestCreatorMock>(browser()->profile()); |
| permission_creator_ = |
| static_cast<PermissionRequestCreatorMock*>(creator.get()); |
| permission_creator_->SetEnabled(); |
| service->SetPrimaryPermissionCreatorForTest(std::move(creator)); |
| |
| WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); |
| tracker_ = std::make_unique<RenderFrameTracker>(tab); |
| } |
| |
| void SupervisedUserIframeFilterTest::TearDownOnMainThread() { |
| tracker_.reset(); |
| SupervisedUserNavigationThrottleTest::TearDownOnMainThread(); |
| } |
| |
| std::vector<int> SupervisedUserIframeFilterTest::GetBlockedFrames() { |
| WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); |
| auto* navigation_observer = |
| SupervisedUserNavigationObserver::FromWebContents(tab); |
| const auto& interstitials = navigation_observer->interstitials_for_test(); |
| |
| std::vector<int> blocked_frames; |
| blocked_frames.reserve(interstitials.size()); |
| |
| for (const auto& elem : interstitials) |
| blocked_frames.push_back(elem.first); |
| |
| return blocked_frames; |
| } |
| |
| const GURL& SupervisedUserIframeFilterTest::GetBlockedFrameURL(int frame_id) { |
| WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); |
| auto* navigation_observer = |
| SupervisedUserNavigationObserver::FromWebContents(tab); |
| const auto& interstitials = navigation_observer->interstitials_for_test(); |
| DCHECK(base::Contains(interstitials, frame_id)); |
| return interstitials.at(frame_id)->url(); |
| } |
| |
| bool SupervisedUserIframeFilterTest::IsInterstitialBeingShownInFrame( |
| int frame_id) { |
| std::string command = |
| "domAutomationController.send(" |
| "(document.getElementsByClassName('supervised-user-block') != null) " |
| "? (true) : (false));"; |
| return RunCommandAndGetBooleanFromFrame(frame_id, command); |
| } |
| |
| bool SupervisedUserIframeFilterTest::IsAskPermissionButtonBeingShown( |
| int frame_id) { |
| std::string command = |
| "domAutomationController.send(" |
| "(document.getElementById('request-access-button').hidden" |
| "? (false) : (true)));"; |
| return RunCommandAndGetBooleanFromFrame(frame_id, command); |
| } |
| |
| void SupervisedUserIframeFilterTest::RequestPermissionFromFrame(int frame_id) { |
| auto* render_frame_host = tracker()->GetHost(frame_id); |
| DCHECK(render_frame_host); |
| DCHECK(render_frame_host->IsRenderFrameLive()); |
| std::string command = "sendCommand(\'request\')"; |
| ASSERT_TRUE(content::ExecuteScript( |
| content::ToRenderFrameHost(render_frame_host), command)); |
| } |
| |
| void SupervisedUserIframeFilterTest::WaitForNavigationFinished( |
| int frame_id, |
| const GURL& url) { |
| WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); |
| NavigationFinishedWaiter waiter(tab, frame_id, url); |
| 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) { |
| BlockHost(kIframeHost2); |
| GURL allowed_url_with_iframes = embedded_test_server()->GetURL( |
| kExampleHost, "/supervised_user/with_iframes.html"); |
| ui_test_utils::NavigateToURL(browser(), allowed_url_with_iframes); |
| EXPECT_FALSE(IsInterstitialBeingShownInMainFrame(browser())); |
| |
| // The first iframe's source is |kIframeHost1| and it is not blocked. It will |
| // successfully load. |
| auto blocked = GetBlockedFrames(); |
| EXPECT_EQ(blocked.size(), 1u); |
| |
| int blocked_frame_id = blocked[0]; |
| |
| EXPECT_TRUE(IsInterstitialBeingShownInFrame(blocked_frame_id)); |
| |
| permission_creator()->SetPermissionResult(true); |
| RequestPermissionFromFrame(blocked_frame_id); |
| EXPECT_EQ(permission_creator()->url_requests().size(), 1u); |
| std::string requested_host = permission_creator()->url_requests()[0].host(); |
| |
| EXPECT_EQ(requested_host, kIframeHost2); |
| |
| WaitForNavigationFinished(blocked[0], |
| permission_creator()->url_requests()[0]); |
| |
| EXPECT_FALSE(IsInterstitialBeingShownInFrame(blocked_frame_id)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SupervisedUserIframeFilterTest, BlockMultipleSubFrames) { |
| BlockHost(kIframeHost1); |
| BlockHost(kIframeHost2); |
| |
| GURL allowed_url_with_iframes = embedded_test_server()->GetURL( |
| kExampleHost, "/supervised_user/with_iframes.html"); |
| ui_test_utils::NavigateToURL(browser(), allowed_url_with_iframes); |
| EXPECT_FALSE(IsInterstitialBeingShownInMainFrame(browser())); |
| |
| auto blocked = GetBlockedFrames(); |
| EXPECT_EQ(blocked.size(), 2u); |
| |
| int blocked_frame_id_1 = blocked[0]; |
| GURL blocked_frame_url_1 = GetBlockedFrameURL(blocked_frame_id_1); |
| |
| int blocked_frame_id_2 = blocked[1]; |
| GURL blocked_frame_url_2 = GetBlockedFrameURL(blocked_frame_id_2); |
| |
| EXPECT_TRUE(IsInterstitialBeingShownInFrame(blocked_frame_id_1)); |
| |
| WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); |
| |
| permission_creator()->SetPermissionResult(true); |
| permission_creator()->DelayHandlingForNextRequests(); |
| |
| RequestPermissionFromFrame(blocked_frame_id_1); |
| RequestPermissionFromFrame(blocked_frame_id_2); |
| |
| EXPECT_EQ(permission_creator()->url_requests().size(), 2u); |
| EXPECT_EQ(permission_creator()->url_requests()[0], GURL(blocked_frame_url_1)); |
| EXPECT_EQ(permission_creator()->url_requests()[1], GURL(blocked_frame_url_2)); |
| |
| NavigationFinishedWaiter waiter1(tab, blocked_frame_id_1, |
| blocked_frame_url_1); |
| NavigationFinishedWaiter waiter2(tab, blocked_frame_id_2, |
| blocked_frame_url_2); |
| |
| permission_creator()->HandleDelayedRequests(); |
| |
| waiter1.Wait(); |
| waiter2.Wait(); |
| |
| DCHECK_EQ(GetBlockedFrames().size(), 0u); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SupervisedUserIframeFilterTest, TestBackButton) { |
| BlockHost(kIframeHost1); |
| |
| GURL allowed_url_with_iframes = embedded_test_server()->GetURL( |
| kExampleHost, "/supervised_user/with_iframes.html"); |
| ui_test_utils::NavigateToURL(browser(), allowed_url_with_iframes); |
| EXPECT_FALSE(IsInterstitialBeingShownInMainFrame(browser())); |
| |
| auto blocked = GetBlockedFrames(); |
| EXPECT_EQ(blocked.size(), 1u); |
| |
| permission_creator()->SetPermissionResult(true); |
| permission_creator()->DelayHandlingForNextRequests(); |
| |
| RequestPermissionFromFrame(blocked[0]); |
| |
| std::string command = |
| "domAutomationController.send(" |
| "(document.getElementById('back-button').hidden));"; |
| |
| auto* render_frame_host = tracker()->GetHost(blocked[0]); |
| DCHECK(render_frame_host->IsRenderFrameLive()); |
| bool value = false; |
| auto target = content::ToRenderFrameHost(render_frame_host); |
| EXPECT_TRUE(content::ExecuteScriptWithoutUserGestureAndExtractBool( |
| target, command, &value)); |
| |
| // Back button should be hidden in iframes. |
| EXPECT_TRUE(value); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SupervisedUserIframeFilterTest, |
| TestBackButtonMainFrame) { |
| BlockHost(kExampleHost); |
| |
| GURL allowed_url_with_iframes = embedded_test_server()->GetURL( |
| kExampleHost, "/supervised_user/with_iframes.html"); |
| ui_test_utils::NavigateToURL(browser(), allowed_url_with_iframes); |
| EXPECT_TRUE(IsInterstitialBeingShownInMainFrame(browser())); |
| |
| auto blocked = GetBlockedFrames(); |
| EXPECT_EQ(blocked.size(), 1u); |
| |
| permission_creator()->SetPermissionResult(true); |
| permission_creator()->DelayHandlingForNextRequests(); |
| |
| RequestPermissionFromFrame(blocked[0]); |
| |
| std::string command = |
| "domAutomationController.send(" |
| "(document.getElementById('back-button').hidden));"; |
| auto* render_frame_host = tracker()->GetHost(blocked[0]); |
| DCHECK(render_frame_host->IsRenderFrameLive()); |
| |
| bool value = false; |
| auto target = content::ToRenderFrameHost(render_frame_host); |
| EXPECT_TRUE(content::ExecuteScriptWithoutUserGestureAndExtractBool( |
| target, command, &value)); |
| |
| // Back button should not be hidden in main frame. |
| EXPECT_FALSE(value); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SupervisedUserIframeFilterTest, |
| AllowlistedMainFrameDenylistedIframe) { |
| AllowlistHost(kExampleHost); |
| BlockHost(kIframeHost1); |
| |
| GURL allowed_url_with_iframes = embedded_test_server()->GetURL( |
| kExampleHost, "/supervised_user/with_iframes.html"); |
| ui_test_utils::NavigateToURL(browser(), allowed_url_with_iframes); |
| EXPECT_FALSE(IsInterstitialBeingShownInMainFrame(browser())); |
| auto blocked = GetBlockedFrames(); |
| EXPECT_EQ(blocked.size(), 1u); |
| 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 |
| : public SupervisedUserNavigationThrottleTest { |
| protected: |
| SupervisedUserNavigationThrottleNotSupervisedTest() = default; |
| ~SupervisedUserNavigationThrottleNotSupervisedTest() override = default; |
| |
| chromeos::LoggedInUserMixin::LogInType GetLogInType() override { |
| return chromeos::LoggedInUserMixin::LogInType::kRegular; |
| } |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(SupervisedUserNavigationThrottleNotSupervisedTest, |
| DontBlock) { |
| BlockHost(kExampleHost); |
| |
| GURL blocked_url = embedded_test_server()->GetURL( |
| kExampleHost, "/supervised_user/simple.html"); |
| ui_test_utils::NavigateToURL(browser(), blocked_url); |
| // Even though the URL is marked as blocked, the load should go through, since |
| // the user isn't supervised. |
| EXPECT_FALSE(IsInterstitialBeingShownInMainFrame(browser())); |
| } |