blob: 83e62d55cf7f9bf2bb78e73002901e9a4baf691f [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
Devlin Cronincac45cb2018-04-25 04:43:0310#include "base/test/scoped_feature_list.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
Devlin Cronincac45cb2018-04-25 04:43:0382 // Used to enable features::kRuntimeHostPermissions for ExtensionActionRunner
83 // to take effect.
84 base::test::ScopedFeatureList scoped_feature_list_;
[email protected]78cd68e2014-05-22 20:33:5285
rdevlin.cronin8408b4f92016-03-15 19:14:1486 // The associated ExtensionActionRunner.
Devlin Cronincac45cb2018-04-25 04:43:0387 ExtensionActionRunner* extension_action_runner_ = nullptr;
[email protected]78cd68e2014-05-22 20:33:5288
89 // The map of observed executions, keyed by extension id.
90 std::map<std::string, int> extension_executions_;
[email protected]e1670582014-08-15 23:05:4191
92 scoped_refptr<const Extension> extension_;
rdevlin.cronin8d034e52016-02-02 22:46:3293
rdevlin.cronin8408b4f92016-03-15 19:14:1494 DISALLOW_COPY_AND_ASSIGN(ExtensionActionRunnerUnitTest);
[email protected]78cd68e2014-05-22 20:33:5295};
96
Devlin Cronincac45cb2018-04-25 04:43:0397ExtensionActionRunnerUnitTest::ExtensionActionRunnerUnitTest() = default;
98ExtensionActionRunnerUnitTest::~ExtensionActionRunnerUnitTest() = default;
[email protected]78cd68e2014-05-22 20:33:5299
rdevlin.cronin8408b4f92016-03-15 19:14:14100const Extension* ExtensionActionRunnerUnitTest::AddExtension() {
[email protected]fdd28372014-08-21 02:27:26101 const std::string kId = crx_file::id_util::GenerateId("all_hosts_extension");
limasdf3d102542015-12-09 03:58:45102 extension_ =
103 ExtensionBuilder()
dcheng794d2bd2016-02-27 03:51:32104 .SetManifest(
limasdf21d67e62015-12-19 12:04:49105 DictionaryBuilder()
106 .Set("name", "all_hosts_extension")
107 .Set("description", "an extension")
108 .Set("manifest_version", 2)
109 .Set("version", "1.0.0")
110 .Set("permissions",
dcheng794d2bd2016-02-27 03:51:32111 ListBuilder().Append(kAllHostsPermission).Build())
112 .Build())
limasdf3d102542015-12-09 03:58:45113 .SetLocation(Manifest::INTERNAL)
114 .SetID(kId)
115 .Build();
[email protected]78cd68e2014-05-22 20:33:52116
[email protected]e1670582014-08-15 23:05:41117 ExtensionRegistry::Get(profile())->AddEnabled(extension_);
dchengc7047942014-08-26 05:05:31118 PermissionsUpdater(profile()).InitializePermissions(extension_.get());
Devlin Croninf355f1de2018-05-14 15:27:24119
120 ScriptingPermissionsModifier(profile(), extension_.get())
Devlin Croninc5830702018-07-03 00:26:16121 .SetWithholdHostPermissions(true);
dchengc7047942014-08-26 05:05:31122 return extension_.get();
[email protected]e1670582014-08-15 23:05:41123}
124
rdevlin.cronin8408b4f92016-03-15 19:14:14125const Extension* ExtensionActionRunnerUnitTest::ReloadExtension() {
[email protected]e1670582014-08-15 23:05:41126 ExtensionRegistry::Get(profile())->RemoveEnabled(extension_->id());
127 return AddExtension();
[email protected]78cd68e2014-05-22 20:33:52128}
129
rdevlin.cronin8408b4f92016-03-15 19:14:14130bool ExtensionActionRunnerUnitTest::RequiresUserConsent(
[email protected]23a85362014-07-07 23:26:19131 const Extension* extension) const {
Devlin Cronin3e532b82018-05-03 21:27:19132 PermissionsData::PageAccess access_type =
rdevlin.cronin8408b4f92016-03-15 19:14:14133 runner()->RequiresUserConsentForScriptInjectionForTesting(
[email protected]23a85362014-07-07 23:26:19134 extension, UserScript::PROGRAMMATIC_SCRIPT);
135 // We should never downright refuse access in these tests.
Devlin Cronin3e532b82018-05-03 21:27:19136 DCHECK_NE(PermissionsData::PageAccess::kDenied, access_type);
137 return access_type == PermissionsData::PageAccess::kWithheld;
[email protected]23a85362014-07-07 23:26:19138}
139
rdevlin.cronin8408b4f92016-03-15 19:14:14140void ExtensionActionRunnerUnitTest::RequestInjection(
[email protected]23a85362014-07-07 23:26:19141 const Extension* extension) {
rdevlin.cronin8d034e52016-02-02 22:46:32142 RequestInjection(extension, UserScript::DOCUMENT_IDLE);
143}
144
rdevlin.cronin8408b4f92016-03-15 19:14:14145void ExtensionActionRunnerUnitTest::RequestInjection(
rdevlin.cronin8d034e52016-02-02 22:46:32146 const Extension* extension,
147 UserScript::RunLocation run_location) {
rdevlin.cronin8408b4f92016-03-15 19:14:14148 runner()->RequestScriptInjectionForTesting(
rdevlin.cronin8d034e52016-02-02 22:46:32149 extension, run_location,
[email protected]23a85362014-07-07 23:26:19150 GetExecutionCallbackForExtension(extension->id()));
[email protected]78cd68e2014-05-22 20:33:52151}
152
rdevlin.cronin8408b4f92016-03-15 19:14:14153size_t ExtensionActionRunnerUnitTest::GetExecutionCountForExtension(
[email protected]78cd68e2014-05-22 20:33:52154 const std::string& extension_id) const {
155 std::map<std::string, int>::const_iterator iter =
156 extension_executions_.find(extension_id);
157 if (iter != extension_executions_.end())
158 return iter->second;
159 return 0u;
160}
161
rdevlin.cronin8408b4f92016-03-15 19:14:14162base::Closure ExtensionActionRunnerUnitTest::GetExecutionCallbackForExtension(
[email protected]23a85362014-07-07 23:26:19163 const std::string& extension_id) {
164 // We use base unretained here, but if this ever gets executed outside of
165 // this test's lifetime, we have a major problem anyway.
rdevlin.cronin8408b4f92016-03-15 19:14:14166 return base::Bind(&ExtensionActionRunnerUnitTest::IncrementExecutionCount,
167 base::Unretained(this), extension_id);
[email protected]23a85362014-07-07 23:26:19168}
169
rdevlin.cronin8408b4f92016-03-15 19:14:14170void ExtensionActionRunnerUnitTest::IncrementExecutionCount(
[email protected]78cd68e2014-05-22 20:33:52171 const std::string& extension_id) {
172 ++extension_executions_[extension_id];
173}
174
rdevlin.cronin8408b4f92016-03-15 19:14:14175void ExtensionActionRunnerUnitTest::SetUp() {
[email protected]78cd68e2014-05-22 20:33:52176 ChromeRenderViewHostTestHarness::SetUp();
177
Devlin Cronincac45cb2018-04-25 04:43:03178 scoped_feature_list_.InitAndEnableFeature(features::kRuntimeHostPermissions);
179
isherman30fa851a2015-06-09 23:32:10180 // Skip syncing for testing purposes.
181 ExtensionSyncServiceFactory::GetInstance()->SetTestingFactory(profile(),
182 nullptr);
rdevlin.cronind1aa8522015-02-13 00:25:57183
[email protected]78cd68e2014-05-22 20:33:52184 TabHelper::CreateForWebContents(web_contents());
185 TabHelper* tab_helper = TabHelper::FromWebContents(web_contents());
rdevlin.cronin8d034e52016-02-02 22:46:32186 // These should never be null.
[email protected]78cd68e2014-05-22 20:33:52187 DCHECK(tab_helper);
rdevlin.cronin8408b4f92016-03-15 19:14:14188 extension_action_runner_ = tab_helper->extension_action_runner();
189 DCHECK(extension_action_runner_);
[email protected]78cd68e2014-05-22 20:33:52190}
191
192// Test that extensions with all_hosts require permission to execute, and, once
193// that permission is granted, do execute.
rdevlin.cronin8408b4f92016-03-15 19:14:14194TEST_F(ExtensionActionRunnerUnitTest, RequestPermissionAndExecute) {
[email protected]78cd68e2014-05-22 20:33:52195 const Extension* extension = AddExtension();
196 ASSERT_TRUE(extension);
197
198 NavigateAndCommit(GURL("https://www.google.com"));
199
200 // Ensure that there aren't any executions pending.
201 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14202 ASSERT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52203
204 // Since the extension requests all_hosts, we should require user consent.
[email protected]23a85362014-07-07 23:26:19205 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52206
rdevlin.cronin91f162a12014-09-03 16:48:40207 // Request an injection. The extension should want to run, but should not have
208 // executed.
[email protected]23a85362014-07-07 23:26:19209 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14210 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52211 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
212
213 // Click to accept the extension executing.
rdevlin.cronin4a78c48b2016-03-24 00:02:29214 runner()->RunForTesting(extension);
[email protected]78cd68e2014-05-22 20:33:52215
rdevlin.cronin91f162a12014-09-03 16:48:40216 // The extension should execute, and the extension shouldn't want to run.
[email protected]78cd68e2014-05-22 20:33:52217 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14218 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52219
220 // Since we already executed on the given page, we shouldn't need permission
221 // for a second time.
[email protected]23a85362014-07-07 23:26:19222 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52223
[email protected]4b8d1c62014-08-16 01:22:21224 // Reloading and same-origin navigations shouldn't clear those permissions,
225 // and we shouldn't require user constent again.
clamyf2053032017-10-20 16:01:59226 content::NavigationSimulator::Reload(web_contents());
[email protected]4b8d1c62014-08-16 01:22:21227 EXPECT_FALSE(RequiresUserConsent(extension));
228 NavigateAndCommit(GURL("https://www.google.com/foo"));
229 EXPECT_FALSE(RequiresUserConsent(extension));
230 NavigateAndCommit(GURL("https://www.google.com/bar"));
231 EXPECT_FALSE(RequiresUserConsent(extension));
232
233 // Cross-origin navigations should clear permissions.
234 NavigateAndCommit(GURL("https://otherdomain.google.com"));
[email protected]23a85362014-07-07 23:26:19235 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52236
237 // Grant access.
[email protected]23a85362014-07-07 23:26:19238 RequestInjection(extension);
rdevlin.cronin4a78c48b2016-03-24 00:02:29239 runner()->RunForTesting(extension);
[email protected]78cd68e2014-05-22 20:33:52240 EXPECT_EQ(2u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14241 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52242
243 // Navigating to another site should also clear the permissions.
244 NavigateAndCommit(GURL("https://www.foo.com"));
[email protected]23a85362014-07-07 23:26:19245 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52246}
247
248// Test that injections that are not executed by the time the user navigates are
249// ignored and never execute.
rdevlin.cronin8408b4f92016-03-15 19:14:14250TEST_F(ExtensionActionRunnerUnitTest, PendingInjectionsRemovedAtNavigation) {
[email protected]78cd68e2014-05-22 20:33:52251 const Extension* extension = AddExtension();
252 ASSERT_TRUE(extension);
253
254 NavigateAndCommit(GURL("https://www.google.com"));
255
256 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
257
rdevlin.cronin91f162a12014-09-03 16:48:40258 // Request an injection. The extension should want to run, but not execute.
[email protected]23a85362014-07-07 23:26:19259 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14260 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52261 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
262
[email protected]8d5cb212014-06-04 09:00:39263 // Reload. This should remove the pending injection, and we should not
[email protected]78cd68e2014-05-22 20:33:52264 // execute anything.
clamyf2053032017-10-20 16:01:59265 content::NavigationSimulator::Reload(web_contents());
rdevlin.cronin8408b4f92016-03-15 19:14:14266 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52267 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
268
269 // Request and accept a new injection.
[email protected]23a85362014-07-07 23:26:19270 RequestInjection(extension);
rdevlin.cronin4a78c48b2016-03-24 00:02:29271 runner()->RunForTesting(extension);
[email protected]78cd68e2014-05-22 20:33:52272
273 // The extension should only have executed once, even though a grand total
274 // of two executions were requested.
275 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14276 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52277}
278
279// Test that queueing multiple pending injections, and then accepting, triggers
280// them all.
rdevlin.cronin8408b4f92016-03-15 19:14:14281TEST_F(ExtensionActionRunnerUnitTest, MultiplePendingInjection) {
[email protected]78cd68e2014-05-22 20:33:52282 const Extension* extension = AddExtension();
283 ASSERT_TRUE(extension);
284 NavigateAndCommit(GURL("https://www.google.com"));
285
286 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
287
288 const size_t kNumInjections = 3u;
289 // Queue multiple pending injections.
[email protected]23a85362014-07-07 23:26:19290 for (size_t i = 0u; i < kNumInjections; ++i)
291 RequestInjection(extension);
292
[email protected]78cd68e2014-05-22 20:33:52293 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
294
rdevlin.cronin4a78c48b2016-03-24 00:02:29295 runner()->RunForTesting(extension);
[email protected]78cd68e2014-05-22 20:33:52296
297 // All pending injections should have executed.
298 EXPECT_EQ(kNumInjections, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14299 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52300}
301
rdevlin.cronin8408b4f92016-03-15 19:14:14302TEST_F(ExtensionActionRunnerUnitTest, ActiveScriptsUseActiveTabPermissions) {
[email protected]78cd68e2014-05-22 20:33:52303 const Extension* extension = AddExtension();
304 NavigateAndCommit(GURL("https://www.google.com"));
305
306 ActiveTabPermissionGranter* active_tab_permission_granter =
307 TabHelper::FromWebContents(web_contents())
308 ->active_tab_permission_granter();
309 ASSERT_TRUE(active_tab_permission_granter);
310 // Grant the extension active tab permissions. This normally happens, e.g.,
311 // if the user clicks on a browser action.
312 active_tab_permission_granter->GrantIfRequested(extension);
313
314 // Since we have active tab permissions, we shouldn't need user consent
315 // anymore.
[email protected]23a85362014-07-07 23:26:19316 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52317
[email protected]4b8d1c62014-08-16 01:22:21318 // Reloading and other same-origin navigations maintain the permission to
319 // execute.
clamyf2053032017-10-20 16:01:59320 content::NavigationSimulator::Reload(web_contents());
[email protected]4b8d1c62014-08-16 01:22:21321 EXPECT_FALSE(RequiresUserConsent(extension));
322 NavigateAndCommit(GURL("https://www.google.com/foo"));
323 EXPECT_FALSE(RequiresUserConsent(extension));
324 NavigateAndCommit(GURL("https://www.google.com/bar"));
325 EXPECT_FALSE(RequiresUserConsent(extension));
326
327 // Navigating to a different origin will require user consent again.
328 NavigateAndCommit(GURL("https://yahoo.com"));
329 EXPECT_TRUE(RequiresUserConsent(extension));
330
331 // Back to the original origin should also re-require constent.
332 NavigateAndCommit(GURL("https://www.google.com"));
[email protected]23a85362014-07-07 23:26:19333 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]11814f52014-05-23 06:50:35334
[email protected]23a85362014-07-07 23:26:19335 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14336 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]11814f52014-05-23 06:50:35337 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
338
339 // Grant active tab.
340 active_tab_permission_granter->GrantIfRequested(extension);
341
342 // The pending injections should have run since active tab permission was
343 // granted.
344 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14345 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52346}
347
rdevlin.cronin8408b4f92016-03-15 19:14:14348TEST_F(ExtensionActionRunnerUnitTest, ActiveScriptsCanHaveAllUrlsPref) {
[email protected]b33c8c22014-05-29 19:51:08349 const Extension* extension = AddExtension();
350 ASSERT_TRUE(extension);
351
352 NavigateAndCommit(GURL("https://www.google.com"));
[email protected]23a85362014-07-07 23:26:19353 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08354
355 // Enable the extension on all urls.
rdevlin.cronind01837b2016-08-17 01:37:18356 ScriptingPermissionsModifier permissions_modifier(profile(), extension);
Devlin Croninc5830702018-07-03 00:26:16357 permissions_modifier.SetWithholdHostPermissions(false);
[email protected]b33c8c22014-05-29 19:51:08358
[email protected]23a85362014-07-07 23:26:19359 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08360 // This should carry across navigations, and websites.
361 NavigateAndCommit(GURL("http://www.foo.com"));
[email protected]23a85362014-07-07 23:26:19362 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08363
364 // Turning off the preference should have instant effect.
Devlin Croninc5830702018-07-03 00:26:16365 permissions_modifier.SetWithholdHostPermissions(true);
[email protected]23a85362014-07-07 23:26:19366 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08367
368 // And should also persist across navigations and websites.
369 NavigateAndCommit(GURL("http://www.bar.com"));
[email protected]23a85362014-07-07 23:26:19370 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08371}
372
rdevlin.cronin8408b4f92016-03-15 19:14:14373TEST_F(ExtensionActionRunnerUnitTest, TestAlwaysRun) {
[email protected]e1670582014-08-15 23:05:41374 const Extension* extension = AddExtension();
375 ASSERT_TRUE(extension);
376
377 NavigateAndCommit(GURL("https://www.google.com/?gws_rd=ssl"));
378
379 // Ensure that there aren't any executions pending.
380 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14381 ASSERT_FALSE(runner()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41382
383 // Since the extension requests all_hosts, we should require user consent.
384 EXPECT_TRUE(RequiresUserConsent(extension));
385
rdevlin.cronin91f162a12014-09-03 16:48:40386 // Request an injection. The extension should want to run, but not execute.
[email protected]e1670582014-08-15 23:05:41387 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14388 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41389 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
390
391 // Allow the extension to always run on this origin.
rdevlin.cronincb9f86e2015-10-15 15:13:42392 ScriptingPermissionsModifier modifier(profile(), extension);
393 modifier.GrantHostPermission(web_contents()->GetLastCommittedURL());
rdevlin.cronin4a78c48b2016-03-24 00:02:29394 runner()->RunForTesting(extension);
[email protected]e1670582014-08-15 23:05:41395
rdevlin.cronin91f162a12014-09-03 16:48:40396 // The extension should execute, and the extension shouldn't want to run.
[email protected]e1670582014-08-15 23:05:41397 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14398 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41399
400 // Since we already executed on the given page, we shouldn't need permission
401 // for a second time.
402 EXPECT_FALSE(RequiresUserConsent(extension));
403
404 // Navigating to another site that hasn't been granted a persisted permission
405 // should necessitate user consent.
406 NavigateAndCommit(GURL("https://www.foo.com/bar"));
407 EXPECT_TRUE(RequiresUserConsent(extension));
408
409 // We shouldn't need user permission upon returning to the original origin.
410 NavigateAndCommit(GURL("https://www.google.com/foo/bar"));
411 EXPECT_FALSE(RequiresUserConsent(extension));
412
413 // Reloading the extension should not clear any granted host permissions.
414 extension = ReloadExtension();
clamyf2053032017-10-20 16:01:59415 content::NavigationSimulator::Reload(web_contents());
[email protected]e1670582014-08-15 23:05:41416 EXPECT_FALSE(RequiresUserConsent(extension));
417
418 // Different host...
419 NavigateAndCommit(GURL("https://www.foo.com/bar"));
420 EXPECT_TRUE(RequiresUserConsent(extension));
421 // Different scheme...
422 NavigateAndCommit(GURL("http://www.google.com/foo/bar"));
423 EXPECT_TRUE(RequiresUserConsent(extension));
424 // Different subdomain...
425 NavigateAndCommit(GURL("https://en.google.com/foo/bar"));
426 EXPECT_TRUE(RequiresUserConsent(extension));
427 // Only the "always run" origin should be allowed to run without user consent.
428 NavigateAndCommit(GURL("https://www.google.com/foo/bar"));
429 EXPECT_FALSE(RequiresUserConsent(extension));
430}
431
rdevlin.cronin8408b4f92016-03-15 19:14:14432TEST_F(ExtensionActionRunnerUnitTest, TestDifferentScriptRunLocations) {
rdevlin.cronin8d034e52016-02-02 22:46:32433 const Extension* extension = AddExtension();
434 ASSERT_TRUE(extension);
435
436 NavigateAndCommit(GURL("https://www.foo.com"));
437
rdevlin.cronin8408b4f92016-03-15 19:14:14438 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32439
440 RequestInjection(extension, UserScript::DOCUMENT_END);
441 EXPECT_EQ(BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14442 runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32443 RequestInjection(extension, UserScript::DOCUMENT_IDLE);
444 EXPECT_EQ(BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14445 runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32446 RequestInjection(extension, UserScript::DOCUMENT_START);
447 EXPECT_EQ(BLOCKED_ACTION_SCRIPT_AT_START | BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14448 runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32449
rdevlin.cronin4a78c48b2016-03-24 00:02:29450 runner()->RunForTesting(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14451 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32452}
453
rdevlin.cronin8408b4f92016-03-15 19:14:14454TEST_F(ExtensionActionRunnerUnitTest, TestWebRequestBlocked) {
rdevlin.cronin8d034e52016-02-02 22:46:32455 const Extension* extension = AddExtension();
456 ASSERT_TRUE(extension);
457
458 NavigateAndCommit(GURL("https://www.foo.com"));
459
rdevlin.cronin8408b4f92016-03-15 19:14:14460 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
461 EXPECT_FALSE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32462
rdevlin.cronin8408b4f92016-03-15 19:14:14463 runner()->OnWebRequestBlocked(extension);
464 EXPECT_EQ(BLOCKED_ACTION_WEB_REQUEST, runner()->GetBlockedActions(extension));
465 EXPECT_TRUE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32466
467 RequestInjection(extension);
468 EXPECT_EQ(BLOCKED_ACTION_WEB_REQUEST | BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14469 runner()->GetBlockedActions(extension));
470 EXPECT_TRUE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32471
472 NavigateAndCommit(GURL("https://www.bar.com"));
rdevlin.cronin8408b4f92016-03-15 19:14:14473 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
474 EXPECT_FALSE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32475}
476
[email protected]78cd68e2014-05-22 20:33:52477} // namespace extensions