 Chromium Code Reviews
 Chromium Code Reviews Issue 2495353003:
  chrome.webRequest support for ExtensionSettings  (Closed)
    
  
    Issue 2495353003:
  chrome.webRequest support for ExtensionSettings  (Closed) 
  | Index: chrome/browser/extensions/api/web_request/web_request_apitest.cc | 
| diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc | 
| index 689edf0961772cf262738164502912176a36e5bb..7c69b599a5ae754c98e89735c4d24b29e9a10152 100644 | 
| --- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc | 
| +++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc | 
| @@ -15,6 +15,7 @@ | 
| #include "chrome/browser/extensions/extension_action_runner.h" | 
| #include "chrome/browser/extensions/extension_apitest.h" | 
| #include "chrome/browser/extensions/extension_service.h" | 
| +#include "chrome/browser/extensions/extension_with_management_policy_apitest.h" | 
| #include "chrome/browser/extensions/tab_helper.h" | 
| #include "chrome/browser/extensions/test_extension_dir.h" | 
| #include "chrome/browser/profiles/profile.h" | 
| @@ -46,6 +47,7 @@ | 
| #include "extensions/test/result_catcher.h" | 
| #include "net/dns/mock_host_resolver.h" | 
| #include "net/test/embedded_test_server/embedded_test_server.h" | 
| +#include "net/test/embedded_test_server/http_request.h" | 
| #include "net/test/test_data_directory.h" | 
| #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" | 
| #include "net/url_request/test_url_fetcher_factory.h" | 
| @@ -954,4 +956,207 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, | 
| } | 
| } | 
| +// Tests that the webRequest events aren't dispatched when the request initiator | 
| +// is protected by policy. | 
| +IN_PROC_BROWSER_TEST_F(ExtensionApiTestWithManagementPolicy, | 
| + InitiatorProtectedByPolicy) { | 
| + // Host navigated to. | 
| + const std::string example_com = "example.com"; | 
| + | 
| + // Domain that hosts javascript file referenced by example_com. | 
| + const std::string example2_com = "example2.com"; | 
| + | 
| + // Extension communicates back using this listener name. | 
| + const std::string listener_name = "protected_origin"; | 
| 
Devlin
2017/06/01 15:21:33
this isn't a name, it's a message.
 
nrpeter
2017/06/06 21:42:07
Done.
 | 
| + | 
| + // We expect that no webRequest will be hidden or modification blocked. This | 
| + // means that the request to example.com will be seen by the extension. | 
| + { | 
| + ExtensionManagementPolicyUpdater pref(&policy_provider_); | 
| + pref.AddRuntimeBlockedHost("*", "*://notexample.com"); | 
| + } | 
| + // Set auto confirm UI flag. | 
| + PermissionsRequestFunction::SetAutoConfirmForTests(true); | 
| 
Devlin
2017/06/01 15:21:33
As mentioned in https://codereview.chromium.org/24
 
nrpeter
2017/06/06 21:42:07
Done.
 | 
| + | 
| + ASSERT_TRUE(StartEmbeddedTestServer()); | 
| + | 
| + // URL within the text extension that initiates cross domain requests when | 
| + // navigated to. | 
| + const GURL extension_test_url = embedded_test_server()->GetURL( | 
| + example_com, | 
| + "/extensions/api_test/webrequest/policy_blocked/ref_remote_js.html"); | 
| + | 
| + LoadExtension(test_data_dir_.AppendASCII("webrequest/policy_blocked")); | 
| + | 
| + // Listen to verify extension sees the web request. | 
| + ExtensionTestMessageListener before_request_listener(listener_name, false); | 
| + | 
| + // Wait until all remote Javascript files have been blocked / pulled down. | 
| + ui_test_utils::NavigateToURLWithDisposition( | 
| + browser(), extension_test_url, WindowOpenDisposition::CURRENT_TAB, | 
| + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 
| + | 
| + // The server saw a request for the remote Javascript file. | 
| + EXPECT_TRUE(BrowsedTo(example2_com)); | 
| + | 
| + // The webRequest was seen by the extension. | 
| + EXPECT_TRUE(before_request_listener.was_satisfied()); | 
| + | 
| + // Clear the list of domains the server has seen. | 
| + ClearRequestLog(); | 
| + | 
| + // Make sure we've cleared the embedded server history. | 
| + EXPECT_FALSE(BrowsedTo(example2_com)); | 
| + | 
| + // Set the policy to hide webRequests to example.com or any resource | 
| 
Devlin
2017/06/01 15:21:32
s/webRequests/requests (webRequest is the API)
 
nrpeter
2017/06/06 21:42:07
Done.
 | 
| + // it includes. We expect that in this test, the webRequest to example2.com | 
| + // will not be seen by the extension. | 
| + { | 
| + ExtensionManagementPolicyUpdater pref(&policy_provider_); | 
| + pref.AddRuntimeBlockedHost("*", "*://" + example_com); | 
| + } | 
| + | 
| + // Listen in case extension sees the web requst. | 
| + ExtensionTestMessageListener before_request_listener2(listener_name, false); | 
| + | 
| + // Wait until all remote Javascript files have been pulled down. | 
| + ui_test_utils::NavigateToURLWithDisposition( | 
| + browser(), extension_test_url, WindowOpenDisposition::CURRENT_TAB, | 
| + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 
| + | 
| + // The server saw a request for the remote Javascript file. | 
| + EXPECT_TRUE(BrowsedTo(example2_com)); | 
| + | 
| + // The webRequest was hidden from the extension. | 
| + EXPECT_FALSE(before_request_listener2.was_satisfied()); | 
| +} | 
| + | 
| +// Tests that the webRequest events aren't dispatched when the URL of the | 
| +// request is protected by policy. | 
| +IN_PROC_BROWSER_TEST_F(ExtensionApiTestWithManagementPolicy, | 
| + UrlProtectedByPolicy) { | 
| + // Host protected by policy. | 
| + const std::string protected_domain = "example.com"; | 
| + | 
| + // Host not protected by policy. | 
| + const std::string unprotected_domain = "not_blocked_example.com"; | 
| 
Devlin
2017/06/01 15:21:32
As mentioned at https://codereview.chromium.org/24
 
nrpeter
2017/06/06 21:42:07
Done.
 | 
| + | 
| + // File to resolve during test navigations. | 
| + const std::string file_url = | 
| 
Devlin
2017/06/01 15:21:33
variables should be declared near their first use.
 
nrpeter
2017/06/06 21:42:07
Done.
 | 
| + "/extensions/api_test/webrequest/policy_blocked/protected_url.html"; | 
| + | 
| + { | 
| + ExtensionManagementPolicyUpdater pref(&policy_provider_); | 
| + pref.AddRuntimeBlockedHost("*", "*://" + protected_domain); | 
| + } | 
| + | 
| + // Set auto confirm UI flag. | 
| + PermissionsRequestFunction::SetAutoConfirmForTests(true); | 
| + | 
| + ASSERT_TRUE(StartEmbeddedTestServer()); | 
| + | 
| + LoadExtension(test_data_dir_.AppendASCII("webrequest/policy_blocked")); | 
| + | 
| + // Listen in case extension sees the web requst. | 
| + ExtensionTestMessageListener before_request_listener("protected_url", false); | 
| + | 
| + // Navigate to the protected domain and wait until page fully loads. | 
| + ui_test_utils::NavigateToURLWithDisposition( | 
| + browser(), embedded_test_server()->GetURL(protected_domain, file_url), | 
| + WindowOpenDisposition::CURRENT_TAB, | 
| + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 
| + | 
| + // The server saw a request for the protected site. | 
| + EXPECT_TRUE(BrowsedTo(protected_domain)); | 
| + | 
| + // The webRequest was hidden from the extension. | 
| + EXPECT_FALSE(before_request_listener.was_satisfied()); | 
| + | 
| + // Now we'll test browsing to a non-protected website where we expect the | 
| + // extension to see the webrequest event. | 
| + ui_test_utils::NavigateToURLWithDisposition( | 
| + browser(), embedded_test_server()->GetURL(unprotected_domain, file_url), | 
| + WindowOpenDisposition::CURRENT_TAB, | 
| + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 
| + | 
| + // The server saw a request for the non-protected site. | 
| + EXPECT_TRUE(BrowsedTo(unprotected_domain)); | 
| + | 
| + // The webRequest was visible from the extension. | 
| + EXPECT_TRUE(before_request_listener.was_satisfied()); | 
| +} | 
| + | 
| +// Test that no webRequest events are seen for a protected host during normal | 
| +// navigation. This replicates most of the tests from | 
| +// WebRequestWithWithheldPermissions with a protected host. Granting a tab | 
| +// specific permission shouldn't bypass our policy. | 
| +IN_PROC_BROWSER_TEST_F(ExtensionApiTestWithManagementPolicy, | 
| + WebRequestProtectedByPolicy) { | 
| + FeatureSwitch::ScopedOverride enable_scripts_require_action( | 
| + FeatureSwitch::scripts_require_action(), true); | 
| + | 
| + // Host protected by policy. | 
| + const std::string protected_domain = "example.com"; | 
| + | 
| + { | 
| + ExtensionManagementPolicyUpdater pref(&policy_provider_); | 
| + pref.AddRuntimeBlockedHost("*", "*://" + protected_domain); | 
| + } | 
| + | 
| + extensions::PermissionsRequestFunction::SetAutoConfirmForTests(true); | 
| + ASSERT_TRUE(StartEmbeddedTestServer()); | 
| + | 
| + ExtensionTestMessageListener listener("ready", false); | 
| + const Extension* extension = | 
| + LoadExtension(test_data_dir_.AppendASCII("webrequest_activetab")); | 
| + ASSERT_TRUE(extension) << message_; | 
| + EXPECT_TRUE(listener.WaitUntilSatisfied()); | 
| + | 
| + // Navigate the browser to a page in a new tab. | 
| + GURL url = embedded_test_server()->GetURL(protected_domain, "/empty.html"); | 
| + chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK); | 
| + params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; | 
| + ui_test_utils::NavigateToURL(¶ms); | 
| + | 
| + content::WebContents* web_contents = | 
| + browser()->tab_strip_model()->GetActiveWebContents(); | 
| + ASSERT_TRUE(web_contents); | 
| + ExtensionActionRunner* runner = | 
| + ExtensionActionRunner::GetForWebContents(web_contents); | 
| + ASSERT_TRUE(runner); | 
| + | 
| + int port = embedded_test_server()->port(); | 
| + const std::string kXhrPath = "simple.html"; | 
| + | 
| + // The extension shouldn't have currently received any webRequest events, | 
| + // since it doesn't have permission (and shouldn't receive any from an XHR). | 
| + EXPECT_EQ(0, GetWebRequestCountFromBackgroundPage(extension, profile())); | 
| + PerformXhrInFrame(web_contents->GetMainFrame(), protected_domain, port, | 
| + kXhrPath); | 
| + EXPECT_EQ(0, GetWebRequestCountFromBackgroundPage(extension, profile())); | 
| + | 
| + // Grant activeTab permission, and perform another XHR. The extension should | 
| + // still be blocked due to ExtensionSettings policy on example.com. | 
| + // Only records ACCESS_WITHHELD, not ACCESS_DENIED, this is why it matches | 
| + // BLOCKED_ACTION_NONE. | 
| + EXPECT_EQ(BLOCKED_ACTION_NONE, runner->GetBlockedActions(extension)); | 
| + runner->set_default_bubble_close_action_for_testing( | 
| 
Devlin
2017/06/01 15:21:32
Trying to run when the extension doesn't want to i
 
nrpeter
2017/06/06 21:42:07
I could, but wanted to make sure that modification
 | 
| + base::WrapUnique(new ToolbarActionsBarBubbleDelegate::CloseAction( | 
| + ToolbarActionsBarBubbleDelegate::CLOSE_EXECUTE))); | 
| + runner->RunAction(extension, true); | 
| + base::RunLoop().RunUntilIdle(); | 
| + EXPECT_TRUE(content::WaitForLoadStop(web_contents)); | 
| + // The runner will have refreshed the page... | 
| 
Devlin
2017/06/01 15:21:33
Will it have, if there was no blocked action?
 
nrpeter
2017/06/06 21:42:07
Done. Thanks, that was an old comment.
 | 
| + EXPECT_EQ(BLOCKED_ACTION_NONE, runner->GetBlockedActions(extension)); | 
| + int xhr_count = GetWebRequestCountFromBackgroundPage(extension, profile()); | 
| + // ... which means that we should have a non-zero xhr count if the policy | 
| + // didn't block the events. | 
| + EXPECT_EQ(xhr_count, 0); | 
| 
Devlin
2017/06/01 15:21:33
EXPECT_EQ(expected, actual)
 
nrpeter
2017/06/06 21:42:07
Done.
 | 
| + // And the extension should also block future events. | 
| + PerformXhrInFrame(web_contents->GetMainFrame(), protected_domain, port, | 
| + kXhrPath); | 
| + EXPECT_EQ(xhr_count, | 
| 
Devlin
2017/06/01 15:21:33
prefer 0, since that's what we expect
 
nrpeter
2017/06/06 21:42:07
Done.
 | 
| + GetWebRequestCountFromBackgroundPage(extension, profile())); | 
| +} | 
| + | 
| } // namespace extensions |