davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 1 | // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 5 | #include <memory> |
| 6 | |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 7 | #include "base/bind.h" |
Nick Peterson | 87ecb10 | 2018-10-16 04:55:01 | [diff] [blame] | 8 | #include "base/json/json_reader.h" |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 9 | #include "base/run_loop.h" |
Devlin Cronin | d7f5857 | 2018-04-19 18:45:43 | [diff] [blame] | 10 | #include "base/strings/stringprintf.h" |
Eric Seckler | 8652dcd5 | 2018-09-20 10:42:28 | [diff] [blame] | 11 | #include "base/task/post_task.h" |
Devlin Cronin | d7f5857 | 2018-04-19 18:45:43 | [diff] [blame] | 12 | #include "chrome/browser/extensions/extension_apitest.h" |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 13 | #include "chrome/browser/extensions/extension_browsertest.h" |
Nick Peterson | 87ecb10 | 2018-10-16 04:55:01 | [diff] [blame] | 14 | #include "chrome/browser/extensions/extension_with_management_policy_apitest.h" |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 15 | #include "chrome/browser/profiles/profile.h" |
| 16 | #include "chrome/browser/profiles/profile_io_data.h" |
| 17 | #include "chrome/browser/ui/browser.h" |
Devlin Cronin | d7f5857 | 2018-04-19 18:45:43 | [diff] [blame] | 18 | #include "chrome/common/chrome_switches.h" |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 19 | #include "chrome/test/base/ui_test_utils.h" |
Eric Seckler | 8652dcd5 | 2018-09-20 10:42:28 | [diff] [blame] | 20 | #include "content/public/browser/browser_task_traits.h" |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 21 | #include "content/public/browser/browser_thread.h" |
Clark DuVall | 444729a60 | 2018-08-08 23:09:54 | [diff] [blame] | 22 | #include "content/public/browser/storage_partition.h" |
Nick Peterson | 87ecb10 | 2018-10-16 04:55:01 | [diff] [blame] | 23 | #include "content/public/test/browser_test_utils.h" |
Devlin Cronin | d7f5857 | 2018-04-19 18:45:43 | [diff] [blame] | 24 | #include "extensions/browser/browsertest_util.h" |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 25 | #include "extensions/common/extension.h" |
Devlin Cronin | d7f5857 | 2018-04-19 18:45:43 | [diff] [blame] | 26 | #include "extensions/common/extension_urls.h" |
| 27 | #include "extensions/test/extension_test_message_listener.h" |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 28 | #include "extensions/test/result_catcher.h" |
Devlin Cronin | d7f5857 | 2018-04-19 18:45:43 | [diff] [blame] | 29 | #include "extensions/test/test_extension_dir.h" |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 30 | #include "net/base/escape.h" |
| 31 | #include "net/base/url_util.h" |
Devlin Cronin | d7f5857 | 2018-04-19 18:45:43 | [diff] [blame] | 32 | #include "net/dns/mock_host_resolver.h" |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 33 | #include "net/ssl/client_cert_store.h" |
svaldez | a01f7d9 | 2015-11-18 17:47:56 | [diff] [blame] | 34 | #include "net/ssl/ssl_server_config.h" |
| 35 | #include "net/test/embedded_test_server/embedded_test_server.h" |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 36 | #include "url/gurl.h" |
| 37 | |
Devlin Cronin | d7f5857 | 2018-04-19 18:45:43 | [diff] [blame] | 38 | namespace extensions { |
| 39 | |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 40 | namespace { |
| 41 | |
Devlin Cronin | d7f5857 | 2018-04-19 18:45:43 | [diff] [blame] | 42 | constexpr const char kWebstoreDomain[] = "cws.com"; |
| 43 | |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 44 | std::unique_ptr<net::ClientCertStore> CreateNullCertStore() { |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 45 | return nullptr; |
| 46 | } |
| 47 | |
| 48 | void InstallNullCertStoreFactoryOnIOThread( |
| 49 | content::ResourceContext* resource_context) { |
| 50 | ProfileIOData::FromResourceContext(resource_context) |
| 51 | ->set_client_cert_store_factory_for_testing( |
| 52 | base::Bind(&CreateNullCertStore)); |
| 53 | } |
| 54 | |
| 55 | } // namespace |
| 56 | |
| 57 | class BackgroundXhrTest : public ExtensionBrowserTest { |
| 58 | protected: |
| 59 | void RunTest(const std::string& path, const GURL& url) { |
Devlin Cronin | d7f5857 | 2018-04-19 18:45:43 | [diff] [blame] | 60 | const Extension* extension = |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 61 | LoadExtension(test_data_dir_.AppendASCII("background_xhr")); |
| 62 | ASSERT_TRUE(extension); |
| 63 | |
Devlin Cronin | d7f5857 | 2018-04-19 18:45:43 | [diff] [blame] | 64 | ResultCatcher catcher; |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 65 | GURL test_url = net::AppendQueryParameter(extension->GetResourceURL(path), |
| 66 | "url", url.spec()); |
| 67 | ui_test_utils::NavigateToURL(browser(), test_url); |
Clark DuVall | 444729a60 | 2018-08-08 23:09:54 | [diff] [blame] | 68 | content::BrowserContext::GetDefaultStoragePartition(profile()) |
| 69 | ->FlushNetworkInterfaceForTesting(); |
Clark DuVall | 16be254 | 2018-07-23 22:42:42 | [diff] [blame] | 70 | constexpr char kSendXHRScript[] = R"( |
| 71 | var xhr = new XMLHttpRequest(); |
| 72 | xhr.open('GET', '%s'); |
| 73 | xhr.send(); |
| 74 | domAutomationController.send(''); |
| 75 | )"; |
| 76 | browsertest_util::ExecuteScriptInBackgroundPage( |
| 77 | profile(), extension->id(), |
| 78 | base::StringPrintf(kSendXHRScript, url.spec().c_str())); |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 79 | ASSERT_TRUE(catcher.GetNextResult()); |
| 80 | } |
| 81 | }; |
| 82 | |
| 83 | // Test that fetching a URL using TLS client auth doesn't crash, hang, or |
| 84 | // prompt. |
| 85 | IN_PROC_BROWSER_TEST_F(BackgroundXhrTest, TlsClientAuth) { |
| 86 | // Install a null ClientCertStore so the client auth prompt isn't bypassed due |
| 87 | // to the system certificate store returning no certificates. |
| 88 | base::RunLoop loop; |
Eric Seckler | 8652dcd5 | 2018-09-20 10:42:28 | [diff] [blame] | 89 | base::PostTaskWithTraitsAndReply( |
| 90 | FROM_HERE, {content::BrowserThread::IO}, |
tzik | 8d880ee | 2017-04-20 19:46:24 | [diff] [blame] | 91 | base::BindOnce(&InstallNullCertStoreFactoryOnIOThread, |
| 92 | browser()->profile()->GetResourceContext()), |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 93 | loop.QuitClosure()); |
| 94 | loop.Run(); |
| 95 | |
| 96 | // Launch HTTPS server. |
svaldez | a01f7d9 | 2015-11-18 17:47:56 | [diff] [blame] | 97 | net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); |
| 98 | net::SSLServerConfig ssl_config; |
ryanchung | 987b2ff | 2016-02-19 00:17:12 | [diff] [blame] | 99 | ssl_config.client_cert_type = |
| 100 | net::SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT; |
svaldez | a01f7d9 | 2015-11-18 17:47:56 | [diff] [blame] | 101 | https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config); |
| 102 | https_server.ServeFilesFromSourceDirectory("content/test/data"); |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 103 | ASSERT_TRUE(https_server.Start()); |
| 104 | |
| 105 | ASSERT_NO_FATAL_FAILURE( |
svaldez | a01f7d9 | 2015-11-18 17:47:56 | [diff] [blame] | 106 | RunTest("test_tls_client_auth.html", https_server.GetURL("/"))); |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 107 | } |
| 108 | |
| 109 | // Test that fetching a URL using HTTP auth doesn't crash, hang, or prompt. |
| 110 | IN_PROC_BROWSER_TEST_F(BackgroundXhrTest, HttpAuth) { |
svaldez | a01f7d9 | 2015-11-18 17:47:56 | [diff] [blame] | 111 | ASSERT_TRUE(embedded_test_server()->Start()); |
| 112 | ASSERT_NO_FATAL_FAILURE(RunTest( |
| 113 | "test_http_auth.html", embedded_test_server()->GetURL("/auth-basic"))); |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 114 | } |
Devlin Cronin | d7f5857 | 2018-04-19 18:45:43 | [diff] [blame] | 115 | |
Nick Peterson | 87ecb10 | 2018-10-16 04:55:01 | [diff] [blame] | 116 | class BackgroundXhrWebstoreTest : public ExtensionApiTestWithManagementPolicy { |
Devlin Cronin | d7f5857 | 2018-04-19 18:45:43 | [diff] [blame] | 117 | public: |
| 118 | BackgroundXhrWebstoreTest() = default; |
| 119 | ~BackgroundXhrWebstoreTest() override = default; |
| 120 | |
| 121 | void SetUpCommandLine(base::CommandLine* command_line) override { |
| 122 | ExtensionApiTest::SetUpCommandLine(command_line); |
| 123 | // TODO(devlin): For some reason, trying to fetch an HTTPS url in this test |
| 124 | // fails (even when using an HTTPS EmbeddedTestServer). For this reason, we |
| 125 | // need to fake the webstore URLs as http versions. |
| 126 | command_line->AppendSwitchASCII( |
| 127 | ::switches::kAppsGalleryURL, |
| 128 | base::StringPrintf("http://%s", kWebstoreDomain)); |
| 129 | } |
| 130 | |
| 131 | void SetUpOnMainThread() override { |
| 132 | ExtensionApiTest::SetUpOnMainThread(); |
| 133 | host_resolver()->AddRule("*", "127.0.0.1"); |
| 134 | ASSERT_TRUE(embedded_test_server()->Start()); |
| 135 | } |
| 136 | |
Nick Peterson | 87ecb10 | 2018-10-16 04:55:01 | [diff] [blame] | 137 | bool CanFetch(const Extension* extension, const GURL& url) { |
| 138 | content::DOMMessageQueue message_queue; |
| 139 | browsertest_util::ExecuteScriptInBackgroundPageNoWait( |
| 140 | profile(), extension->id(), |
| 141 | base::StringPrintf("canFetch('%s');", url.spec().c_str())); |
| 142 | std::string json; |
| 143 | EXPECT_TRUE(message_queue.WaitForMessage(&json)); |
| 144 | base::JSONReader reader(base::JSON_ALLOW_TRAILING_COMMAS); |
| 145 | std::unique_ptr<base::Value> value = reader.ReadToValue(json); |
| 146 | std::string result; |
| 147 | EXPECT_TRUE(value->GetAsString(&result)); |
| 148 | EXPECT_TRUE(result == "true" || result == "false") << result; |
| 149 | return result == "true"; |
| 150 | } |
| 151 | |
| 152 | const Extension* LoadXhrExtension(const std::string& host) { |
| 153 | ExtensionTestMessageListener listener("ready", false); |
| 154 | TestExtensionDir test_dir; |
| 155 | test_dir.WriteManifest(R"( |
| 156 | { |
| 157 | "name": "XHR Test", |
| 158 | "manifest_version": 2, |
| 159 | "version": "0.1", |
| 160 | "background": {"scripts": ["background.js"]}, |
| 161 | "permissions": [")" + host + R"("] |
| 162 | })"); |
| 163 | constexpr char kBackgroundScriptFile[] = R"( |
| 164 | function canFetch(url) { |
| 165 | console.warn('Fetching: ' + url); |
| 166 | fetch(url).then((response) => { |
| 167 | domAutomationController.send('true'); |
| 168 | }).catch((e) => { |
| 169 | let message; |
| 170 | if (e.message == 'Failed to fetch') |
| 171 | message = 'false' |
| 172 | else |
| 173 | message = 'Unexpected Error: ' + e.message; |
| 174 | domAutomationController.send(message); |
| 175 | }); |
| 176 | } |
| 177 | chrome.test.sendMessage('ready');)"; |
| 178 | |
| 179 | test_dir.WriteFile(FILE_PATH_LITERAL("background.js"), |
| 180 | kBackgroundScriptFile); |
| 181 | const Extension* extension = LoadExtension(test_dir.UnpackedPath()); |
| 182 | EXPECT_TRUE(listener.WaitUntilSatisfied()); |
| 183 | return extension; |
| 184 | } |
| 185 | |
Devlin Cronin | d7f5857 | 2018-04-19 18:45:43 | [diff] [blame] | 186 | private: |
| 187 | DISALLOW_COPY_AND_ASSIGN(BackgroundXhrWebstoreTest); |
| 188 | }; |
| 189 | |
| 190 | // Extensions should not be able to XHR to the webstore. |
| 191 | IN_PROC_BROWSER_TEST_F(BackgroundXhrWebstoreTest, XHRToWebstore) { |
Nick Peterson | 87ecb10 | 2018-10-16 04:55:01 | [diff] [blame] | 192 | const Extension* extension = LoadXhrExtension("<all_urls>"); |
Devlin Cronin | d7f5857 | 2018-04-19 18:45:43 | [diff] [blame] | 193 | |
| 194 | GURL webstore_launch_url = extension_urls::GetWebstoreLaunchURL(); |
| 195 | GURL webstore_url_to_fetch = embedded_test_server()->GetURL( |
| 196 | webstore_launch_url.host(), "/simple.html"); |
| 197 | |
Nick Peterson | 87ecb10 | 2018-10-16 04:55:01 | [diff] [blame] | 198 | EXPECT_FALSE(CanFetch(extension, webstore_url_to_fetch)); |
Devlin Cronin | d7f5857 | 2018-04-19 18:45:43 | [diff] [blame] | 199 | |
| 200 | // Sanity check: the extension should be able to fetch google.com. |
| 201 | GURL google_url = |
| 202 | embedded_test_server()->GetURL("google.com", "/simple.html"); |
Nick Peterson | 87ecb10 | 2018-10-16 04:55:01 | [diff] [blame] | 203 | EXPECT_TRUE(CanFetch(extension, google_url)); |
| 204 | } |
| 205 | |
| 206 | // Extensions should not be able to XHR to the webstore regardless of policy. |
| 207 | IN_PROC_BROWSER_TEST_F(BackgroundXhrWebstoreTest, XHRToWebstorePolicy) { |
| 208 | { |
| 209 | ExtensionManagementPolicyUpdater pref(&policy_provider_); |
| 210 | pref.AddPolicyAllowedHost( |
| 211 | "*", "*://" + extension_urls::GetWebstoreLaunchURL().host()); |
| 212 | } |
| 213 | |
| 214 | const Extension* extension = LoadXhrExtension("<all_urls>"); |
| 215 | |
| 216 | GURL webstore_launch_url = extension_urls::GetWebstoreLaunchURL(); |
| 217 | GURL webstore_url_to_fetch = embedded_test_server()->GetURL( |
| 218 | webstore_launch_url.host(), "/simple.html"); |
| 219 | |
| 220 | EXPECT_FALSE(CanFetch(extension, webstore_url_to_fetch)); |
| 221 | |
| 222 | // Sanity check: the extension should be able to fetch google.com. |
| 223 | GURL google_url = |
| 224 | embedded_test_server()->GetURL("google.com", "/simple.html"); |
| 225 | EXPECT_TRUE(CanFetch(extension, google_url)); |
| 226 | } |
| 227 | |
| 228 | // Extensions should not be able to bypass same-origin despite declaring |
| 229 | // <all_urls> for hosts restricted by enterprise policy. |
| 230 | IN_PROC_BROWSER_TEST_F(BackgroundXhrWebstoreTest, PolicyBlockedXHR) { |
| 231 | { |
| 232 | ExtensionManagementPolicyUpdater pref(&policy_provider_); |
| 233 | pref.AddPolicyBlockedHost("*", "*://*.example.com"); |
| 234 | pref.AddPolicyAllowedHost("*", "*://public.example.com"); |
| 235 | } |
| 236 | |
| 237 | const Extension* extension = LoadXhrExtension("<all_urls>"); |
| 238 | |
| 239 | // Should block due to "runtime_blocked_hosts" section of policy. |
| 240 | GURL protected_url_to_fetch = |
| 241 | embedded_test_server()->GetURL("example.com", "/simple.html"); |
| 242 | EXPECT_FALSE(CanFetch(extension, protected_url_to_fetch)); |
| 243 | |
| 244 | // Should allow due to "runtime_allowed_hosts" section of policy. |
| 245 | GURL exempted_url_to_fetch = |
| 246 | embedded_test_server()->GetURL("public.example.com", "/simple.html"); |
| 247 | EXPECT_TRUE(CanFetch(extension, exempted_url_to_fetch)); |
| 248 | } |
| 249 | |
| 250 | // Verify that policy blocklists apply to XHRs done from injected scripts. |
| 251 | IN_PROC_BROWSER_TEST_F(BackgroundXhrWebstoreTest, PolicyContentScriptXHR) { |
| 252 | TestExtensionDir test_dir; |
| 253 | test_dir.WriteManifest(R"( |
| 254 | { |
| 255 | "name": "XHR Content Script Test", |
| 256 | "manifest_version": 2, |
| 257 | "version": "0.1", |
| 258 | "permissions": ["<all_urls>", "tabs"], |
| 259 | "background": {"scripts": ["background.js"]} |
| 260 | })"); |
| 261 | |
| 262 | constexpr char kBackgroundScript[] = |
| 263 | R"(function canFetch(url) { |
| 264 | chrome.tabs.executeScript({code: ` |
| 265 | fetch("${url}") |
| 266 | .then(response => response.text()) |
| 267 | .then(text => domAutomationController.send('true')) |
| 268 | .catch(err => domAutomationController.send('false')); |
| 269 | `}); |
| 270 | } |
| 271 | )"; |
| 272 | test_dir.WriteFile(FILE_PATH_LITERAL("background.js"), kBackgroundScript); |
| 273 | |
| 274 | const Extension* extension = LoadExtension(test_dir.UnpackedPath()); |
| 275 | ASSERT_TRUE(extension); |
| 276 | |
| 277 | // Navigate to a foo.com page. |
| 278 | content::WebContents* web_contents = |
| 279 | browser()->tab_strip_model()->GetActiveWebContents(); |
| 280 | GURL page_url(embedded_test_server()->GetURL("foo.com", "/title1.html")); |
| 281 | ui_test_utils::NavigateToURL(browser(), page_url); |
| 282 | EXPECT_EQ(page_url, web_contents->GetMainFrame()->GetLastCommittedURL()); |
| 283 | |
| 284 | GURL example_url = |
| 285 | embedded_test_server()->GetURL("example.com", "/simple.html"); |
| 286 | GURL public_example_url = |
| 287 | embedded_test_server()->GetURL("public.example.com", "/simple.html"); |
| 288 | |
| 289 | // Sanity Check: Should be able to fetch cross origin. |
| 290 | EXPECT_TRUE(CanFetch(extension, example_url)); |
| 291 | EXPECT_TRUE(CanFetch(extension, public_example_url)); |
| 292 | |
| 293 | { |
| 294 | ExtensionManagementPolicyUpdater pref(&policy_provider_); |
| 295 | pref.AddPolicyBlockedHost("*", "*://*.example.com"); |
| 296 | pref.AddPolicyAllowedHost("*", "*://public.example.com"); |
| 297 | } |
| 298 | |
| 299 | // Policies apply to XHR from a content script. |
| 300 | EXPECT_FALSE(CanFetch(extension, example_url)); |
| 301 | EXPECT_TRUE(CanFetch(extension, public_example_url)); |
| 302 | } |
| 303 | |
| 304 | // Make sure the blocklist and allowlist update for both Default and Individual |
| 305 | // scope policies. Testing with all host permissions granted (<all_urls>). |
| 306 | IN_PROC_BROWSER_TEST_F(BackgroundXhrWebstoreTest, PolicyUpdateXHR) { |
| 307 | const Extension* extension = LoadXhrExtension("<all_urls>"); |
| 308 | |
| 309 | GURL example_url = |
| 310 | embedded_test_server()->GetURL("example.com", "/simple.html"); |
| 311 | GURL public_example_url = |
| 312 | embedded_test_server()->GetURL("public.example.com", "/simple.html"); |
| 313 | |
| 314 | // Sanity check: Without restrictions all fetches should work. |
| 315 | EXPECT_TRUE(CanFetch(extension, public_example_url)); |
| 316 | EXPECT_TRUE(CanFetch(extension, example_url)); |
| 317 | |
| 318 | { |
| 319 | ExtensionManagementPolicyUpdater pref(&policy_provider_); |
| 320 | pref.AddPolicyBlockedHost("*", "*://*.example.com"); |
| 321 | pref.AddPolicyAllowedHost("*", "*://public.example.com"); |
| 322 | } |
| 323 | |
| 324 | // Default policies propagate. |
| 325 | EXPECT_TRUE(CanFetch(extension, public_example_url)); |
| 326 | EXPECT_FALSE(CanFetch(extension, example_url)); |
| 327 | { |
| 328 | ExtensionManagementPolicyUpdater pref(&policy_provider_); |
| 329 | pref.AddPolicyBlockedHost(extension->id(), "*://*.example2.com"); |
| 330 | pref.AddPolicyAllowedHost(extension->id(), "*://public.example2.com"); |
| 331 | } |
| 332 | |
| 333 | // Default policies overridden when individual scope policies applied. |
| 334 | EXPECT_TRUE(CanFetch(extension, public_example_url)); |
| 335 | EXPECT_TRUE(CanFetch(extension, example_url)); |
| 336 | |
| 337 | GURL example2_url = |
| 338 | embedded_test_server()->GetURL("example2.com", "/simple.html"); |
| 339 | GURL public_example2_url = |
| 340 | embedded_test_server()->GetURL("public.example2.com", "/simple.html"); |
| 341 | |
| 342 | // Individual scope policies propagate. |
| 343 | EXPECT_TRUE(CanFetch(extension, public_example2_url)); |
| 344 | EXPECT_FALSE(CanFetch(extension, example2_url)); |
| 345 | } |
| 346 | |
| 347 | // Make sure the allowlist entries added due to host permissions are removed |
| 348 | // when a more generic blocklist policy is updated and contains them. |
| 349 | // This tests the default policy scope update. |
| 350 | IN_PROC_BROWSER_TEST_F(BackgroundXhrWebstoreTest, PolicyUpdateDefaultXHR) { |
| 351 | const Extension* extension = LoadXhrExtension("*://public.example.com/*"); |
| 352 | |
| 353 | GURL example_url = |
| 354 | embedded_test_server()->GetURL("example.com", "/simple.html"); |
| 355 | GURL public_example_url = |
| 356 | embedded_test_server()->GetURL("public.example.com", "/simple.html"); |
| 357 | |
| 358 | // Sanity check: Without restrictions only public.example.com should work. |
| 359 | EXPECT_TRUE(CanFetch(extension, public_example_url)); |
| 360 | EXPECT_FALSE(CanFetch(extension, example_url)); |
| 361 | |
| 362 | { |
| 363 | ExtensionManagementPolicyUpdater pref(&policy_provider_); |
| 364 | pref.AddPolicyBlockedHost("*", "*://*.example.com"); |
| 365 | } |
| 366 | |
| 367 | // The blocklist of example.com overrides allowlist of public.example.com. |
| 368 | EXPECT_FALSE(CanFetch(extension, example_url)); |
| 369 | EXPECT_FALSE(CanFetch(extension, public_example_url)); |
| 370 | } |
| 371 | |
| 372 | // Make sure the allowlist entries added due to host permissions are removed |
| 373 | // when a more generic blocklist policy is updated and contains them. |
| 374 | // This tests an individual policy scope update. |
| 375 | IN_PROC_BROWSER_TEST_F(BackgroundXhrWebstoreTest, PolicyUpdateIndividualXHR) { |
| 376 | const Extension* extension = LoadXhrExtension("*://public.example.com/*"); |
| 377 | |
| 378 | GURL example_url = |
| 379 | embedded_test_server()->GetURL("example.com", "/simple.html"); |
| 380 | GURL public_example_url = |
| 381 | embedded_test_server()->GetURL("public.example.com", "/simple.html"); |
| 382 | |
| 383 | // Sanity check: Without restrictions only public.example.com should work. |
| 384 | EXPECT_TRUE(CanFetch(extension, public_example_url)); |
| 385 | EXPECT_FALSE(CanFetch(extension, example_url)); |
| 386 | |
| 387 | { |
| 388 | ExtensionManagementPolicyUpdater pref(&policy_provider_); |
| 389 | pref.AddPolicyBlockedHost(extension->id(), "*://*.example.com"); |
| 390 | } |
| 391 | |
| 392 | // The blocklist of example.com overrides allowlist of public.example.com. |
| 393 | EXPECT_FALSE(CanFetch(extension, example_url)); |
| 394 | EXPECT_FALSE(CanFetch(extension, public_example_url)); |
Devlin Cronin | d7f5857 | 2018-04-19 18:45:43 | [diff] [blame] | 395 | } |
| 396 | |
| 397 | } // namespace extensions |