Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(400)

Side by Side Diff: chrome/browser/extensions/active_script_controller_browsertest.cc

Issue 313453002: Resubmit: Block content scripts from executing until user grants permission (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Tests Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/files/file_path.h" 5 #include "base/files/file_path.h"
6 #include "base/macros.h" 6 #include "base/macros.h"
7 #include "base/strings/stringprintf.h" 7 #include "base/strings/stringprintf.h"
8 #include "chrome/browser/extensions/active_script_controller.h" 8 #include "chrome/browser/extensions/active_script_controller.h"
9 #include "chrome/browser/extensions/extension_action.h" 9 #include "chrome/browser/extensions/extension_action.h"
10 #include "chrome/browser/extensions/extension_browsertest.h" 10 #include "chrome/browser/extensions/extension_browsertest.h"
11 #include "chrome/browser/extensions/extension_test_message_listener.h" 11 #include "chrome/browser/extensions/extension_test_message_listener.h"
12 #include "chrome/browser/extensions/location_bar_controller.h" 12 #include "chrome/browser/extensions/location_bar_controller.h"
13 #include "chrome/browser/extensions/tab_helper.h" 13 #include "chrome/browser/extensions/tab_helper.h"
14 #include "chrome/browser/extensions/test_extension_dir.h" 14 #include "chrome/browser/extensions/test_extension_dir.h"
15 #include "chrome/browser/ui/browser.h" 15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h" 16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/test/base/ui_test_utils.h" 17 #include "chrome/test/base/ui_test_utils.h"
18 #include "content/public/test/browser_test_utils.h"
18 #include "extensions/common/feature_switch.h" 19 #include "extensions/common/feature_switch.h"
20 #include "extensions/common/switches.h"
19 #include "net/test/embedded_test_server/embedded_test_server.h" 21 #include "net/test/embedded_test_server/embedded_test_server.h"
20 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
21 23
22 namespace extensions { 24 namespace extensions {
23 25
24 namespace { 26 namespace {
25 27
26 const char kAllHostsScheme[] = "*://*/*"; 28 const char kAllHostsScheme[] = "*://*/*";
27 const char kExplicitHostsScheme[] = "http://127.0.0.1/*"; 29 const char kExplicitHostsScheme[] = "http://127.0.0.1/*";
28 const char kBackgroundScript[] = 30 const char kBackgroundScript[] =
(...skipping 25 matching lines...) Expand all
54 56
55 enum RequiresConsent { 57 enum RequiresConsent {
56 REQUIRES_CONSENT, 58 REQUIRES_CONSENT,
57 DOES_NOT_REQUIRE_CONSENT 59 DOES_NOT_REQUIRE_CONSENT
58 }; 60 };
59 61
60 } // namespace 62 } // namespace
61 63
62 class ActiveScriptControllerBrowserTest : public ExtensionBrowserTest { 64 class ActiveScriptControllerBrowserTest : public ExtensionBrowserTest {
63 public: 65 public:
64 ActiveScriptControllerBrowserTest() 66 ActiveScriptControllerBrowserTest() {}
65 : feature_override_(FeatureSwitch::scripts_require_action(),
66 FeatureSwitch::OVERRIDE_ENABLED) {}
67 67
68 virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE;
68 virtual void CleanUpOnMainThread() OVERRIDE; 69 virtual void CleanUpOnMainThread() OVERRIDE;
69 70
70 // Returns an extension with the given |host_type| and |injection_type|. If 71 // Returns an extension with the given |host_type| and |injection_type|. If
71 // one already exists, the existing extension will be returned. Othewrwise, 72 // one already exists, the existing extension will be returned. Othewrwise,
72 // one will be created. 73 // one will be created.
73 // This could potentially return NULL if LoadExtension() fails. 74 // This could potentially return NULL if LoadExtension() fails.
74 const Extension* GetOrCreateExtension(HostType host_type, 75 const Extension* GetOrCreateExtension(HostType host_type,
75 InjectionType injection_type); 76 InjectionType injection_type);
76 77
77 private: 78 private:
78 FeatureSwitch::ScopedOverride feature_override_;
79 ScopedVector<TestExtensionDir> test_extension_dirs_; 79 ScopedVector<TestExtensionDir> test_extension_dirs_;
80 std::vector<const Extension*> extensions_; 80 std::vector<const Extension*> extensions_;
81 }; 81 };
82 82
83 void ActiveScriptControllerBrowserTest::SetUpCommandLine(
84 base::CommandLine* command_line) {
85 ExtensionBrowserTest::SetUpCommandLine(command_line);
86 // We append the actual switch to the commandline because it needs to be
87 // passed over to the renderer, which a FeatureSwitch::ScopedOverride will
88 // not do.
89 command_line->AppendSwitch(switches::kEnableScriptsRequireAction);
90 }
91
83 void ActiveScriptControllerBrowserTest::CleanUpOnMainThread() { 92 void ActiveScriptControllerBrowserTest::CleanUpOnMainThread() {
84 test_extension_dirs_.clear(); 93 test_extension_dirs_.clear();
85 } 94 }
86 95
87 const Extension* ActiveScriptControllerBrowserTest::GetOrCreateExtension( 96 const Extension* ActiveScriptControllerBrowserTest::GetOrCreateExtension(
88 HostType host_type, InjectionType injection_type) { 97 HostType host_type, InjectionType injection_type) {
89 std::string name = 98 std::string name =
90 base::StringPrintf( 99 base::StringPrintf(
91 "%s %s", 100 "%s %s",
92 injection_type == CONTENT_SCRIPT ? 101 injection_type == CONTENT_SCRIPT ?
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 268
260 // If the extension has permission, we should be able to simply wait for it 269 // If the extension has permission, we should be able to simply wait for it
261 // to execute. 270 // to execute.
262 if (requires_consent_ == DOES_NOT_REQUIRE_CONSENT) { 271 if (requires_consent_ == DOES_NOT_REQUIRE_CONSENT) {
263 inject_success_listener_->WaitUntilSatisfied(); 272 inject_success_listener_->WaitUntilSatisfied();
264 return testing::AssertionSuccess(); 273 return testing::AssertionSuccess();
265 } 274 }
266 275
267 // Otherwise, we don't have permission, and have to grant it. Ensure the 276 // Otherwise, we don't have permission, and have to grant it. Ensure the
268 // script has *not* already executed. 277 // script has *not* already executed.
269 // Currently, it's okay for content scripts to execute, because we don't 278 if (inject_success_listener_->was_satisfied()) {
270 // block them.
271 // TODO(rdevlin.cronin): Fix this.
272 if (inject_success_listener_->was_satisfied() && type_ != CONTENT_SCRIPT) {
273 return testing::AssertionFailure() << 279 return testing::AssertionFailure() <<
274 name_ << "'s script ran without permission."; 280 name_ << "'s script ran without permission.";
275 } 281 }
276 282
277 // If we reach this point, we should always have an action. 283 // If we reach this point, we should always have an action.
278 DCHECK(action); 284 DCHECK(action);
279 285
280 // Grant permission by clicking on the extension action. 286 // Grant permission by clicking on the extension action.
281 location_bar_controller->OnClicked(action); 287 location_bar_controller->OnClicked(action);
282 288
(...skipping 26 matching lines...) Expand all
309 return location_bar_controller ? 315 return location_bar_controller ?
310 location_bar_controller->active_script_controller() : NULL; 316 location_bar_controller->active_script_controller() : NULL;
311 } 317 }
312 318
313 ExtensionAction* ActiveScriptTester::GetAction() { 319 ExtensionAction* ActiveScriptTester::GetAction() {
314 ActiveScriptController* controller = GetActiveScriptController(); 320 ActiveScriptController* controller = GetActiveScriptController();
315 return controller ? controller->GetActionForExtension(extension_) : NULL; 321 return controller ? controller->GetActionForExtension(extension_) : NULL;
316 } 322 }
317 323
318 IN_PROC_BROWSER_TEST_F(ActiveScriptControllerBrowserTest, 324 IN_PROC_BROWSER_TEST_F(ActiveScriptControllerBrowserTest,
319 ActiveScriptsAreDisplayed) { 325 ActiveScriptsAreDisplayedAndDelayExecution) {
320 base::FilePath active_script_path = 326 base::FilePath active_script_path =
321 test_data_dir_.AppendASCII("active_script"); 327 test_data_dir_.AppendASCII("active_script");
322 328
323 const char* kExtensionNames[] = { 329 const char* kExtensionNames[] = {
324 "inject_scripts_all_hosts", 330 "inject_scripts_all_hosts",
325 "inject_scripts_explicit_hosts", 331 "inject_scripts_explicit_hosts",
326 "content_scripts_all_hosts", 332 "content_scripts_all_hosts",
327 "content_scripts_explicit_hosts" 333 "content_scripts_explicit_hosts"
328 }; 334 };
329 335
(...skipping 25 matching lines...) Expand all
355 CONTENT_SCRIPT), 361 CONTENT_SCRIPT),
356 ActiveScriptTester( 362 ActiveScriptTester(
357 kExtensionNames[3], 363 kExtensionNames[3],
358 GetOrCreateExtension(EXPLICIT_HOSTS, CONTENT_SCRIPT), 364 GetOrCreateExtension(EXPLICIT_HOSTS, CONTENT_SCRIPT),
359 browser(), 365 browser(),
360 DOES_NOT_REQUIRE_CONSENT, 366 DOES_NOT_REQUIRE_CONSENT,
361 CONTENT_SCRIPT), 367 CONTENT_SCRIPT),
362 }; 368 };
363 369
364 // Navigate to an URL (which matches the explicit host specified in the 370 // Navigate to an URL (which matches the explicit host specified in the
365 // extension content_scripts_explicit_hosts). All three extensions should 371 // extension content_scripts_explicit_hosts). All four extensions should
366 // inject the script. 372 // inject the script.
367 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 373 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
368 ui_test_utils::NavigateToURL( 374 ui_test_utils::NavigateToURL(
369 browser(), embedded_test_server()->GetURL("/extensions/test_file.html")); 375 browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
370 376
371 for (size_t i = 0u; i < arraysize(testers); ++i) 377 for (size_t i = 0u; i < arraysize(testers); ++i)
372 EXPECT_TRUE(testers[i].Verify()) << kExtensionNames[i]; 378 EXPECT_TRUE(testers[i].Verify()) << kExtensionNames[i];
373 } 379 }
374 380
381 // Test that removing an extension with pending injections a) removes the
382 // pending injections for that extension, and b) does not affect pending
383 // injections for other extensions.
384 IN_PROC_BROWSER_TEST_F(ActiveScriptControllerBrowserTest,
385 RemoveExtensionWithPendingInjections) {
386 const Extension* extension1 = GetOrCreateExtension(ALL_HOSTS, CONTENT_SCRIPT);
387 ASSERT_TRUE(extension1);
388 const Extension* extension2 = GetOrCreateExtension(ALL_HOSTS, EXECUTE_SCRIPT);
389 ASSERT_TRUE(extension2);
390
391 content::WebContents* web_contents =
392 browser()->tab_strip_model()->GetActiveWebContents();
393 ASSERT_TRUE(web_contents);
394 ActiveScriptController* active_script_controller =
395 ActiveScriptController::GetForWebContents(web_contents);
396 ASSERT_TRUE(active_script_controller);
397
398 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
399 ui_test_utils::NavigateToURL(
400 browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
401
402 // Both extensions should have pending requests.
403 EXPECT_TRUE(active_script_controller->GetActionForExtension(extension1));
404 EXPECT_TRUE(active_script_controller->GetActionForExtension(extension2));
405
406 // Unload one of the extensions.
407 UnloadExtension(extension2->id());
408
409 // This is slight hack to achieve a RunPendingInRenderer() method. Since IPCs
410 // are sent synchronously, the renderer will be notified of the extension
411 // being unloaded before the script is executed, and, since ExecuteScript() is
412 // synchronous, the renderer is guaranteed to be done updating scripts.
413 EXPECT_TRUE(content::ExecuteScript(web_contents, "1 == 1;"));
414
415 // We should have pending requests for extension1, but not the removed
416 // extension2.
417 EXPECT_TRUE(active_script_controller->GetActionForExtension(extension1));
418 EXPECT_FALSE(active_script_controller->GetActionForExtension(extension2));
419
420 // We should still be able to run the request for extension1.
421 ExtensionTestMessageListener inject_success_listener(
422 new ExtensionTestMessageListener(kInjectSucceeded,
423 false /* won't reply */));
424 active_script_controller->OnClicked(extension1);
425 inject_success_listener.WaitUntilSatisfied();
not at google - send to devlin 2014/06/02 21:28:17 it doesn't seem like you're necessarily testing re
Devlin 2014/06/02 22:19:16 We are testing that the script gets injected by wa
not at google - send to devlin 2014/06/02 22:20:19 good point. renderer is tested.
426 }
427
428 // A version of the test with the flag off, in order to test that everything
429 // still works as expected.
430 class FlagOffActiveScriptControllerBrowserTest
431 : public ActiveScriptControllerBrowserTest {
432 private:
433 // Simply don't append the flag.
434 virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE {
435 ExtensionBrowserTest::SetUpCommandLine(command_line);
436 }
437 };
438
439 IN_PROC_BROWSER_TEST_F(FlagOffActiveScriptControllerBrowserTest,
440 ScriptsExecuteWhenFlagAbsent) {
441 const char* kExtensionNames[] = {
442 "content_scripts_all_hosts",
443 "inject_scripts_all_hosts",
444 };
445 ActiveScriptTester testers[] = {
446 ActiveScriptTester(
447 kExtensionNames[0],
448 GetOrCreateExtension(ALL_HOSTS, CONTENT_SCRIPT),
449 browser(),
450 DOES_NOT_REQUIRE_CONSENT,
451 CONTENT_SCRIPT),
452 ActiveScriptTester(
453 kExtensionNames[1],
454 GetOrCreateExtension(ALL_HOSTS, EXECUTE_SCRIPT),
455 browser(),
456 DOES_NOT_REQUIRE_CONSENT,
457 EXECUTE_SCRIPT),
458 };
459
460 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
461 ui_test_utils::NavigateToURL(
462 browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
463
464 for (size_t i = 0u; i < arraysize(testers); ++i)
465 EXPECT_TRUE(testers[i].Verify()) << kExtensionNames[i];
466 }
467
375 } // namespace extensions 468 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698