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

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

Issue 2766263003: Extensions: Only load incognito-enabled extensions in an incognito renderer. (Closed)
Patch Set: Address review Created 3 years, 8 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <stddef.h> 5 #include <stddef.h>
6 #include <stdint.h> 6 #include <stdint.h>
7 7
8 #include <memory> 8 #include <memory>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/base64.h" 11 #include "base/base64.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/json/json_reader.h" 13 #include "base/json/json_reader.h"
14 #include "base/json/json_writer.h" 14 #include "base/json/json_writer.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/path_service.h" 16 #include "base/path_service.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_piece.h" 18 #include "base/strings/string_piece.h"
19 #include "base/strings/stringprintf.h" 19 #include "base/strings/stringprintf.h"
20 #include "base/strings/utf_string_conversions.h" 20 #include "base/strings/utf_string_conversions.h"
21 #include "base/synchronization/waitable_event.h" 21 #include "base/synchronization/waitable_event.h"
22 #include "base/values.h" 22 #include "base/values.h"
23 #include "build/build_config.h" 23 #include "build/build_config.h"
24 #include "chrome/browser/chrome_notification_types.h" 24 #include "chrome/browser/chrome_notification_types.h"
25 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h" 25 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h"
26 #include "chrome/browser/extensions/extension_apitest.h" 26 #include "chrome/browser/extensions/extension_apitest.h"
27 #include "chrome/browser/extensions/extension_util.h"
27 #include "chrome/browser/extensions/test_extension_dir.h" 28 #include "chrome/browser/extensions/test_extension_dir.h"
28 #include "chrome/browser/infobars/infobar_service.h" 29 #include "chrome/browser/infobars/infobar_service.h"
29 #include "chrome/browser/profiles/profile.h" 30 #include "chrome/browser/profiles/profile.h"
30 #include "chrome/browser/ui/browser.h" 31 #include "chrome/browser/ui/browser.h"
31 #include "chrome/browser/ui/browser_commands.h" 32 #include "chrome/browser/ui/browser_commands.h"
32 #include "chrome/browser/ui/tabs/tab_strip_model.h" 33 #include "chrome/browser/ui/tabs/tab_strip_model.h"
33 #include "chrome/common/chrome_paths.h" 34 #include "chrome/common/chrome_paths.h"
34 #include "chrome/common/chrome_switches.h" 35 #include "chrome/common/chrome_switches.h"
35 #include "chrome/test/base/ui_test_utils.h" 36 #include "chrome/test/base/ui_test_utils.h"
36 #include "content/public/browser/notification_registrar.h" 37 #include "content/public/browser/notification_registrar.h"
37 #include "content/public/browser/notification_service.h" 38 #include "content/public/browser/notification_service.h"
38 #include "content/public/test/browser_test_utils.h" 39 #include "content/public/test/browser_test_utils.h"
39 #include "content/public/test/test_utils.h" 40 #include "content/public/test/test_utils.h"
40 #include "extensions/browser/event_router.h" 41 #include "extensions/browser/event_router.h"
41 #include "extensions/browser/extension_prefs.h" 42 #include "extensions/browser/extension_prefs.h"
43 #include "extensions/browser/extension_registry.h"
42 #include "extensions/browser/extension_system.h" 44 #include "extensions/browser/extension_system.h"
45 #include "extensions/browser/extension_util.h"
43 #include "extensions/browser/process_manager.h" 46 #include "extensions/browser/process_manager.h"
47 #include "extensions/browser/test_extension_registry_observer.h"
44 #include "extensions/common/api/runtime.h" 48 #include "extensions/common/api/runtime.h"
45 #include "extensions/common/extension_builder.h" 49 #include "extensions/common/extension_builder.h"
46 #include "extensions/common/value_builder.h" 50 #include "extensions/common/value_builder.h"
47 #include "extensions/test/extension_test_message_listener.h" 51 #include "extensions/test/extension_test_message_listener.h"
48 #include "extensions/test/result_catcher.h" 52 #include "extensions/test/result_catcher.h"
49 #include "net/cert/asn1_util.h" 53 #include "net/cert/asn1_util.h"
50 #include "net/cert/jwk_serializer.h" 54 #include "net/cert/jwk_serializer.h"
51 #include "net/dns/mock_host_resolver.h" 55 #include "net/dns/mock_host_resolver.h"
52 #include "net/ssl/channel_id_service.h" 56 #include "net/ssl/channel_id_service.h"
53 #include "net/test/embedded_test_server/embedded_test_server.h" 57 #include "net/test/embedded_test_server/embedded_test_server.h"
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 345
342 GURL popup_opener_url() { 346 GURL popup_opener_url() {
343 return GetURLForPath("www.chromium.org", "/popup_opener.html"); 347 return GetURLForPath("www.chromium.org", "/popup_opener.html");
344 } 348 }
345 349
346 GURL google_com_url() { 350 GURL google_com_url() {
347 return GetURLForPath("www.google.com", "/google.com.html"); 351 return GetURLForPath("www.google.com", "/google.com.html");
348 } 352 }
349 353
350 scoped_refptr<const Extension> LoadChromiumConnectableExtension() { 354 scoped_refptr<const Extension> LoadChromiumConnectableExtension() {
351 scoped_refptr<const Extension> extension = 355 scoped_refptr<const Extension> extension = LoadExtensionIntoDir(
352 LoadExtensionIntoDir(&web_connectable_dir_, 356 &web_connectable_dir_extension_,
353 base::StringPrintf( 357 base::StringPrintf("{"
354 "{" 358 " \"name\": \"chromium_connectable\","
355 " \"name\": \"chromium_connectable\"," 359 " %s,"
356 " %s," 360 " \"externally_connectable\": {"
357 " \"externally_connectable\": {" 361 " \"matches\": [\"*://*.chromium.org:*/*\"]"
358 " \"matches\": [\"*://*.chromium.org:*/*\"]" 362 " }"
359 " }" 363 "}",
360 "}", 364 common_manifest()));
361 common_manifest()));
362 CHECK(extension.get()); 365 CHECK(extension.get());
363 return extension; 366 return extension;
364 } 367 }
365 368
366 scoped_refptr<const Extension> LoadChromiumConnectableApp( 369 scoped_refptr<const Extension> LoadChromiumConnectableApp(
367 bool with_event_handlers = true) { 370 bool with_event_handlers = true) {
368 scoped_refptr<const Extension> extension = 371 scoped_refptr<const Extension> extension =
369 LoadExtensionIntoDir(&web_connectable_dir_, 372 LoadExtensionIntoDir(&web_connectable_dir_app_,
370 "{" 373 "{"
371 " \"app\": {" 374 " \"app\": {"
372 " \"background\": {" 375 " \"background\": {"
373 " \"scripts\": [\"background.js\"]" 376 " \"scripts\": [\"background.js\"]"
374 " }" 377 " }"
375 " }," 378 " },"
376 " \"externally_connectable\": {" 379 " \"externally_connectable\": {"
377 " \"matches\": [\"*://*.chromium.org:*/*\"]" 380 " \"matches\": [\"*://*.chromium.org:*/*\"]"
378 " }," 381 " },"
379 " \"manifest_version\": 2," 382 " \"manifest_version\": 2,"
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 args += include_tls_channel_id ? "true" : "false"; 505 args += include_tls_channel_id ? "true" : "false";
503 if (message) 506 if (message)
504 args += std::string(", '") + message + "'"; 507 args += std::string(", '") + message + "'";
505 CHECK(content::ExecuteScriptAndExtractString( 508 CHECK(content::ExecuteScriptAndExtractString(
506 browser()->tab_strip_model()->GetActiveWebContents(), 509 browser()->tab_strip_model()->GetActiveWebContents(),
507 base::StringPrintf("assertions.%s(%s)", method, args.c_str()), 510 base::StringPrintf("assertions.%s(%s)", method, args.c_str()),
508 &result)); 511 &result));
509 return result; 512 return result;
510 } 513 }
511 514
512 TestExtensionDir web_connectable_dir_; 515 TestExtensionDir web_connectable_dir_extension_;
516 TestExtensionDir web_connectable_dir_app_;
513 TestExtensionDir not_connectable_dir_; 517 TestExtensionDir not_connectable_dir_;
514 TestExtensionDir tls_channel_id_connectable_dir_; 518 TestExtensionDir tls_channel_id_connectable_dir_;
515 TestExtensionDir hosted_app_dir_; 519 TestExtensionDir hosted_app_dir_;
516 }; 520 };
517 521
518 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, NotInstalled) { 522 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, NotInstalled) {
519 InitializeTestServer(); 523 InitializeTestServer();
520 524
521 scoped_refptr<const Extension> extension = 525 scoped_refptr<const Extension> extension =
522 ExtensionBuilder() 526 ExtensionBuilder()
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount()); 768 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount());
765 } 769 }
766 770
767 // It's not possible to allow an app in incognito. 771 // It's not possible to allow an app in incognito.
768 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(app->id(), true); 772 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(app->id(), true);
769 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, 773 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
770 CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL)); 774 CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
771 } 775 }
772 776
773 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, 777 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
774 FromIncognitoDenyExtension) { 778 FromIncognitoDenyExtensionAndApp) {
775 InitializeTestServer(); 779 InitializeTestServer();
776 780
777 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension(); 781 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
782 EXPECT_FALSE(util::IsIncognitoEnabled(extension->id(), profile()));
778 783
779 Browser* incognito_browser = OpenURLOffTheRecord( 784 Browser* incognito_browser = OpenURLOffTheRecord(
780 profile()->GetOffTheRecordProfile(), chromium_org_url()); 785 profile()->GetOffTheRecordProfile(), chromium_org_url());
781 content::RenderFrameHost* incognito_frame = 786 content::RenderFrameHost* incognito_frame =
782 incognito_browser->tab_strip_model() 787 incognito_browser->tab_strip_model()
783 ->GetActiveWebContents() 788 ->GetActiveWebContents()
784 ->GetMainFrame(); 789 ->GetMainFrame();
785 790
786 { 791 IncognitoConnectability::ScopedAlertTracker alert_tracker(
787 IncognitoConnectability::ScopedAlertTracker alert_tracker( 792 IncognitoConnectability::ScopedAlertTracker::ALWAYS_DENY);
788 IncognitoConnectability::ScopedAlertTracker::ALWAYS_DENY);
789 793
790 // The alert doesn't show for extensions. 794 // |extension| won't be loaded in the incognito renderer since it's not
791 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, 795 // enabled for incognito. Since there is no externally connectible extension
792 CanConnectAndSendMessagesToFrame( 796 // loaded into the incognito renderer, the chrome.runtime API won't be
793 incognito_frame, extension.get(), NULL)); 797 // defined.
794 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount()); 798 EXPECT_EQ(NAMESPACE_NOT_DEFINED,
795 } 799 CanConnectAndSendMessagesToFrame(incognito_frame, extension.get(),
800 nullptr));
796 801
797 // Allowing the extension in incognito mode will bypass the deny. 802 // Loading a platform app in the renderer should cause the chrome.runtime
798 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(extension->id(), true); 803 // bindings to be generated in the renderer. A platform app is always loaded
799 EXPECT_EQ( 804 // in the incognito renderer.
800 OK, 805 LoadChromiumConnectableApp();
801 CanConnectAndSendMessagesToFrame(incognito_frame, extension.get(), NULL)); 806 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
807 CanConnectAndSendMessagesToFrame(incognito_frame, extension.get(),
808 nullptr));
809
810 // Allowing the extension in incognito mode loads the extension in the
811 // incognito renderer, allowing it to receive connections.
812 TestExtensionRegistryObserver observer(
813 ExtensionRegistry::Get(profile()->GetOffTheRecordProfile()),
814 extension->id());
815 util::SetIsIncognitoEnabled(extension->id(),
816 profile()->GetOffTheRecordProfile(), true);
817 const Extension* loaded_extension = observer.WaitForExtensionLoaded();
818 EXPECT_EQ(OK, CanConnectAndSendMessagesToFrame(incognito_frame,
819 loaded_extension, nullptr));
820
821 // No alert is shown for extensions since they support being enabled in
822 // incognito mode.
823 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount());
802 } 824 }
803 825
804 // Tests connection from incognito tabs when the extension doesn't have an event 826 // Tests connection from incognito tabs when the extension doesn't have an event
805 // handler for the connection event. 827 // handler for the connection event.
806 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, 828 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
807 FromIncognitoNoEventHandlerInApp) { 829 FromIncognitoNoEventHandlerInApp) {
808 InitializeTestServer(); 830 InitializeTestServer();
809 831
810 scoped_refptr<const Extension> app = LoadChromiumConnectableApp(false); 832 scoped_refptr<const Extension> app = LoadChromiumConnectableApp(false);
811 ASSERT_TRUE(app->is_platform_app()); 833 ASSERT_TRUE(app->is_platform_app());
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 browser()->tab_strip_model()->GetActiveWebContents(), 965 browser()->tab_strip_model()->GetActiveWebContents(),
944 "assertions.tryIllegalArguments()", &result)); 966 "assertions.tryIllegalArguments()", &result));
945 EXPECT_TRUE(result); 967 EXPECT_TRUE(result);
946 } 968 }
947 969
948 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, 970 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
949 FromIncognitoAllowExtension) { 971 FromIncognitoAllowExtension) {
950 InitializeTestServer(); 972 InitializeTestServer();
951 973
952 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension(); 974 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
975 EXPECT_FALSE(util::IsIncognitoEnabled(extension->id(), profile()));
953 976
954 Browser* incognito_browser = OpenURLOffTheRecord( 977 Browser* incognito_browser = OpenURLOffTheRecord(
955 profile()->GetOffTheRecordProfile(), chromium_org_url()); 978 profile()->GetOffTheRecordProfile(), chromium_org_url());
956 content::RenderFrameHost* incognito_frame = 979 content::RenderFrameHost* incognito_frame =
957 incognito_browser->tab_strip_model() 980 incognito_browser->tab_strip_model()
958 ->GetActiveWebContents() 981 ->GetActiveWebContents()
959 ->GetMainFrame(); 982 ->GetMainFrame();
960 983
961 { 984 IncognitoConnectability::ScopedAlertTracker alert_tracker(
962 IncognitoConnectability::ScopedAlertTracker alert_tracker( 985 IncognitoConnectability::ScopedAlertTracker::ALWAYS_ALLOW);
963 IncognitoConnectability::ScopedAlertTracker::ALWAYS_ALLOW);
964 986
965 // No alert is shown. 987 // |extension| won't be loaded in the incognito renderer since it's not
966 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, 988 // enabled for incognito. Since there is no externally connectible extension
967 CanConnectAndSendMessagesToFrame( 989 // loaded into the incognito renderer, the chrome.runtime API won't be
968 incognito_frame, extension.get(), NULL)); 990 // defined.
969 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount()); 991 EXPECT_EQ(NAMESPACE_NOT_DEFINED,
970 } 992 CanConnectAndSendMessagesToFrame(incognito_frame, extension.get(),
993 nullptr));
971 994
972 // Allowing the extension in incognito mode is what allows connections. 995 // Allowing the extension in incognito mode loads the extension in the
973 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(extension->id(), true); 996 // incognito renderer, causing the chrome.runtime bindings to be generated in
974 EXPECT_EQ( 997 // the renderer and allowing the extension to receive connections.
975 OK, 998 TestExtensionRegistryObserver observer(
976 CanConnectAndSendMessagesToFrame(incognito_frame, extension.get(), NULL)); 999 ExtensionRegistry::Get(profile()->GetOffTheRecordProfile()),
1000 extension->id());
1001 util::SetIsIncognitoEnabled(extension->id(),
1002 profile()->GetOffTheRecordProfile(), true);
1003 const Extension* loaded_extension = observer.WaitForExtensionLoaded();
1004 EXPECT_EQ(OK, CanConnectAndSendMessagesToFrame(incognito_frame,
1005 loaded_extension, nullptr));
1006
1007 // No alert is shown for extensions which support being enabled in incognito
1008 // mode.
1009 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount());
977 } 1010 }
978 1011
979 // Tests a connection from an iframe within a tab which doesn't have 1012 // Tests a connection from an iframe within a tab which doesn't have
980 // permission. Iframe should work. 1013 // permission. Iframe should work.
981 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, 1014 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
982 FromIframeWithPermission) { 1015 FromIframeWithPermission) {
983 InitializeTestServer(); 1016 InitializeTestServer();
984 1017
985 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension(); 1018 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
986 1019
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 ASSERT_TRUE(content::ExecuteScriptAndExtractInt( 1357 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
1325 background_contents, 1358 background_contents,
1326 "window.domAutomationController.send(window.messageCount);", 1359 "window.domAutomationController.send(window.messageCount);",
1327 &message_count)); 1360 &message_count));
1328 EXPECT_EQ(1, message_count); 1361 EXPECT_EQ(1, message_count);
1329 } 1362 }
1330 1363
1331 } // namespace 1364 } // namespace
1332 1365
1333 }; // namespace extensions 1366 }; // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/messaging/message_service.cc ('k') | extensions/browser/renderer_startup_helper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698