blob: 0edd6e0b43060638a1b49cf03c28fb55833d6e95 [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());
119 return extension_.get();
[email protected]e1670582014-08-15 23:05:41120}
121
rdevlin.cronin8408b4f92016-03-15 19:14:14122const Extension* ExtensionActionRunnerUnitTest::ReloadExtension() {
[email protected]e1670582014-08-15 23:05:41123 ExtensionRegistry::Get(profile())->RemoveEnabled(extension_->id());
124 return AddExtension();
[email protected]78cd68e2014-05-22 20:33:52125}
126
rdevlin.cronin8408b4f92016-03-15 19:14:14127bool ExtensionActionRunnerUnitTest::RequiresUserConsent(
[email protected]23a85362014-07-07 23:26:19128 const Extension* extension) const {
Devlin Cronin3e532b82018-05-03 21:27:19129 PermissionsData::PageAccess access_type =
rdevlin.cronin8408b4f92016-03-15 19:14:14130 runner()->RequiresUserConsentForScriptInjectionForTesting(
[email protected]23a85362014-07-07 23:26:19131 extension, UserScript::PROGRAMMATIC_SCRIPT);
132 // We should never downright refuse access in these tests.
Devlin Cronin3e532b82018-05-03 21:27:19133 DCHECK_NE(PermissionsData::PageAccess::kDenied, access_type);
134 return access_type == PermissionsData::PageAccess::kWithheld;
[email protected]23a85362014-07-07 23:26:19135}
136
rdevlin.cronin8408b4f92016-03-15 19:14:14137void ExtensionActionRunnerUnitTest::RequestInjection(
[email protected]23a85362014-07-07 23:26:19138 const Extension* extension) {
rdevlin.cronin8d034e52016-02-02 22:46:32139 RequestInjection(extension, UserScript::DOCUMENT_IDLE);
140}
141
rdevlin.cronin8408b4f92016-03-15 19:14:14142void ExtensionActionRunnerUnitTest::RequestInjection(
rdevlin.cronin8d034e52016-02-02 22:46:32143 const Extension* extension,
144 UserScript::RunLocation run_location) {
rdevlin.cronin8408b4f92016-03-15 19:14:14145 runner()->RequestScriptInjectionForTesting(
rdevlin.cronin8d034e52016-02-02 22:46:32146 extension, run_location,
[email protected]23a85362014-07-07 23:26:19147 GetExecutionCallbackForExtension(extension->id()));
[email protected]78cd68e2014-05-22 20:33:52148}
149
rdevlin.cronin8408b4f92016-03-15 19:14:14150size_t ExtensionActionRunnerUnitTest::GetExecutionCountForExtension(
[email protected]78cd68e2014-05-22 20:33:52151 const std::string& extension_id) const {
152 std::map<std::string, int>::const_iterator iter =
153 extension_executions_.find(extension_id);
154 if (iter != extension_executions_.end())
155 return iter->second;
156 return 0u;
157}
158
rdevlin.cronin8408b4f92016-03-15 19:14:14159base::Closure ExtensionActionRunnerUnitTest::GetExecutionCallbackForExtension(
[email protected]23a85362014-07-07 23:26:19160 const std::string& extension_id) {
161 // We use base unretained here, but if this ever gets executed outside of
162 // this test's lifetime, we have a major problem anyway.
rdevlin.cronin8408b4f92016-03-15 19:14:14163 return base::Bind(&ExtensionActionRunnerUnitTest::IncrementExecutionCount,
164 base::Unretained(this), extension_id);
[email protected]23a85362014-07-07 23:26:19165}
166
rdevlin.cronin8408b4f92016-03-15 19:14:14167void ExtensionActionRunnerUnitTest::IncrementExecutionCount(
[email protected]78cd68e2014-05-22 20:33:52168 const std::string& extension_id) {
169 ++extension_executions_[extension_id];
170}
171
rdevlin.cronin8408b4f92016-03-15 19:14:14172void ExtensionActionRunnerUnitTest::SetUp() {
[email protected]78cd68e2014-05-22 20:33:52173 ChromeRenderViewHostTestHarness::SetUp();
174
Devlin Cronincac45cb2018-04-25 04:43:03175 scoped_feature_list_.InitAndEnableFeature(features::kRuntimeHostPermissions);
176
isherman30fa851a2015-06-09 23:32:10177 // Skip syncing for testing purposes.
178 ExtensionSyncServiceFactory::GetInstance()->SetTestingFactory(profile(),
179 nullptr);
rdevlin.cronind1aa8522015-02-13 00:25:57180
[email protected]78cd68e2014-05-22 20:33:52181 TabHelper::CreateForWebContents(web_contents());
182 TabHelper* tab_helper = TabHelper::FromWebContents(web_contents());
rdevlin.cronin8d034e52016-02-02 22:46:32183 // These should never be null.
[email protected]78cd68e2014-05-22 20:33:52184 DCHECK(tab_helper);
rdevlin.cronin8408b4f92016-03-15 19:14:14185 extension_action_runner_ = tab_helper->extension_action_runner();
186 DCHECK(extension_action_runner_);
[email protected]78cd68e2014-05-22 20:33:52187}
188
189// Test that extensions with all_hosts require permission to execute, and, once
190// that permission is granted, do execute.
rdevlin.cronin8408b4f92016-03-15 19:14:14191TEST_F(ExtensionActionRunnerUnitTest, RequestPermissionAndExecute) {
[email protected]78cd68e2014-05-22 20:33:52192 const Extension* extension = AddExtension();
193 ASSERT_TRUE(extension);
194
195 NavigateAndCommit(GURL("https://www.google.com"));
196
197 // Ensure that there aren't any executions pending.
198 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14199 ASSERT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52200
[email protected]78cd68e2014-05-22 20:33:52201 // Since the extension requests all_hosts, we should require user consent.
[email protected]23a85362014-07-07 23:26:19202 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52203
rdevlin.cronin91f162a12014-09-03 16:48:40204 // Request an injection. The extension should want to run, but should not have
205 // executed.
[email protected]23a85362014-07-07 23:26:19206 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14207 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52208 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
209
210 // Click to accept the extension executing.
rdevlin.cronin4a78c48b2016-03-24 00:02:29211 runner()->RunForTesting(extension);
[email protected]78cd68e2014-05-22 20:33:52212
rdevlin.cronin91f162a12014-09-03 16:48:40213 // The extension should execute, and the extension shouldn't want to run.
[email protected]78cd68e2014-05-22 20:33:52214 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14215 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52216
217 // Since we already executed on the given page, we shouldn't need permission
218 // for a second time.
[email protected]23a85362014-07-07 23:26:19219 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52220
[email protected]4b8d1c62014-08-16 01:22:21221 // Reloading and same-origin navigations shouldn't clear those permissions,
222 // and we shouldn't require user constent again.
clamyf2053032017-10-20 16:01:59223 content::NavigationSimulator::Reload(web_contents());
[email protected]4b8d1c62014-08-16 01:22:21224 EXPECT_FALSE(RequiresUserConsent(extension));
225 NavigateAndCommit(GURL("https://www.google.com/foo"));
226 EXPECT_FALSE(RequiresUserConsent(extension));
227 NavigateAndCommit(GURL("https://www.google.com/bar"));
228 EXPECT_FALSE(RequiresUserConsent(extension));
229
230 // Cross-origin navigations should clear permissions.
231 NavigateAndCommit(GURL("https://otherdomain.google.com"));
[email protected]23a85362014-07-07 23:26:19232 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52233
234 // Grant access.
[email protected]23a85362014-07-07 23:26:19235 RequestInjection(extension);
rdevlin.cronin4a78c48b2016-03-24 00:02:29236 runner()->RunForTesting(extension);
[email protected]78cd68e2014-05-22 20:33:52237 EXPECT_EQ(2u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14238 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52239
240 // Navigating to another site should also clear the permissions.
241 NavigateAndCommit(GURL("https://www.foo.com"));
[email protected]23a85362014-07-07 23:26:19242 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52243}
244
245// Test that injections that are not executed by the time the user navigates are
246// ignored and never execute.
rdevlin.cronin8408b4f92016-03-15 19:14:14247TEST_F(ExtensionActionRunnerUnitTest, PendingInjectionsRemovedAtNavigation) {
[email protected]78cd68e2014-05-22 20:33:52248 const Extension* extension = AddExtension();
249 ASSERT_TRUE(extension);
250
251 NavigateAndCommit(GURL("https://www.google.com"));
252
253 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
254
rdevlin.cronin91f162a12014-09-03 16:48:40255 // Request an injection. The extension should want to run, but not execute.
[email protected]23a85362014-07-07 23:26:19256 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14257 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52258 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
259
[email protected]8d5cb212014-06-04 09:00:39260 // Reload. This should remove the pending injection, and we should not
[email protected]78cd68e2014-05-22 20:33:52261 // execute anything.
clamyf2053032017-10-20 16:01:59262 content::NavigationSimulator::Reload(web_contents());
rdevlin.cronin8408b4f92016-03-15 19:14:14263 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52264 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
265
266 // Request and accept a new injection.
[email protected]23a85362014-07-07 23:26:19267 RequestInjection(extension);
rdevlin.cronin4a78c48b2016-03-24 00:02:29268 runner()->RunForTesting(extension);
[email protected]78cd68e2014-05-22 20:33:52269
270 // The extension should only have executed once, even though a grand total
271 // of two executions were requested.
272 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14273 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52274}
275
276// Test that queueing multiple pending injections, and then accepting, triggers
277// them all.
rdevlin.cronin8408b4f92016-03-15 19:14:14278TEST_F(ExtensionActionRunnerUnitTest, MultiplePendingInjection) {
[email protected]78cd68e2014-05-22 20:33:52279 const Extension* extension = AddExtension();
280 ASSERT_TRUE(extension);
281 NavigateAndCommit(GURL("https://www.google.com"));
282
283 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
284
285 const size_t kNumInjections = 3u;
286 // Queue multiple pending injections.
[email protected]23a85362014-07-07 23:26:19287 for (size_t i = 0u; i < kNumInjections; ++i)
288 RequestInjection(extension);
289
[email protected]78cd68e2014-05-22 20:33:52290 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
291
rdevlin.cronin4a78c48b2016-03-24 00:02:29292 runner()->RunForTesting(extension);
[email protected]78cd68e2014-05-22 20:33:52293
294 // All pending injections should have executed.
295 EXPECT_EQ(kNumInjections, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14296 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52297}
298
rdevlin.cronin8408b4f92016-03-15 19:14:14299TEST_F(ExtensionActionRunnerUnitTest, ActiveScriptsUseActiveTabPermissions) {
[email protected]78cd68e2014-05-22 20:33:52300 const Extension* extension = AddExtension();
301 NavigateAndCommit(GURL("https://www.google.com"));
302
303 ActiveTabPermissionGranter* active_tab_permission_granter =
304 TabHelper::FromWebContents(web_contents())
305 ->active_tab_permission_granter();
306 ASSERT_TRUE(active_tab_permission_granter);
307 // Grant the extension active tab permissions. This normally happens, e.g.,
308 // if the user clicks on a browser action.
309 active_tab_permission_granter->GrantIfRequested(extension);
310
311 // Since we have active tab permissions, we shouldn't need user consent
312 // anymore.
[email protected]23a85362014-07-07 23:26:19313 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52314
[email protected]4b8d1c62014-08-16 01:22:21315 // Reloading and other same-origin navigations maintain the permission to
316 // execute.
clamyf2053032017-10-20 16:01:59317 content::NavigationSimulator::Reload(web_contents());
[email protected]4b8d1c62014-08-16 01:22:21318 EXPECT_FALSE(RequiresUserConsent(extension));
319 NavigateAndCommit(GURL("https://www.google.com/foo"));
320 EXPECT_FALSE(RequiresUserConsent(extension));
321 NavigateAndCommit(GURL("https://www.google.com/bar"));
322 EXPECT_FALSE(RequiresUserConsent(extension));
323
324 // Navigating to a different origin will require user consent again.
325 NavigateAndCommit(GURL("https://yahoo.com"));
326 EXPECT_TRUE(RequiresUserConsent(extension));
327
328 // Back to the original origin should also re-require constent.
329 NavigateAndCommit(GURL("https://www.google.com"));
[email protected]23a85362014-07-07 23:26:19330 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]11814f52014-05-23 06:50:35331
[email protected]23a85362014-07-07 23:26:19332 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14333 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]11814f52014-05-23 06:50:35334 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
335
336 // Grant active tab.
337 active_tab_permission_granter->GrantIfRequested(extension);
338
339 // The pending injections should have run since active tab permission was
340 // granted.
341 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14342 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52343}
344
rdevlin.cronin8408b4f92016-03-15 19:14:14345TEST_F(ExtensionActionRunnerUnitTest, ActiveScriptsCanHaveAllUrlsPref) {
[email protected]b33c8c22014-05-29 19:51:08346 const Extension* extension = AddExtension();
347 ASSERT_TRUE(extension);
348
349 NavigateAndCommit(GURL("https://www.google.com"));
[email protected]23a85362014-07-07 23:26:19350 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08351
352 // Enable the extension on all urls.
rdevlin.cronind01837b2016-08-17 01:37:18353 ScriptingPermissionsModifier permissions_modifier(profile(), extension);
354 permissions_modifier.SetAllowedOnAllUrls(true);
[email protected]b33c8c22014-05-29 19:51:08355
[email protected]23a85362014-07-07 23:26:19356 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08357 // This should carry across navigations, and websites.
358 NavigateAndCommit(GURL("http://www.foo.com"));
[email protected]23a85362014-07-07 23:26:19359 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08360
361 // Turning off the preference should have instant effect.
rdevlin.cronind01837b2016-08-17 01:37:18362 permissions_modifier.SetAllowedOnAllUrls(false);
[email protected]23a85362014-07-07 23:26:19363 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08364
365 // And should also persist across navigations and websites.
366 NavigateAndCommit(GURL("http://www.bar.com"));
[email protected]23a85362014-07-07 23:26:19367 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08368}
369
rdevlin.cronin8408b4f92016-03-15 19:14:14370TEST_F(ExtensionActionRunnerUnitTest, TestAlwaysRun) {
[email protected]e1670582014-08-15 23:05:41371 const Extension* extension = AddExtension();
372 ASSERT_TRUE(extension);
373
374 NavigateAndCommit(GURL("https://www.google.com/?gws_rd=ssl"));
375
376 // Ensure that there aren't any executions pending.
377 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14378 ASSERT_FALSE(runner()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41379
380 // Since the extension requests all_hosts, we should require user consent.
381 EXPECT_TRUE(RequiresUserConsent(extension));
382
rdevlin.cronin91f162a12014-09-03 16:48:40383 // Request an injection. The extension should want to run, but not execute.
[email protected]e1670582014-08-15 23:05:41384 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14385 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41386 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
387
388 // Allow the extension to always run on this origin.
rdevlin.cronincb9f86e2015-10-15 15:13:42389 ScriptingPermissionsModifier modifier(profile(), extension);
390 modifier.GrantHostPermission(web_contents()->GetLastCommittedURL());
rdevlin.cronin4a78c48b2016-03-24 00:02:29391 runner()->RunForTesting(extension);
[email protected]e1670582014-08-15 23:05:41392
rdevlin.cronin91f162a12014-09-03 16:48:40393 // The extension should execute, and the extension shouldn't want to run.
[email protected]e1670582014-08-15 23:05:41394 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14395 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41396
397 // Since we already executed on the given page, we shouldn't need permission
398 // for a second time.
399 EXPECT_FALSE(RequiresUserConsent(extension));
400
401 // Navigating to another site that hasn't been granted a persisted permission
402 // should necessitate user consent.
403 NavigateAndCommit(GURL("https://www.foo.com/bar"));
404 EXPECT_TRUE(RequiresUserConsent(extension));
405
406 // We shouldn't need user permission upon returning to the original origin.
407 NavigateAndCommit(GURL("https://www.google.com/foo/bar"));
408 EXPECT_FALSE(RequiresUserConsent(extension));
409
410 // Reloading the extension should not clear any granted host permissions.
411 extension = ReloadExtension();
clamyf2053032017-10-20 16:01:59412 content::NavigationSimulator::Reload(web_contents());
[email protected]e1670582014-08-15 23:05:41413 EXPECT_FALSE(RequiresUserConsent(extension));
414
415 // Different host...
416 NavigateAndCommit(GURL("https://www.foo.com/bar"));
417 EXPECT_TRUE(RequiresUserConsent(extension));
418 // Different scheme...
419 NavigateAndCommit(GURL("http://www.google.com/foo/bar"));
420 EXPECT_TRUE(RequiresUserConsent(extension));
421 // Different subdomain...
422 NavigateAndCommit(GURL("https://en.google.com/foo/bar"));
423 EXPECT_TRUE(RequiresUserConsent(extension));
424 // Only the "always run" origin should be allowed to run without user consent.
425 NavigateAndCommit(GURL("https://www.google.com/foo/bar"));
426 EXPECT_FALSE(RequiresUserConsent(extension));
427}
428
rdevlin.cronin8408b4f92016-03-15 19:14:14429TEST_F(ExtensionActionRunnerUnitTest, TestDifferentScriptRunLocations) {
rdevlin.cronin8d034e52016-02-02 22:46:32430 const Extension* extension = AddExtension();
431 ASSERT_TRUE(extension);
432
433 NavigateAndCommit(GURL("https://www.foo.com"));
434
rdevlin.cronin8408b4f92016-03-15 19:14:14435 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32436
437 RequestInjection(extension, UserScript::DOCUMENT_END);
438 EXPECT_EQ(BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14439 runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32440 RequestInjection(extension, UserScript::DOCUMENT_IDLE);
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_START);
444 EXPECT_EQ(BLOCKED_ACTION_SCRIPT_AT_START | BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14445 runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32446
rdevlin.cronin4a78c48b2016-03-24 00:02:29447 runner()->RunForTesting(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14448 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32449}
450
rdevlin.cronin8408b4f92016-03-15 19:14:14451TEST_F(ExtensionActionRunnerUnitTest, TestWebRequestBlocked) {
rdevlin.cronin8d034e52016-02-02 22:46:32452 const Extension* extension = AddExtension();
453 ASSERT_TRUE(extension);
454
455 NavigateAndCommit(GURL("https://www.foo.com"));
456
rdevlin.cronin8408b4f92016-03-15 19:14:14457 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
458 EXPECT_FALSE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32459
rdevlin.cronin8408b4f92016-03-15 19:14:14460 runner()->OnWebRequestBlocked(extension);
461 EXPECT_EQ(BLOCKED_ACTION_WEB_REQUEST, runner()->GetBlockedActions(extension));
462 EXPECT_TRUE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32463
464 RequestInjection(extension);
465 EXPECT_EQ(BLOCKED_ACTION_WEB_REQUEST | BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14466 runner()->GetBlockedActions(extension));
467 EXPECT_TRUE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32468
469 NavigateAndCommit(GURL("https://www.bar.com"));
rdevlin.cronin8408b4f92016-03-15 19:14:14470 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
471 EXPECT_FALSE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32472}
473
[email protected]78cd68e2014-05-22 20:33:52474} // namespace extensions