blob: 0be4201d33b8f8cf75416d88050a2bb2778ac3af [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
10#include "base/values.h"
[email protected]78cd68e2014-05-22 20:33:5211#include "chrome/browser/extensions/active_tab_permission_granter.h"
rdevlin.cronin699ca6ff2014-09-29 23:59:5712#include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
rdevlin.cronin8408b4f92016-03-15 19:14:1413#include "chrome/browser/extensions/extension_action_runner.h"
rdevlin.cronind1aa8522015-02-13 00:25:5714#include "chrome/browser/extensions/extension_sync_service_factory.h"
[email protected]23a85362014-07-07 23:26:1915#include "chrome/browser/extensions/permissions_updater.h"
rdevlin.cronincb9f86e2015-10-15 15:13:4216#include "chrome/browser/extensions/scripting_permissions_modifier.h"
[email protected]78cd68e2014-05-22 20:33:5217#include "chrome/browser/extensions/tab_helper.h"
18#include "chrome/test/base/chrome_render_view_host_test_harness.h"
19#include "chrome/test/base/testing_profile.h"
[email protected]fdd28372014-08-21 02:27:2620#include "components/crx_file/id_util.h"
[email protected]78cd68e2014-05-22 20:33:5221#include "content/public/browser/navigation_controller.h"
22#include "content/public/browser/navigation_entry.h"
23#include "content/public/browser/web_contents.h"
clamyf2053032017-10-20 16:01:5924#include "content/public/test/navigation_simulator.h"
[email protected]78cd68e2014-05-22 20:33:5225#include "extensions/browser/extension_registry.h"
26#include "extensions/common/extension.h"
27#include "extensions/common/extension_builder.h"
28#include "extensions/common/feature_switch.h"
29#include "extensions/common/manifest.h"
[email protected]23a85362014-07-07 23:26:1930#include "extensions/common/user_script.h"
[email protected]78cd68e2014-05-22 20:33:5231#include "extensions/common/value_builder.h"
32
33namespace extensions {
34
35namespace {
36
37const char kAllHostsPermission[] = "*://*/*";
38
39} // namespace
40
rdevlin.cronin8408b4f92016-03-15 19:14:1441// Unittests for the ExtensionActionRunner mostly test the internal logic
42// of the runner itself (when to allow/deny extension script injection).
[email protected]78cd68e2014-05-22 20:33:5243// Testing real injection is allowed/denied as expected (i.e., that the
rdevlin.cronin8408b4f92016-03-15 19:14:1444// ExtensionActionRunner correctly interfaces in the system) is done in the
45// ExtensionActionRunnerBrowserTests.
46class ExtensionActionRunnerUnitTest : public ChromeRenderViewHostTestHarness {
[email protected]78cd68e2014-05-22 20:33:5247 protected:
rdevlin.cronin8408b4f92016-03-15 19:14:1448 ExtensionActionRunnerUnitTest();
49 ~ExtensionActionRunnerUnitTest() override;
[email protected]78cd68e2014-05-22 20:33:5250
51 // Creates an extension with all hosts permission and adds it to the registry.
52 const Extension* AddExtension();
53
[email protected]e1670582014-08-15 23:05:4154 // Reloads |extension_| by removing it from the registry and recreating it.
55 const Extension* ReloadExtension();
56
[email protected]23a85362014-07-07 23:26:1957 // Returns true if the |extension| requires user consent before injecting
58 // a script.
59 bool RequiresUserConsent(const Extension* extension) const;
60
61 // Request an injection for the given |extension|.
62 void RequestInjection(const Extension* extension);
rdevlin.cronin8d034e52016-02-02 22:46:3263 void RequestInjection(const Extension* extension,
64 UserScript::RunLocation run_location);
[email protected]78cd68e2014-05-22 20:33:5265
66 // Returns the number of times a given extension has had a script execute.
67 size_t GetExecutionCountForExtension(const std::string& extension_id) const;
68
rdevlin.cronin8408b4f92016-03-15 19:14:1469 ExtensionActionRunner* runner() const { return extension_action_runner_; }
[email protected]78cd68e2014-05-22 20:33:5270
71 private:
[email protected]23a85362014-07-07 23:26:1972 // Returns a closure to use as a script execution for a given extension.
73 base::Closure GetExecutionCallbackForExtension(
74 const std::string& extension_id);
75
[email protected]78cd68e2014-05-22 20:33:5276 // Increment the number of executions for the given |extension_id|.
77 void IncrementExecutionCount(const std::string& extension_id);
78
dcheng72191812014-10-28 20:49:5679 void SetUp() override;
[email protected]78cd68e2014-05-22 20:33:5280
rdevlin.cronin8408b4f92016-03-15 19:14:1481 // Since ExtensionActionRunner's behavior is behind a flag, override the
[email protected]78cd68e2014-05-22 20:33:5282 // feature switch.
83 FeatureSwitch::ScopedOverride feature_override_;
84
rdevlin.cronin8408b4f92016-03-15 19:14:1485 // The associated ExtensionActionRunner.
86 ExtensionActionRunner* extension_action_runner_;
[email protected]78cd68e2014-05-22 20:33:5287
88 // The map of observed executions, keyed by extension id.
89 std::map<std::string, int> extension_executions_;
[email protected]e1670582014-08-15 23:05:4190
91 scoped_refptr<const Extension> extension_;
rdevlin.cronin8d034e52016-02-02 22:46:3292
rdevlin.cronin8408b4f92016-03-15 19:14:1493 DISALLOW_COPY_AND_ASSIGN(ExtensionActionRunnerUnitTest);
[email protected]78cd68e2014-05-22 20:33:5294};
95
rdevlin.cronin8408b4f92016-03-15 19:14:1496ExtensionActionRunnerUnitTest::ExtensionActionRunnerUnitTest()
[email protected]78cd68e2014-05-22 20:33:5297 : feature_override_(FeatureSwitch::scripts_require_action(),
98 FeatureSwitch::OVERRIDE_ENABLED),
rdevlin.cronin8408b4f92016-03-15 19:14:1499 extension_action_runner_(nullptr) {}
[email protected]78cd68e2014-05-22 20:33:52100
rdevlin.cronin8408b4f92016-03-15 19:14:14101ExtensionActionRunnerUnitTest::~ExtensionActionRunnerUnitTest() {}
[email protected]78cd68e2014-05-22 20:33:52102
rdevlin.cronin8408b4f92016-03-15 19:14:14103const Extension* ExtensionActionRunnerUnitTest::AddExtension() {
[email protected]fdd28372014-08-21 02:27:26104 const std::string kId = crx_file::id_util::GenerateId("all_hosts_extension");
limasdf3d102542015-12-09 03:58:45105 extension_ =
106 ExtensionBuilder()
dcheng794d2bd2016-02-27 03:51:32107 .SetManifest(
limasdf21d67e62015-12-19 12:04:49108 DictionaryBuilder()
109 .Set("name", "all_hosts_extension")
110 .Set("description", "an extension")
111 .Set("manifest_version", 2)
112 .Set("version", "1.0.0")
113 .Set("permissions",
dcheng794d2bd2016-02-27 03:51:32114 ListBuilder().Append(kAllHostsPermission).Build())
115 .Build())
limasdf3d102542015-12-09 03:58:45116 .SetLocation(Manifest::INTERNAL)
117 .SetID(kId)
118 .Build();
[email protected]78cd68e2014-05-22 20:33:52119
[email protected]e1670582014-08-15 23:05:41120 ExtensionRegistry::Get(profile())->AddEnabled(extension_);
dchengc7047942014-08-26 05:05:31121 PermissionsUpdater(profile()).InitializePermissions(extension_.get());
122 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 {
132 PermissionsData::AccessType 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.
136 DCHECK_NE(PermissionsData::ACCESS_DENIED, access_type);
137 return access_type == PermissionsData::ACCESS_WITHHELD;
138}
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
isherman30fa851a2015-06-09 23:32:10178 // Skip syncing for testing purposes.
179 ExtensionSyncServiceFactory::GetInstance()->SetTestingFactory(profile(),
180 nullptr);
rdevlin.cronind1aa8522015-02-13 00:25:57181
[email protected]78cd68e2014-05-22 20:33:52182 TabHelper::CreateForWebContents(web_contents());
183 TabHelper* tab_helper = TabHelper::FromWebContents(web_contents());
rdevlin.cronin8d034e52016-02-02 22:46:32184 // These should never be null.
[email protected]78cd68e2014-05-22 20:33:52185 DCHECK(tab_helper);
rdevlin.cronin8408b4f92016-03-15 19:14:14186 extension_action_runner_ = tab_helper->extension_action_runner();
187 DCHECK(extension_action_runner_);
[email protected]78cd68e2014-05-22 20:33:52188}
189
190// Test that extensions with all_hosts require permission to execute, and, once
191// that permission is granted, do execute.
rdevlin.cronin8408b4f92016-03-15 19:14:14192TEST_F(ExtensionActionRunnerUnitTest, RequestPermissionAndExecute) {
[email protected]78cd68e2014-05-22 20:33:52193 const Extension* extension = AddExtension();
194 ASSERT_TRUE(extension);
195
196 NavigateAndCommit(GURL("https://www.google.com"));
197
198 // Ensure that there aren't any executions pending.
199 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14200 ASSERT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52201
[email protected]78cd68e2014-05-22 20:33:52202 // Since the extension requests all_hosts, we should require user consent.
[email protected]23a85362014-07-07 23:26:19203 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52204
rdevlin.cronin91f162a12014-09-03 16:48:40205 // Request an injection. The extension should want to run, but should not have
206 // executed.
[email protected]23a85362014-07-07 23:26:19207 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14208 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52209 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
210
211 // Click to accept the extension executing.
rdevlin.cronin4a78c48b2016-03-24 00:02:29212 runner()->RunForTesting(extension);
[email protected]78cd68e2014-05-22 20:33:52213
rdevlin.cronin91f162a12014-09-03 16:48:40214 // The extension should execute, and the extension shouldn't want to run.
[email protected]78cd68e2014-05-22 20:33:52215 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14216 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52217
218 // Since we already executed on the given page, we shouldn't need permission
219 // for a second time.
[email protected]23a85362014-07-07 23:26:19220 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52221
[email protected]4b8d1c62014-08-16 01:22:21222 // Reloading and same-origin navigations shouldn't clear those permissions,
223 // and we shouldn't require user constent again.
clamyf2053032017-10-20 16:01:59224 content::NavigationSimulator::Reload(web_contents());
[email protected]4b8d1c62014-08-16 01:22:21225 EXPECT_FALSE(RequiresUserConsent(extension));
226 NavigateAndCommit(GURL("https://www.google.com/foo"));
227 EXPECT_FALSE(RequiresUserConsent(extension));
228 NavigateAndCommit(GURL("https://www.google.com/bar"));
229 EXPECT_FALSE(RequiresUserConsent(extension));
230
231 // Cross-origin navigations should clear permissions.
232 NavigateAndCommit(GURL("https://otherdomain.google.com"));
[email protected]23a85362014-07-07 23:26:19233 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52234
235 // Grant access.
[email protected]23a85362014-07-07 23:26:19236 RequestInjection(extension);
rdevlin.cronin4a78c48b2016-03-24 00:02:29237 runner()->RunForTesting(extension);
[email protected]78cd68e2014-05-22 20:33:52238 EXPECT_EQ(2u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14239 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52240
241 // Navigating to another site should also clear the permissions.
242 NavigateAndCommit(GURL("https://www.foo.com"));
[email protected]23a85362014-07-07 23:26:19243 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52244}
245
246// Test that injections that are not executed by the time the user navigates are
247// ignored and never execute.
rdevlin.cronin8408b4f92016-03-15 19:14:14248TEST_F(ExtensionActionRunnerUnitTest, PendingInjectionsRemovedAtNavigation) {
[email protected]78cd68e2014-05-22 20:33:52249 const Extension* extension = AddExtension();
250 ASSERT_TRUE(extension);
251
252 NavigateAndCommit(GURL("https://www.google.com"));
253
254 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
255
rdevlin.cronin91f162a12014-09-03 16:48:40256 // Request an injection. The extension should want to run, but not execute.
[email protected]23a85362014-07-07 23:26:19257 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14258 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52259 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
260
[email protected]8d5cb212014-06-04 09:00:39261 // Reload. This should remove the pending injection, and we should not
[email protected]78cd68e2014-05-22 20:33:52262 // execute anything.
clamyf2053032017-10-20 16:01:59263 content::NavigationSimulator::Reload(web_contents());
rdevlin.cronin8408b4f92016-03-15 19:14:14264 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52265 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
266
267 // Request and accept a new injection.
[email protected]23a85362014-07-07 23:26:19268 RequestInjection(extension);
rdevlin.cronin4a78c48b2016-03-24 00:02:29269 runner()->RunForTesting(extension);
[email protected]78cd68e2014-05-22 20:33:52270
271 // The extension should only have executed once, even though a grand total
272 // of two executions were requested.
273 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14274 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52275}
276
277// Test that queueing multiple pending injections, and then accepting, triggers
278// them all.
rdevlin.cronin8408b4f92016-03-15 19:14:14279TEST_F(ExtensionActionRunnerUnitTest, MultiplePendingInjection) {
[email protected]78cd68e2014-05-22 20:33:52280 const Extension* extension = AddExtension();
281 ASSERT_TRUE(extension);
282 NavigateAndCommit(GURL("https://www.google.com"));
283
284 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
285
286 const size_t kNumInjections = 3u;
287 // Queue multiple pending injections.
[email protected]23a85362014-07-07 23:26:19288 for (size_t i = 0u; i < kNumInjections; ++i)
289 RequestInjection(extension);
290
[email protected]78cd68e2014-05-22 20:33:52291 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
292
rdevlin.cronin4a78c48b2016-03-24 00:02:29293 runner()->RunForTesting(extension);
[email protected]78cd68e2014-05-22 20:33:52294
295 // All pending injections should have executed.
296 EXPECT_EQ(kNumInjections, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14297 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52298}
299
rdevlin.cronin8408b4f92016-03-15 19:14:14300TEST_F(ExtensionActionRunnerUnitTest, ActiveScriptsUseActiveTabPermissions) {
[email protected]78cd68e2014-05-22 20:33:52301 const Extension* extension = AddExtension();
302 NavigateAndCommit(GURL("https://www.google.com"));
303
304 ActiveTabPermissionGranter* active_tab_permission_granter =
305 TabHelper::FromWebContents(web_contents())
306 ->active_tab_permission_granter();
307 ASSERT_TRUE(active_tab_permission_granter);
308 // Grant the extension active tab permissions. This normally happens, e.g.,
309 // if the user clicks on a browser action.
310 active_tab_permission_granter->GrantIfRequested(extension);
311
312 // Since we have active tab permissions, we shouldn't need user consent
313 // anymore.
[email protected]23a85362014-07-07 23:26:19314 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52315
[email protected]4b8d1c62014-08-16 01:22:21316 // Reloading and other same-origin navigations maintain the permission to
317 // execute.
clamyf2053032017-10-20 16:01:59318 content::NavigationSimulator::Reload(web_contents());
[email protected]4b8d1c62014-08-16 01:22:21319 EXPECT_FALSE(RequiresUserConsent(extension));
320 NavigateAndCommit(GURL("https://www.google.com/foo"));
321 EXPECT_FALSE(RequiresUserConsent(extension));
322 NavigateAndCommit(GURL("https://www.google.com/bar"));
323 EXPECT_FALSE(RequiresUserConsent(extension));
324
325 // Navigating to a different origin will require user consent again.
326 NavigateAndCommit(GURL("https://yahoo.com"));
327 EXPECT_TRUE(RequiresUserConsent(extension));
328
329 // Back to the original origin should also re-require constent.
330 NavigateAndCommit(GURL("https://www.google.com"));
[email protected]23a85362014-07-07 23:26:19331 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]11814f52014-05-23 06:50:35332
[email protected]23a85362014-07-07 23:26:19333 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14334 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]11814f52014-05-23 06:50:35335 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
336
337 // Grant active tab.
338 active_tab_permission_granter->GrantIfRequested(extension);
339
340 // The pending injections should have run since active tab permission was
341 // granted.
342 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14343 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52344}
345
rdevlin.cronin8408b4f92016-03-15 19:14:14346TEST_F(ExtensionActionRunnerUnitTest, ActiveScriptsCanHaveAllUrlsPref) {
[email protected]b33c8c22014-05-29 19:51:08347 const Extension* extension = AddExtension();
348 ASSERT_TRUE(extension);
349
350 NavigateAndCommit(GURL("https://www.google.com"));
[email protected]23a85362014-07-07 23:26:19351 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08352
353 // Enable the extension on all urls.
rdevlin.cronind01837b2016-08-17 01:37:18354 ScriptingPermissionsModifier permissions_modifier(profile(), extension);
355 permissions_modifier.SetAllowedOnAllUrls(true);
[email protected]b33c8c22014-05-29 19:51:08356
[email protected]23a85362014-07-07 23:26:19357 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08358 // This should carry across navigations, and websites.
359 NavigateAndCommit(GURL("http://www.foo.com"));
[email protected]23a85362014-07-07 23:26:19360 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08361
362 // Turning off the preference should have instant effect.
rdevlin.cronind01837b2016-08-17 01:37:18363 permissions_modifier.SetAllowedOnAllUrls(false);
[email protected]23a85362014-07-07 23:26:19364 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08365
366 // And should also persist across navigations and websites.
367 NavigateAndCommit(GURL("http://www.bar.com"));
[email protected]23a85362014-07-07 23:26:19368 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08369}
370
rdevlin.cronin8408b4f92016-03-15 19:14:14371TEST_F(ExtensionActionRunnerUnitTest, TestAlwaysRun) {
[email protected]e1670582014-08-15 23:05:41372 const Extension* extension = AddExtension();
373 ASSERT_TRUE(extension);
374
375 NavigateAndCommit(GURL("https://www.google.com/?gws_rd=ssl"));
376
377 // Ensure that there aren't any executions pending.
378 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14379 ASSERT_FALSE(runner()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41380
381 // Since the extension requests all_hosts, we should require user consent.
382 EXPECT_TRUE(RequiresUserConsent(extension));
383
rdevlin.cronin91f162a12014-09-03 16:48:40384 // Request an injection. The extension should want to run, but not execute.
[email protected]e1670582014-08-15 23:05:41385 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14386 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41387 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
388
389 // Allow the extension to always run on this origin.
rdevlin.cronincb9f86e2015-10-15 15:13:42390 ScriptingPermissionsModifier modifier(profile(), extension);
391 modifier.GrantHostPermission(web_contents()->GetLastCommittedURL());
rdevlin.cronin4a78c48b2016-03-24 00:02:29392 runner()->RunForTesting(extension);
[email protected]e1670582014-08-15 23:05:41393
rdevlin.cronin91f162a12014-09-03 16:48:40394 // The extension should execute, and the extension shouldn't want to run.
[email protected]e1670582014-08-15 23:05:41395 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14396 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41397
398 // Since we already executed on the given page, we shouldn't need permission
399 // for a second time.
400 EXPECT_FALSE(RequiresUserConsent(extension));
401
402 // Navigating to another site that hasn't been granted a persisted permission
403 // should necessitate user consent.
404 NavigateAndCommit(GURL("https://www.foo.com/bar"));
405 EXPECT_TRUE(RequiresUserConsent(extension));
406
407 // We shouldn't need user permission upon returning to the original origin.
408 NavigateAndCommit(GURL("https://www.google.com/foo/bar"));
409 EXPECT_FALSE(RequiresUserConsent(extension));
410
411 // Reloading the extension should not clear any granted host permissions.
412 extension = ReloadExtension();
clamyf2053032017-10-20 16:01:59413 content::NavigationSimulator::Reload(web_contents());
[email protected]e1670582014-08-15 23:05:41414 EXPECT_FALSE(RequiresUserConsent(extension));
415
416 // Different host...
417 NavigateAndCommit(GURL("https://www.foo.com/bar"));
418 EXPECT_TRUE(RequiresUserConsent(extension));
419 // Different scheme...
420 NavigateAndCommit(GURL("http://www.google.com/foo/bar"));
421 EXPECT_TRUE(RequiresUserConsent(extension));
422 // Different subdomain...
423 NavigateAndCommit(GURL("https://en.google.com/foo/bar"));
424 EXPECT_TRUE(RequiresUserConsent(extension));
425 // Only the "always run" origin should be allowed to run without user consent.
426 NavigateAndCommit(GURL("https://www.google.com/foo/bar"));
427 EXPECT_FALSE(RequiresUserConsent(extension));
428}
429
rdevlin.cronin8408b4f92016-03-15 19:14:14430TEST_F(ExtensionActionRunnerUnitTest, TestDifferentScriptRunLocations) {
rdevlin.cronin8d034e52016-02-02 22:46:32431 const Extension* extension = AddExtension();
432 ASSERT_TRUE(extension);
433
434 NavigateAndCommit(GURL("https://www.foo.com"));
435
rdevlin.cronin8408b4f92016-03-15 19:14:14436 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32437
438 RequestInjection(extension, UserScript::DOCUMENT_END);
439 EXPECT_EQ(BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14440 runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32441 RequestInjection(extension, UserScript::DOCUMENT_IDLE);
442 EXPECT_EQ(BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14443 runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32444 RequestInjection(extension, UserScript::DOCUMENT_START);
445 EXPECT_EQ(BLOCKED_ACTION_SCRIPT_AT_START | BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14446 runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32447
rdevlin.cronin4a78c48b2016-03-24 00:02:29448 runner()->RunForTesting(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14449 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32450}
451
rdevlin.cronin8408b4f92016-03-15 19:14:14452TEST_F(ExtensionActionRunnerUnitTest, TestWebRequestBlocked) {
rdevlin.cronin8d034e52016-02-02 22:46:32453 const Extension* extension = AddExtension();
454 ASSERT_TRUE(extension);
455
456 NavigateAndCommit(GURL("https://www.foo.com"));
457
rdevlin.cronin8408b4f92016-03-15 19:14:14458 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
459 EXPECT_FALSE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32460
rdevlin.cronin8408b4f92016-03-15 19:14:14461 runner()->OnWebRequestBlocked(extension);
462 EXPECT_EQ(BLOCKED_ACTION_WEB_REQUEST, runner()->GetBlockedActions(extension));
463 EXPECT_TRUE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32464
465 RequestInjection(extension);
466 EXPECT_EQ(BLOCKED_ACTION_WEB_REQUEST | BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14467 runner()->GetBlockedActions(extension));
468 EXPECT_TRUE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32469
470 NavigateAndCommit(GURL("https://www.bar.com"));
rdevlin.cronin8408b4f92016-03-15 19:14:14471 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
472 EXPECT_FALSE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32473}
474
[email protected]78cd68e2014-05-22 20:33:52475} // namespace extensions