blob: 9e6f6ad28d96a98a1e61f5c8492c804554b7f477 [file] [log] [blame]
[email protected]78cd68e2014-05-22 20:33:521// Copyright 2014 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
avia2f4804a2015-12-24 23:11:135#include <stddef.h>
6
[email protected]78cd68e2014-05-22 20:33:527#include <map>
limasdf3d102542015-12-09 03:58:458#include <utility>
[email protected]78cd68e2014-05-22 20:33:529
Sebastien Marchandf1349f52019-01-25 03:16:4110#include "base/bind.h"
[email protected]78cd68e2014-05-22 20:33:5211#include "base/values.h"
[email protected]78cd68e2014-05-22 20:33:5212#include "chrome/browser/extensions/active_tab_permission_granter.h"
rdevlin.cronin699ca6ff2014-09-29 23:59:5713#include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
rdevlin.cronin8408b4f92016-03-15 19:14:1414#include "chrome/browser/extensions/extension_action_runner.h"
rdevlin.cronind1aa8522015-02-13 00:25:5715#include "chrome/browser/extensions/extension_sync_service_factory.h"
[email protected]23a85362014-07-07 23:26:1916#include "chrome/browser/extensions/permissions_updater.h"
rdevlin.cronincb9f86e2015-10-15 15:13:4217#include "chrome/browser/extensions/scripting_permissions_modifier.h"
[email protected]78cd68e2014-05-22 20:33:5218#include "chrome/browser/extensions/tab_helper.h"
19#include "chrome/test/base/chrome_render_view_host_test_harness.h"
20#include "chrome/test/base/testing_profile.h"
[email protected]fdd28372014-08-21 02:27:2621#include "components/crx_file/id_util.h"
[email protected]78cd68e2014-05-22 20:33:5222#include "content/public/browser/navigation_controller.h"
23#include "content/public/browser/navigation_entry.h"
24#include "content/public/browser/web_contents.h"
clamyf2053032017-10-20 16:01:5925#include "content/public/test/navigation_simulator.h"
[email protected]78cd68e2014-05-22 20:33:5226#include "extensions/browser/extension_registry.h"
27#include "extensions/common/extension.h"
28#include "extensions/common/extension_builder.h"
Devlin Cronincac45cb2018-04-25 04:43:0329#include "extensions/common/extension_features.h"
[email protected]78cd68e2014-05-22 20:33:5230#include "extensions/common/manifest.h"
[email protected]23a85362014-07-07 23:26:1931#include "extensions/common/user_script.h"
[email protected]78cd68e2014-05-22 20:33:5232#include "extensions/common/value_builder.h"
33
34namespace extensions {
35
36namespace {
37
38const char kAllHostsPermission[] = "*://*/*";
39
40} // namespace
41
rdevlin.cronin8408b4f92016-03-15 19:14:1442// Unittests for the ExtensionActionRunner mostly test the internal logic
43// of the runner itself (when to allow/deny extension script injection).
[email protected]78cd68e2014-05-22 20:33:5244// Testing real injection is allowed/denied as expected (i.e., that the
rdevlin.cronin8408b4f92016-03-15 19:14:1445// ExtensionActionRunner correctly interfaces in the system) is done in the
46// ExtensionActionRunnerBrowserTests.
47class ExtensionActionRunnerUnitTest : public ChromeRenderViewHostTestHarness {
[email protected]78cd68e2014-05-22 20:33:5248 protected:
rdevlin.cronin8408b4f92016-03-15 19:14:1449 ExtensionActionRunnerUnitTest();
50 ~ExtensionActionRunnerUnitTest() override;
[email protected]78cd68e2014-05-22 20:33:5251
52 // Creates an extension with all hosts permission and adds it to the registry.
53 const Extension* AddExtension();
54
[email protected]e1670582014-08-15 23:05:4155 // Reloads |extension_| by removing it from the registry and recreating it.
56 const Extension* ReloadExtension();
57
[email protected]23a85362014-07-07 23:26:1958 // Returns true if the |extension| requires user consent before injecting
59 // a script.
60 bool RequiresUserConsent(const Extension* extension) const;
61
62 // Request an injection for the given |extension|.
63 void RequestInjection(const Extension* extension);
rdevlin.cronin8d034e52016-02-02 22:46:3264 void RequestInjection(const Extension* extension,
65 UserScript::RunLocation run_location);
[email protected]78cd68e2014-05-22 20:33:5266
67 // Returns the number of times a given extension has had a script execute.
68 size_t GetExecutionCountForExtension(const std::string& extension_id) const;
69
rdevlin.cronin8408b4f92016-03-15 19:14:1470 ExtensionActionRunner* runner() const { return extension_action_runner_; }
[email protected]78cd68e2014-05-22 20:33:5271
72 private:
[email protected]23a85362014-07-07 23:26:1973 // Returns a closure to use as a script execution for a given extension.
74 base::Closure GetExecutionCallbackForExtension(
75 const std::string& extension_id);
76
[email protected]78cd68e2014-05-22 20:33:5277 // Increment the number of executions for the given |extension_id|.
78 void IncrementExecutionCount(const std::string& extension_id);
79
dcheng72191812014-10-28 20:49:5680 void SetUp() override;
[email protected]78cd68e2014-05-22 20:33:5281
rdevlin.cronin8408b4f92016-03-15 19:14:1482 // The associated ExtensionActionRunner.
Devlin Cronincac45cb2018-04-25 04:43:0383 ExtensionActionRunner* extension_action_runner_ = nullptr;
[email protected]78cd68e2014-05-22 20:33:5284
85 // The map of observed executions, keyed by extension id.
86 std::map<std::string, int> extension_executions_;
[email protected]e1670582014-08-15 23:05:4187
88 scoped_refptr<const Extension> extension_;
rdevlin.cronin8d034e52016-02-02 22:46:3289
rdevlin.cronin8408b4f92016-03-15 19:14:1490 DISALLOW_COPY_AND_ASSIGN(ExtensionActionRunnerUnitTest);
[email protected]78cd68e2014-05-22 20:33:5291};
92
Devlin Cronincac45cb2018-04-25 04:43:0393ExtensionActionRunnerUnitTest::ExtensionActionRunnerUnitTest() = default;
94ExtensionActionRunnerUnitTest::~ExtensionActionRunnerUnitTest() = default;
[email protected]78cd68e2014-05-22 20:33:5295
rdevlin.cronin8408b4f92016-03-15 19:14:1496const Extension* ExtensionActionRunnerUnitTest::AddExtension() {
[email protected]fdd28372014-08-21 02:27:2697 const std::string kId = crx_file::id_util::GenerateId("all_hosts_extension");
limasdf3d102542015-12-09 03:58:4598 extension_ =
99 ExtensionBuilder()
dcheng794d2bd2016-02-27 03:51:32100 .SetManifest(
limasdf21d67e62015-12-19 12:04:49101 DictionaryBuilder()
102 .Set("name", "all_hosts_extension")
103 .Set("description", "an extension")
104 .Set("manifest_version", 2)
105 .Set("version", "1.0.0")
106 .Set("permissions",
dcheng794d2bd2016-02-27 03:51:32107 ListBuilder().Append(kAllHostsPermission).Build())
108 .Build())
limasdf3d102542015-12-09 03:58:45109 .SetLocation(Manifest::INTERNAL)
110 .SetID(kId)
111 .Build();
[email protected]78cd68e2014-05-22 20:33:52112
[email protected]e1670582014-08-15 23:05:41113 ExtensionRegistry::Get(profile())->AddEnabled(extension_);
dchengc7047942014-08-26 05:05:31114 PermissionsUpdater(profile()).InitializePermissions(extension_.get());
Devlin Croninf355f1de2018-05-14 15:27:24115
116 ScriptingPermissionsModifier(profile(), extension_.get())
Devlin Croninc5830702018-07-03 00:26:16117 .SetWithholdHostPermissions(true);
dchengc7047942014-08-26 05:05:31118 return extension_.get();
[email protected]e1670582014-08-15 23:05:41119}
120
rdevlin.cronin8408b4f92016-03-15 19:14:14121const Extension* ExtensionActionRunnerUnitTest::ReloadExtension() {
[email protected]e1670582014-08-15 23:05:41122 ExtensionRegistry::Get(profile())->RemoveEnabled(extension_->id());
123 return AddExtension();
[email protected]78cd68e2014-05-22 20:33:52124}
125
rdevlin.cronin8408b4f92016-03-15 19:14:14126bool ExtensionActionRunnerUnitTest::RequiresUserConsent(
[email protected]23a85362014-07-07 23:26:19127 const Extension* extension) const {
Devlin Cronin3e532b82018-05-03 21:27:19128 PermissionsData::PageAccess access_type =
rdevlin.cronin8408b4f92016-03-15 19:14:14129 runner()->RequiresUserConsentForScriptInjectionForTesting(
[email protected]23a85362014-07-07 23:26:19130 extension, UserScript::PROGRAMMATIC_SCRIPT);
131 // We should never downright refuse access in these tests.
Devlin Cronin3e532b82018-05-03 21:27:19132 DCHECK_NE(PermissionsData::PageAccess::kDenied, access_type);
133 return access_type == PermissionsData::PageAccess::kWithheld;
[email protected]23a85362014-07-07 23:26:19134}
135
rdevlin.cronin8408b4f92016-03-15 19:14:14136void ExtensionActionRunnerUnitTest::RequestInjection(
[email protected]23a85362014-07-07 23:26:19137 const Extension* extension) {
rdevlin.cronin8d034e52016-02-02 22:46:32138 RequestInjection(extension, UserScript::DOCUMENT_IDLE);
139}
140
rdevlin.cronin8408b4f92016-03-15 19:14:14141void ExtensionActionRunnerUnitTest::RequestInjection(
rdevlin.cronin8d034e52016-02-02 22:46:32142 const Extension* extension,
143 UserScript::RunLocation run_location) {
rdevlin.cronin8408b4f92016-03-15 19:14:14144 runner()->RequestScriptInjectionForTesting(
rdevlin.cronin8d034e52016-02-02 22:46:32145 extension, run_location,
[email protected]23a85362014-07-07 23:26:19146 GetExecutionCallbackForExtension(extension->id()));
[email protected]78cd68e2014-05-22 20:33:52147}
148
rdevlin.cronin8408b4f92016-03-15 19:14:14149size_t ExtensionActionRunnerUnitTest::GetExecutionCountForExtension(
[email protected]78cd68e2014-05-22 20:33:52150 const std::string& extension_id) const {
jdoerrie13cd648c82018-10-02 21:21:02151 auto iter = extension_executions_.find(extension_id);
[email protected]78cd68e2014-05-22 20:33:52152 if (iter != extension_executions_.end())
153 return iter->second;
154 return 0u;
155}
156
rdevlin.cronin8408b4f92016-03-15 19:14:14157base::Closure ExtensionActionRunnerUnitTest::GetExecutionCallbackForExtension(
[email protected]23a85362014-07-07 23:26:19158 const std::string& extension_id) {
159 // We use base unretained here, but if this ever gets executed outside of
160 // this test's lifetime, we have a major problem anyway.
rdevlin.cronin8408b4f92016-03-15 19:14:14161 return base::Bind(&ExtensionActionRunnerUnitTest::IncrementExecutionCount,
162 base::Unretained(this), extension_id);
[email protected]23a85362014-07-07 23:26:19163}
164
rdevlin.cronin8408b4f92016-03-15 19:14:14165void ExtensionActionRunnerUnitTest::IncrementExecutionCount(
[email protected]78cd68e2014-05-22 20:33:52166 const std::string& extension_id) {
167 ++extension_executions_[extension_id];
168}
169
rdevlin.cronin8408b4f92016-03-15 19:14:14170void ExtensionActionRunnerUnitTest::SetUp() {
[email protected]78cd68e2014-05-22 20:33:52171 ChromeRenderViewHostTestHarness::SetUp();
172
isherman30fa851a2015-06-09 23:32:10173 // Skip syncing for testing purposes.
Sylvain Defresne711ff6b2018-10-04 12:33:54174 ExtensionSyncServiceFactory::GetInstance()->SetTestingFactory(
175 profile(), BrowserContextKeyedServiceFactory::TestingFactory());
rdevlin.cronind1aa8522015-02-13 00:25:57176
[email protected]78cd68e2014-05-22 20:33:52177 TabHelper::CreateForWebContents(web_contents());
178 TabHelper* tab_helper = TabHelper::FromWebContents(web_contents());
rdevlin.cronin8d034e52016-02-02 22:46:32179 // These should never be null.
[email protected]78cd68e2014-05-22 20:33:52180 DCHECK(tab_helper);
rdevlin.cronin8408b4f92016-03-15 19:14:14181 extension_action_runner_ = tab_helper->extension_action_runner();
182 DCHECK(extension_action_runner_);
[email protected]78cd68e2014-05-22 20:33:52183}
184
185// Test that extensions with all_hosts require permission to execute, and, once
186// that permission is granted, do execute.
rdevlin.cronin8408b4f92016-03-15 19:14:14187TEST_F(ExtensionActionRunnerUnitTest, RequestPermissionAndExecute) {
[email protected]78cd68e2014-05-22 20:33:52188 const Extension* extension = AddExtension();
189 ASSERT_TRUE(extension);
190
191 NavigateAndCommit(GURL("https://www.google.com"));
192
193 // Ensure that there aren't any executions pending.
194 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14195 ASSERT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52196
197 // Since the extension requests all_hosts, we should require user consent.
[email protected]23a85362014-07-07 23:26:19198 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52199
rdevlin.cronin91f162a12014-09-03 16:48:40200 // Request an injection. The extension should want to run, but should not have
201 // executed.
[email protected]23a85362014-07-07 23:26:19202 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14203 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52204 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
205
206 // Click to accept the extension executing.
rdevlin.cronin4a78c48b2016-03-24 00:02:29207 runner()->RunForTesting(extension);
[email protected]78cd68e2014-05-22 20:33:52208
rdevlin.cronin91f162a12014-09-03 16:48:40209 // The extension should execute, and the extension shouldn't want to run.
[email protected]78cd68e2014-05-22 20:33:52210 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14211 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52212
213 // Since we already executed on the given page, we shouldn't need permission
214 // for a second time.
[email protected]23a85362014-07-07 23:26:19215 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52216
[email protected]4b8d1c62014-08-16 01:22:21217 // Reloading and same-origin navigations shouldn't clear those permissions,
218 // and we shouldn't require user constent again.
clamyf2053032017-10-20 16:01:59219 content::NavigationSimulator::Reload(web_contents());
[email protected]4b8d1c62014-08-16 01:22:21220 EXPECT_FALSE(RequiresUserConsent(extension));
221 NavigateAndCommit(GURL("https://www.google.com/foo"));
222 EXPECT_FALSE(RequiresUserConsent(extension));
223 NavigateAndCommit(GURL("https://www.google.com/bar"));
224 EXPECT_FALSE(RequiresUserConsent(extension));
225
226 // Cross-origin navigations should clear permissions.
227 NavigateAndCommit(GURL("https://otherdomain.google.com"));
[email protected]23a85362014-07-07 23:26:19228 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52229
230 // Grant access.
[email protected]23a85362014-07-07 23:26:19231 RequestInjection(extension);
rdevlin.cronin4a78c48b2016-03-24 00:02:29232 runner()->RunForTesting(extension);
[email protected]78cd68e2014-05-22 20:33:52233 EXPECT_EQ(2u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14234 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52235
236 // Navigating to another site should also clear the permissions.
237 NavigateAndCommit(GURL("https://www.foo.com"));
[email protected]23a85362014-07-07 23:26:19238 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52239}
240
241// Test that injections that are not executed by the time the user navigates are
242// ignored and never execute.
rdevlin.cronin8408b4f92016-03-15 19:14:14243TEST_F(ExtensionActionRunnerUnitTest, PendingInjectionsRemovedAtNavigation) {
[email protected]78cd68e2014-05-22 20:33:52244 const Extension* extension = AddExtension();
245 ASSERT_TRUE(extension);
246
247 NavigateAndCommit(GURL("https://www.google.com"));
248
249 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
250
rdevlin.cronin91f162a12014-09-03 16:48:40251 // Request an injection. The extension should want to run, but not execute.
[email protected]23a85362014-07-07 23:26:19252 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14253 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52254 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
255
[email protected]8d5cb212014-06-04 09:00:39256 // Reload. This should remove the pending injection, and we should not
[email protected]78cd68e2014-05-22 20:33:52257 // execute anything.
clamyf2053032017-10-20 16:01:59258 content::NavigationSimulator::Reload(web_contents());
rdevlin.cronin8408b4f92016-03-15 19:14:14259 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52260 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
261
262 // Request and accept a new injection.
[email protected]23a85362014-07-07 23:26:19263 RequestInjection(extension);
rdevlin.cronin4a78c48b2016-03-24 00:02:29264 runner()->RunForTesting(extension);
[email protected]78cd68e2014-05-22 20:33:52265
266 // The extension should only have executed once, even though a grand total
267 // of two executions were requested.
268 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14269 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52270}
271
272// Test that queueing multiple pending injections, and then accepting, triggers
273// them all.
rdevlin.cronin8408b4f92016-03-15 19:14:14274TEST_F(ExtensionActionRunnerUnitTest, MultiplePendingInjection) {
[email protected]78cd68e2014-05-22 20:33:52275 const Extension* extension = AddExtension();
276 ASSERT_TRUE(extension);
277 NavigateAndCommit(GURL("https://www.google.com"));
278
279 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
280
281 const size_t kNumInjections = 3u;
282 // Queue multiple pending injections.
[email protected]23a85362014-07-07 23:26:19283 for (size_t i = 0u; i < kNumInjections; ++i)
284 RequestInjection(extension);
285
[email protected]78cd68e2014-05-22 20:33:52286 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
287
rdevlin.cronin4a78c48b2016-03-24 00:02:29288 runner()->RunForTesting(extension);
[email protected]78cd68e2014-05-22 20:33:52289
290 // All pending injections should have executed.
291 EXPECT_EQ(kNumInjections, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14292 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52293}
294
rdevlin.cronin8408b4f92016-03-15 19:14:14295TEST_F(ExtensionActionRunnerUnitTest, ActiveScriptsUseActiveTabPermissions) {
[email protected]78cd68e2014-05-22 20:33:52296 const Extension* extension = AddExtension();
297 NavigateAndCommit(GURL("https://www.google.com"));
298
299 ActiveTabPermissionGranter* active_tab_permission_granter =
300 TabHelper::FromWebContents(web_contents())
301 ->active_tab_permission_granter();
302 ASSERT_TRUE(active_tab_permission_granter);
303 // Grant the extension active tab permissions. This normally happens, e.g.,
304 // if the user clicks on a browser action.
305 active_tab_permission_granter->GrantIfRequested(extension);
306
307 // Since we have active tab permissions, we shouldn't need user consent
308 // anymore.
[email protected]23a85362014-07-07 23:26:19309 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52310
[email protected]4b8d1c62014-08-16 01:22:21311 // Reloading and other same-origin navigations maintain the permission to
312 // execute.
clamyf2053032017-10-20 16:01:59313 content::NavigationSimulator::Reload(web_contents());
[email protected]4b8d1c62014-08-16 01:22:21314 EXPECT_FALSE(RequiresUserConsent(extension));
315 NavigateAndCommit(GURL("https://www.google.com/foo"));
316 EXPECT_FALSE(RequiresUserConsent(extension));
317 NavigateAndCommit(GURL("https://www.google.com/bar"));
318 EXPECT_FALSE(RequiresUserConsent(extension));
319
320 // Navigating to a different origin will require user consent again.
321 NavigateAndCommit(GURL("https://yahoo.com"));
322 EXPECT_TRUE(RequiresUserConsent(extension));
323
324 // Back to the original origin should also re-require constent.
325 NavigateAndCommit(GURL("https://www.google.com"));
[email protected]23a85362014-07-07 23:26:19326 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]11814f52014-05-23 06:50:35327
[email protected]23a85362014-07-07 23:26:19328 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14329 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]11814f52014-05-23 06:50:35330 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
331
332 // Grant active tab.
333 active_tab_permission_granter->GrantIfRequested(extension);
334
335 // The pending injections should have run since active tab permission was
336 // granted.
337 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14338 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52339}
340
rdevlin.cronin8408b4f92016-03-15 19:14:14341TEST_F(ExtensionActionRunnerUnitTest, ActiveScriptsCanHaveAllUrlsPref) {
[email protected]b33c8c22014-05-29 19:51:08342 const Extension* extension = AddExtension();
343 ASSERT_TRUE(extension);
344
345 NavigateAndCommit(GURL("https://www.google.com"));
[email protected]23a85362014-07-07 23:26:19346 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08347
348 // Enable the extension on all urls.
rdevlin.cronind01837b2016-08-17 01:37:18349 ScriptingPermissionsModifier permissions_modifier(profile(), extension);
Devlin Croninc5830702018-07-03 00:26:16350 permissions_modifier.SetWithholdHostPermissions(false);
[email protected]b33c8c22014-05-29 19:51:08351
[email protected]23a85362014-07-07 23:26:19352 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08353 // This should carry across navigations, and websites.
354 NavigateAndCommit(GURL("http://www.foo.com"));
[email protected]23a85362014-07-07 23:26:19355 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08356
357 // Turning off the preference should have instant effect.
Devlin Croninc5830702018-07-03 00:26:16358 permissions_modifier.SetWithholdHostPermissions(true);
[email protected]23a85362014-07-07 23:26:19359 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08360
361 // And should also persist across navigations and websites.
362 NavigateAndCommit(GURL("http://www.bar.com"));
[email protected]23a85362014-07-07 23:26:19363 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08364}
365
rdevlin.cronin8408b4f92016-03-15 19:14:14366TEST_F(ExtensionActionRunnerUnitTest, TestAlwaysRun) {
[email protected]e1670582014-08-15 23:05:41367 const Extension* extension = AddExtension();
368 ASSERT_TRUE(extension);
369
370 NavigateAndCommit(GURL("https://www.google.com/?gws_rd=ssl"));
371
372 // Ensure that there aren't any executions pending.
373 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14374 ASSERT_FALSE(runner()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41375
376 // Since the extension requests all_hosts, we should require user consent.
377 EXPECT_TRUE(RequiresUserConsent(extension));
378
rdevlin.cronin91f162a12014-09-03 16:48:40379 // Request an injection. The extension should want to run, but not execute.
[email protected]e1670582014-08-15 23:05:41380 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14381 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41382 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
383
384 // Allow the extension to always run on this origin.
rdevlin.cronincb9f86e2015-10-15 15:13:42385 ScriptingPermissionsModifier modifier(profile(), extension);
386 modifier.GrantHostPermission(web_contents()->GetLastCommittedURL());
rdevlin.cronin4a78c48b2016-03-24 00:02:29387 runner()->RunForTesting(extension);
[email protected]e1670582014-08-15 23:05:41388
rdevlin.cronin91f162a12014-09-03 16:48:40389 // The extension should execute, and the extension shouldn't want to run.
[email protected]e1670582014-08-15 23:05:41390 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14391 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41392
393 // Since we already executed on the given page, we shouldn't need permission
394 // for a second time.
395 EXPECT_FALSE(RequiresUserConsent(extension));
396
397 // Navigating to another site that hasn't been granted a persisted permission
398 // should necessitate user consent.
399 NavigateAndCommit(GURL("https://www.foo.com/bar"));
400 EXPECT_TRUE(RequiresUserConsent(extension));
401
402 // We shouldn't need user permission upon returning to the original origin.
403 NavigateAndCommit(GURL("https://www.google.com/foo/bar"));
404 EXPECT_FALSE(RequiresUserConsent(extension));
405
406 // Reloading the extension should not clear any granted host permissions.
407 extension = ReloadExtension();
clamyf2053032017-10-20 16:01:59408 content::NavigationSimulator::Reload(web_contents());
[email protected]e1670582014-08-15 23:05:41409 EXPECT_FALSE(RequiresUserConsent(extension));
410
411 // Different host...
412 NavigateAndCommit(GURL("https://www.foo.com/bar"));
413 EXPECT_TRUE(RequiresUserConsent(extension));
414 // Different scheme...
415 NavigateAndCommit(GURL("http://www.google.com/foo/bar"));
416 EXPECT_TRUE(RequiresUserConsent(extension));
417 // Different subdomain...
418 NavigateAndCommit(GURL("https://en.google.com/foo/bar"));
419 EXPECT_TRUE(RequiresUserConsent(extension));
420 // Only the "always run" origin should be allowed to run without user consent.
421 NavigateAndCommit(GURL("https://www.google.com/foo/bar"));
422 EXPECT_FALSE(RequiresUserConsent(extension));
423}
424
rdevlin.cronin8408b4f92016-03-15 19:14:14425TEST_F(ExtensionActionRunnerUnitTest, TestDifferentScriptRunLocations) {
rdevlin.cronin8d034e52016-02-02 22:46:32426 const Extension* extension = AddExtension();
427 ASSERT_TRUE(extension);
428
429 NavigateAndCommit(GURL("https://www.foo.com"));
430
rdevlin.cronin8408b4f92016-03-15 19:14:14431 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32432
433 RequestInjection(extension, UserScript::DOCUMENT_END);
434 EXPECT_EQ(BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14435 runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32436 RequestInjection(extension, UserScript::DOCUMENT_IDLE);
437 EXPECT_EQ(BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14438 runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32439 RequestInjection(extension, UserScript::DOCUMENT_START);
440 EXPECT_EQ(BLOCKED_ACTION_SCRIPT_AT_START | BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14441 runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32442
rdevlin.cronin4a78c48b2016-03-24 00:02:29443 runner()->RunForTesting(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14444 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32445}
446
rdevlin.cronin8408b4f92016-03-15 19:14:14447TEST_F(ExtensionActionRunnerUnitTest, TestWebRequestBlocked) {
rdevlin.cronin8d034e52016-02-02 22:46:32448 const Extension* extension = AddExtension();
449 ASSERT_TRUE(extension);
450
451 NavigateAndCommit(GURL("https://www.foo.com"));
452
rdevlin.cronin8408b4f92016-03-15 19:14:14453 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
454 EXPECT_FALSE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32455
rdevlin.cronin8408b4f92016-03-15 19:14:14456 runner()->OnWebRequestBlocked(extension);
457 EXPECT_EQ(BLOCKED_ACTION_WEB_REQUEST, runner()->GetBlockedActions(extension));
458 EXPECT_TRUE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32459
460 RequestInjection(extension);
461 EXPECT_EQ(BLOCKED_ACTION_WEB_REQUEST | BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14462 runner()->GetBlockedActions(extension));
463 EXPECT_TRUE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32464
465 NavigateAndCommit(GURL("https://www.bar.com"));
rdevlin.cronin8408b4f92016-03-15 19:14:14466 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
467 EXPECT_FALSE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32468}
469
[email protected]78cd68e2014-05-22 20:33:52470} // namespace extensions