Chromium Code Reviews| 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 |