blob: badade8995aee09d45a681273fe63b2f42ab3621 [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]b33c8c22014-05-29 19:51:0815#include "chrome/browser/extensions/extension_util.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"
25#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
rdevlin.cronin8408b4f92016-03-15 19:14:14202 ExtensionActionAPI* extension_action_api = ExtensionActionAPI::Get(profile());
rdevlin.cronind1331242016-02-05 19:18:51203 ASSERT_FALSE(extension_action_api->HasBeenBlocked(extension, web_contents()));
rdevlin.cronin699ca6ff2014-09-29 23:59:57204
[email protected]78cd68e2014-05-22 20:33:52205 // Since the extension requests all_hosts, we should require user consent.
[email protected]23a85362014-07-07 23:26:19206 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52207
rdevlin.cronin91f162a12014-09-03 16:48:40208 // Request an injection. The extension should want to run, but should not have
209 // executed.
[email protected]23a85362014-07-07 23:26:19210 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14211 EXPECT_TRUE(runner()->WantsToRun(extension));
rdevlin.cronind1331242016-02-05 19:18:51212 EXPECT_TRUE(extension_action_api->HasBeenBlocked(extension, web_contents()));
[email protected]78cd68e2014-05-22 20:33:52213 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
214
215 // Click to accept the extension executing.
rdevlin.cronin8408b4f92016-03-15 19:14:14216 runner()->OnClicked(extension);
[email protected]78cd68e2014-05-22 20:33:52217
rdevlin.cronin91f162a12014-09-03 16:48:40218 // The extension should execute, and the extension shouldn't want to run.
[email protected]78cd68e2014-05-22 20:33:52219 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14220 EXPECT_FALSE(runner()->WantsToRun(extension));
rdevlin.cronind1331242016-02-05 19:18:51221 EXPECT_FALSE(extension_action_api->HasBeenBlocked(extension, web_contents()));
[email protected]78cd68e2014-05-22 20:33:52222
223 // Since we already executed on the given page, we shouldn't need permission
224 // for a second time.
[email protected]23a85362014-07-07 23:26:19225 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52226
[email protected]4b8d1c62014-08-16 01:22:21227 // Reloading and same-origin navigations shouldn't clear those permissions,
228 // and we shouldn't require user constent again.
[email protected]78cd68e2014-05-22 20:33:52229 Reload();
[email protected]4b8d1c62014-08-16 01:22:21230 EXPECT_FALSE(RequiresUserConsent(extension));
231 NavigateAndCommit(GURL("https://www.google.com/foo"));
232 EXPECT_FALSE(RequiresUserConsent(extension));
233 NavigateAndCommit(GURL("https://www.google.com/bar"));
234 EXPECT_FALSE(RequiresUserConsent(extension));
235
236 // Cross-origin navigations should clear permissions.
237 NavigateAndCommit(GURL("https://otherdomain.google.com"));
[email protected]23a85362014-07-07 23:26:19238 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52239
240 // Grant access.
[email protected]23a85362014-07-07 23:26:19241 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14242 runner()->OnClicked(extension);
[email protected]78cd68e2014-05-22 20:33:52243 EXPECT_EQ(2u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14244 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52245
246 // Navigating to another site should also clear the permissions.
247 NavigateAndCommit(GURL("https://www.foo.com"));
[email protected]23a85362014-07-07 23:26:19248 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52249}
250
251// Test that injections that are not executed by the time the user navigates are
252// ignored and never execute.
rdevlin.cronin8408b4f92016-03-15 19:14:14253TEST_F(ExtensionActionRunnerUnitTest, PendingInjectionsRemovedAtNavigation) {
[email protected]78cd68e2014-05-22 20:33:52254 const Extension* extension = AddExtension();
255 ASSERT_TRUE(extension);
256
257 NavigateAndCommit(GURL("https://www.google.com"));
258
259 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
260
rdevlin.cronin91f162a12014-09-03 16:48:40261 // Request an injection. The extension should want to run, but not execute.
[email protected]23a85362014-07-07 23:26:19262 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14263 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52264 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
265
[email protected]8d5cb212014-06-04 09:00:39266 // Reload. This should remove the pending injection, and we should not
[email protected]78cd68e2014-05-22 20:33:52267 // execute anything.
[email protected]8d5cb212014-06-04 09:00:39268 Reload();
rdevlin.cronin8408b4f92016-03-15 19:14:14269 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52270 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
271
272 // Request and accept a new injection.
[email protected]23a85362014-07-07 23:26:19273 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14274 runner()->OnClicked(extension);
[email protected]78cd68e2014-05-22 20:33:52275
276 // The extension should only have executed once, even though a grand total
277 // of two executions were requested.
278 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14279 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52280}
281
282// Test that queueing multiple pending injections, and then accepting, triggers
283// them all.
rdevlin.cronin8408b4f92016-03-15 19:14:14284TEST_F(ExtensionActionRunnerUnitTest, MultiplePendingInjection) {
[email protected]78cd68e2014-05-22 20:33:52285 const Extension* extension = AddExtension();
286 ASSERT_TRUE(extension);
287 NavigateAndCommit(GURL("https://www.google.com"));
288
289 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
290
291 const size_t kNumInjections = 3u;
292 // Queue multiple pending injections.
[email protected]23a85362014-07-07 23:26:19293 for (size_t i = 0u; i < kNumInjections; ++i)
294 RequestInjection(extension);
295
[email protected]78cd68e2014-05-22 20:33:52296 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
297
rdevlin.cronin8408b4f92016-03-15 19:14:14298 runner()->OnClicked(extension);
[email protected]78cd68e2014-05-22 20:33:52299
300 // All pending injections should have executed.
301 EXPECT_EQ(kNumInjections, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14302 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52303}
304
rdevlin.cronin8408b4f92016-03-15 19:14:14305TEST_F(ExtensionActionRunnerUnitTest, ActiveScriptsUseActiveTabPermissions) {
[email protected]78cd68e2014-05-22 20:33:52306 const Extension* extension = AddExtension();
307 NavigateAndCommit(GURL("https://www.google.com"));
308
309 ActiveTabPermissionGranter* active_tab_permission_granter =
310 TabHelper::FromWebContents(web_contents())
311 ->active_tab_permission_granter();
312 ASSERT_TRUE(active_tab_permission_granter);
313 // Grant the extension active tab permissions. This normally happens, e.g.,
314 // if the user clicks on a browser action.
315 active_tab_permission_granter->GrantIfRequested(extension);
316
317 // Since we have active tab permissions, we shouldn't need user consent
318 // anymore.
[email protected]23a85362014-07-07 23:26:19319 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52320
[email protected]4b8d1c62014-08-16 01:22:21321 // Reloading and other same-origin navigations maintain the permission to
322 // execute.
[email protected]8d5cb212014-06-04 09:00:39323 Reload();
[email protected]4b8d1c62014-08-16 01:22:21324 EXPECT_FALSE(RequiresUserConsent(extension));
325 NavigateAndCommit(GURL("https://www.google.com/foo"));
326 EXPECT_FALSE(RequiresUserConsent(extension));
327 NavigateAndCommit(GURL("https://www.google.com/bar"));
328 EXPECT_FALSE(RequiresUserConsent(extension));
329
330 // Navigating to a different origin will require user consent again.
331 NavigateAndCommit(GURL("https://yahoo.com"));
332 EXPECT_TRUE(RequiresUserConsent(extension));
333
334 // Back to the original origin should also re-require constent.
335 NavigateAndCommit(GURL("https://www.google.com"));
[email protected]23a85362014-07-07 23:26:19336 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]11814f52014-05-23 06:50:35337
[email protected]23a85362014-07-07 23:26:19338 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14339 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]11814f52014-05-23 06:50:35340 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
341
342 // Grant active tab.
343 active_tab_permission_granter->GrantIfRequested(extension);
344
345 // The pending injections should have run since active tab permission was
346 // granted.
347 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14348 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52349}
350
rdevlin.cronin8408b4f92016-03-15 19:14:14351TEST_F(ExtensionActionRunnerUnitTest, ActiveScriptsCanHaveAllUrlsPref) {
[email protected]b33c8c22014-05-29 19:51:08352 const Extension* extension = AddExtension();
353 ASSERT_TRUE(extension);
354
355 NavigateAndCommit(GURL("https://www.google.com"));
[email protected]23a85362014-07-07 23:26:19356 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08357
358 // Enable the extension on all urls.
359 util::SetAllowedScriptingOnAllUrls(extension->id(), profile(), true);
360
[email protected]23a85362014-07-07 23:26:19361 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08362 // This should carry across navigations, and websites.
363 NavigateAndCommit(GURL("http://www.foo.com"));
[email protected]23a85362014-07-07 23:26:19364 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08365
366 // Turning off the preference should have instant effect.
367 util::SetAllowedScriptingOnAllUrls(extension->id(), profile(), false);
[email protected]23a85362014-07-07 23:26:19368 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08369
370 // And should also persist across navigations and websites.
371 NavigateAndCommit(GURL("http://www.bar.com"));
[email protected]23a85362014-07-07 23:26:19372 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08373}
374
rdevlin.cronin8408b4f92016-03-15 19:14:14375TEST_F(ExtensionActionRunnerUnitTest, TestAlwaysRun) {
[email protected]e1670582014-08-15 23:05:41376 const Extension* extension = AddExtension();
377 ASSERT_TRUE(extension);
378
379 NavigateAndCommit(GURL("https://www.google.com/?gws_rd=ssl"));
380
381 // Ensure that there aren't any executions pending.
382 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14383 ASSERT_FALSE(runner()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41384
385 // Since the extension requests all_hosts, we should require user consent.
386 EXPECT_TRUE(RequiresUserConsent(extension));
387
rdevlin.cronin91f162a12014-09-03 16:48:40388 // Request an injection. The extension should want to run, but not execute.
[email protected]e1670582014-08-15 23:05:41389 RequestInjection(extension);
rdevlin.cronin8408b4f92016-03-15 19:14:14390 EXPECT_TRUE(runner()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41391 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
392
393 // Allow the extension to always run on this origin.
rdevlin.cronincb9f86e2015-10-15 15:13:42394 ScriptingPermissionsModifier modifier(profile(), extension);
395 modifier.GrantHostPermission(web_contents()->GetLastCommittedURL());
rdevlin.cronin8408b4f92016-03-15 19:14:14396 runner()->OnClicked(extension);
[email protected]e1670582014-08-15 23:05:41397
rdevlin.cronin91f162a12014-09-03 16:48:40398 // The extension should execute, and the extension shouldn't want to run.
[email protected]e1670582014-08-15 23:05:41399 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin8408b4f92016-03-15 19:14:14400 EXPECT_FALSE(runner()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41401
402 // Since we already executed on the given page, we shouldn't need permission
403 // for a second time.
404 EXPECT_FALSE(RequiresUserConsent(extension));
405
406 // Navigating to another site that hasn't been granted a persisted permission
407 // should necessitate user consent.
408 NavigateAndCommit(GURL("https://www.foo.com/bar"));
409 EXPECT_TRUE(RequiresUserConsent(extension));
410
411 // We shouldn't need user permission upon returning to the original origin.
412 NavigateAndCommit(GURL("https://www.google.com/foo/bar"));
413 EXPECT_FALSE(RequiresUserConsent(extension));
414
415 // Reloading the extension should not clear any granted host permissions.
416 extension = ReloadExtension();
417 Reload();
418 EXPECT_FALSE(RequiresUserConsent(extension));
419
420 // Different host...
421 NavigateAndCommit(GURL("https://www.foo.com/bar"));
422 EXPECT_TRUE(RequiresUserConsent(extension));
423 // Different scheme...
424 NavigateAndCommit(GURL("http://www.google.com/foo/bar"));
425 EXPECT_TRUE(RequiresUserConsent(extension));
426 // Different subdomain...
427 NavigateAndCommit(GURL("https://en.google.com/foo/bar"));
428 EXPECT_TRUE(RequiresUserConsent(extension));
429 // Only the "always run" origin should be allowed to run without user consent.
430 NavigateAndCommit(GURL("https://www.google.com/foo/bar"));
431 EXPECT_FALSE(RequiresUserConsent(extension));
432}
433
rdevlin.cronin8408b4f92016-03-15 19:14:14434TEST_F(ExtensionActionRunnerUnitTest, TestDifferentScriptRunLocations) {
rdevlin.cronin8d034e52016-02-02 22:46:32435 const Extension* extension = AddExtension();
436 ASSERT_TRUE(extension);
437
438 NavigateAndCommit(GURL("https://www.foo.com"));
439
rdevlin.cronin8408b4f92016-03-15 19:14:14440 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32441
442 RequestInjection(extension, UserScript::DOCUMENT_END);
443 EXPECT_EQ(BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14444 runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32445 RequestInjection(extension, UserScript::DOCUMENT_IDLE);
446 EXPECT_EQ(BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14447 runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32448 RequestInjection(extension, UserScript::DOCUMENT_START);
449 EXPECT_EQ(BLOCKED_ACTION_SCRIPT_AT_START | BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14450 runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32451
rdevlin.cronin8408b4f92016-03-15 19:14:14452 runner()->OnClicked(extension);
453 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32454}
455
rdevlin.cronin8408b4f92016-03-15 19:14:14456TEST_F(ExtensionActionRunnerUnitTest, TestWebRequestBlocked) {
rdevlin.cronin8d034e52016-02-02 22:46:32457 const Extension* extension = AddExtension();
458 ASSERT_TRUE(extension);
459
460 NavigateAndCommit(GURL("https://www.foo.com"));
461
rdevlin.cronin8408b4f92016-03-15 19:14:14462 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
463 EXPECT_FALSE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32464
rdevlin.cronin8408b4f92016-03-15 19:14:14465 runner()->OnWebRequestBlocked(extension);
466 EXPECT_EQ(BLOCKED_ACTION_WEB_REQUEST, runner()->GetBlockedActions(extension));
467 EXPECT_TRUE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32468
469 RequestInjection(extension);
470 EXPECT_EQ(BLOCKED_ACTION_WEB_REQUEST | BLOCKED_ACTION_SCRIPT_OTHER,
rdevlin.cronin8408b4f92016-03-15 19:14:14471 runner()->GetBlockedActions(extension));
472 EXPECT_TRUE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32473
474 NavigateAndCommit(GURL("https://www.bar.com"));
rdevlin.cronin8408b4f92016-03-15 19:14:14475 EXPECT_EQ(BLOCKED_ACTION_NONE, runner()->GetBlockedActions(extension));
476 EXPECT_FALSE(runner()->WantsToRun(extension));
rdevlin.cronin8d034e52016-02-02 22:46:32477}
478
[email protected]78cd68e2014-05-22 20:33:52479} // namespace extensions