diff options
author | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-13 14:43:02 +0000 |
---|---|---|
committer | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-13 14:43:02 +0000 |
commit | 173e5e807c62bb789ad46598e46367e019180568 (patch) | |
tree | f7d90e64a28b55e2e8417a2ab8ad997392c5836a /chrome/browser/extensions | |
parent | c0a9f12a2dbb98ff17d9fd02b250c5deeeed9a85 (diff) | |
download | chromium_src-173e5e807c62bb789ad46598e46367e019180568.zip chromium_src-173e5e807c62bb789ad46598e46367e019180568.tar.gz chromium_src-173e5e807c62bb789ad46598e46367e019180568.tar.bz2 |
Reland 44348 Add support for restricting broadcasting events to extensions based on host permissions
BUG=38398
TEST=none
TBR=jochen@chromium.org
Review URL: http://codereview.chromium.org/1642005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@44351 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
15 files changed, 95 insertions, 32 deletions
diff --git a/chrome/browser/extensions/extension_accessibility_api.cc b/chrome/browser/extensions/extension_accessibility_api.cc index 3b6a28f..aebdda2 100644 --- a/chrome/browser/extensions/extension_accessibility_api.cc +++ b/chrome/browser/extensions/extension_accessibility_api.cc @@ -176,7 +176,7 @@ void ExtensionAccessibilityEventRouter::DispatchEvent( const std::string& json_args) { if (enabled_ && profile && profile->GetExtensionMessageService()) { profile->GetExtensionMessageService()->DispatchEventToRenderers( - event_name, json_args, profile->IsOffTheRecord()); + event_name, json_args, profile->IsOffTheRecord(), GURL()); } } diff --git a/chrome/browser/extensions/extension_bookmark_manager_api.cc b/chrome/browser/extensions/extension_bookmark_manager_api.cc index d057731..9b577a8 100644 --- a/chrome/browser/extensions/extension_bookmark_manager_api.cc +++ b/chrome/browser/extensions/extension_bookmark_manager_api.cc @@ -156,7 +156,7 @@ void ExtensionBookmarkManagerEventRouter::DispatchEvent(const char* event_name, std::string json_args; base::JSONWriter::Write(args, false, &json_args); profile_->GetExtensionMessageService()->DispatchEventToRenderers( - event_name, json_args, profile_->IsOffTheRecord()); + event_name, json_args, profile_->IsOffTheRecord(), GURL()); } void ExtensionBookmarkManagerEventRouter::DispatchDragEvent( diff --git a/chrome/browser/extensions/extension_bookmarks_module.cc b/chrome/browser/extensions/extension_bookmarks_module.cc index 6a8cd08..629ae76 100644 --- a/chrome/browser/extensions/extension_bookmarks_module.cc +++ b/chrome/browser/extensions/extension_bookmarks_module.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -95,7 +95,7 @@ void ExtensionBookmarkEventRouter::DispatchEvent(Profile *profile, const std::string json_args) { if (profile->GetExtensionMessageService()) { profile->GetExtensionMessageService()->DispatchEventToRenderers( - event_name, json_args, profile->IsOffTheRecord()); + event_name, json_args, profile->IsOffTheRecord(), GURL()); } } diff --git a/chrome/browser/extensions/extension_browser_event_router.cc b/chrome/browser/extensions/extension_browser_event_router.cc index 9b379bc..52d26da 100644 --- a/chrome/browser/extensions/extension_browser_event_router.cc +++ b/chrome/browser/extensions/extension_browser_event_router.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -89,7 +89,7 @@ static void DispatchEvent(Profile* profile, const std::string json_args) { if (profile->GetExtensionMessageService()) { profile->GetExtensionMessageService()->DispatchEventToRenderers( - event_name, json_args, profile->IsOffTheRecord()); + event_name, json_args, profile->IsOffTheRecord(), GURL()); } } diff --git a/chrome/browser/extensions/extension_devtools_bridge.cc b/chrome/browser/extensions/extension_devtools_bridge.cc index a6399d8..d452c04 100644 --- a/chrome/browser/extensions/extension_devtools_bridge.cc +++ b/chrome/browser/extensions/extension_devtools_bridge.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -65,7 +65,7 @@ void ExtensionDevToolsBridge::InspectedTabClosing() { // event in extensions. std::string json("[{}]"); profile_->GetExtensionMessageService()->DispatchEventToRenderers( - on_tab_close_event_name_, json, profile_->IsOffTheRecord()); + on_tab_close_event_name_, json, profile_->IsOffTheRecord(), GURL()); // This may result in this object being destroyed. extension_devtools_manager_->BridgeClosingForTab(tab_id_); @@ -88,7 +88,7 @@ void ExtensionDevToolsBridge::OnRpcMessage(const DevToolsMessageData& data) { && data.method_name == kApuPageEventMessageName) { std::string json = StringPrintf("[%s]", data.arguments[0].c_str()); profile_->GetExtensionMessageService()->DispatchEventToRenderers( - on_page_event_name_, json, profile_->IsOffTheRecord()); + on_page_event_name_, json, profile_->IsOffTheRecord(), GURL()); } } diff --git a/chrome/browser/extensions/extension_history_api.cc b/chrome/browser/extensions/extension_history_api.cc index 1614a80..400c163 100644 --- a/chrome/browser/extensions/extension_history_api.cc +++ b/chrome/browser/extensions/extension_history_api.cc @@ -143,7 +143,7 @@ void ExtensionHistoryEventRouter::DispatchEvent(Profile* profile, const std::string& json_args) { if (profile && profile->GetExtensionMessageService()) { profile->GetExtensionMessageService()->DispatchEventToRenderers( - event_name, json_args, profile->IsOffTheRecord()); + event_name, json_args, profile->IsOffTheRecord(), GURL()); } } diff --git a/chrome/browser/extensions/extension_idle_api.cc b/chrome/browser/extensions/extension_idle_api.cc index 688e4be..949993f 100644 --- a/chrome/browser/extensions/extension_idle_api.cc +++ b/chrome/browser/extensions/extension_idle_api.cc @@ -152,5 +152,6 @@ void ExtensionIdleEventRouter::OnIdleStateChange(Profile* profile, profile->GetExtensionMessageService()->DispatchEventToRenderers( keys::kOnStateChanged, json_args, - profile->IsOffTheRecord()); + profile->IsOffTheRecord(), + GURL()); } diff --git a/chrome/browser/extensions/extension_menu_manager.cc b/chrome/browser/extensions/extension_menu_manager.cc index 809085e..bbf9909 100644 --- a/chrome/browser/extensions/extension_menu_manager.cc +++ b/chrome/browser/extensions/extension_menu_manager.cc @@ -316,7 +316,7 @@ void ExtensionMenuManager::ExecuteCommand(Profile* profile, base::JSONWriter::Write(&args, false, &json_args); std::string event_name = "contextMenu/" + item->extension_id(); service->DispatchEventToRenderers(event_name, json_args, - profile->IsOffTheRecord()); + profile->IsOffTheRecord(), GURL()); } void ExtensionMenuManager::Observe(NotificationType type, diff --git a/chrome/browser/extensions/extension_menu_manager_unittest.cc b/chrome/browser/extensions/extension_menu_manager_unittest.cc index e81fc04..bdc282e 100644 --- a/chrome/browser/extensions/extension_menu_manager_unittest.cc +++ b/chrome/browser/extensions/extension_menu_manager_unittest.cc @@ -201,9 +201,10 @@ class MockExtensionMessageService : public ExtensionMessageService { explicit MockExtensionMessageService(Profile* profile) : ExtensionMessageService(profile) {} - MOCK_METHOD3(DispatchEventToRenderers, void(const std::string& event_name, + MOCK_METHOD4(DispatchEventToRenderers, void(const std::string& event_name, const std::string& event_args, - bool has_incognito_data)); + bool has_incognito_data, + const GURL& event_url)); private: DISALLOW_COPY_AND_ASSIGN(MockExtensionMessageService); @@ -254,7 +255,8 @@ TEST_F(ExtensionMenuManagerTest, ExecuteCommand) { std::string expected_event_name = "contextMenu/" + item->extension_id(); EXPECT_CALL(*mock_message_service.get(), DispatchEventToRenderers(expected_event_name, _, - profile.IsOffTheRecord())) + profile.IsOffTheRecord(), + GURL())) .Times(1) .WillOnce(SaveArg<1>(&event_args)); diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc index 2586151..731e7b8 100644 --- a/chrome/browser/extensions/extension_message_service.cc +++ b/chrome/browser/extensions/extension_message_service.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -70,7 +70,7 @@ static void DispatchOnConnect(const ExtensionMessageService::MessagePort& port, args.Set(4, Value::CreateStringValue(target_extension_id)); CHECK(port.sender); port.sender->Send(new ViewMsg_ExtensionMessageInvoke(port.routing_id, - ExtensionMessageService::kDispatchOnConnect, args, false)); + ExtensionMessageService::kDispatchOnConnect, args, false, GURL())); } static void DispatchOnDisconnect( @@ -78,7 +78,7 @@ static void DispatchOnDisconnect( ListValue args; args.Set(0, Value::CreateIntegerValue(source_port_id)); port.sender->Send(new ViewMsg_ExtensionMessageInvoke(port.routing_id, - ExtensionMessageService::kDispatchOnDisconnect, args, false)); + ExtensionMessageService::kDispatchOnDisconnect, args, false, GURL())); } static void DispatchOnMessage(const ExtensionMessageService::MessagePort& port, @@ -87,18 +87,20 @@ static void DispatchOnMessage(const ExtensionMessageService::MessagePort& port, args.Set(0, Value::CreateStringValue(message)); args.Set(1, Value::CreateIntegerValue(source_port_id)); port.sender->Send(new ViewMsg_ExtensionMessageInvoke(port.routing_id, - ExtensionMessageService::kDispatchOnMessage, args, false)); + ExtensionMessageService::kDispatchOnMessage, args, false, GURL())); } static void DispatchEvent(const ExtensionMessageService::MessagePort& port, const std::string& event_name, const std::string& event_args, - bool has_incognito_data) { + bool has_incognito_data, + const GURL& event_url) { ListValue args; args.Set(0, Value::CreateStringValue(event_name)); args.Set(1, Value::CreateStringValue(event_args)); port.sender->Send(new ViewMsg_ExtensionMessageInvoke(port.routing_id, - ExtensionMessageService::kDispatchEvent, args, has_incognito_data)); + ExtensionMessageService::kDispatchEvent, args, has_incognito_data, + event_url)); } } // namespace @@ -456,7 +458,7 @@ void ExtensionMessageService::PostMessageFromRenderer( void ExtensionMessageService::DispatchEventToRenderers( const std::string& event_name, const std::string& event_args, - bool has_incognito_data) { + bool has_incognito_data, const GURL& event_url) { DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); std::set<int>& pids = listeners_[event_name]; @@ -472,7 +474,8 @@ void ExtensionMessageService::DispatchEventToRenderers( continue; } - DispatchEvent(renderer, event_name, event_args, has_incognito_data); + DispatchEvent( + renderer, event_name, event_args, has_incognito_data, event_url); } } diff --git a/chrome/browser/extensions/extension_message_service.h b/chrome/browser/extensions/extension_message_service.h index 7d7540e..c205bb9 100644 --- a/chrome/browser/extensions/extension_message_service.h +++ b/chrome/browser/extensions/extension_message_service.h @@ -16,6 +16,7 @@ #include "chrome/browser/extensions/extension_devtools_manager.h" #include "ipc/ipc_message.h" +class GURL; class MessageLoop; class Profile; class RenderProcessHost; @@ -80,10 +81,13 @@ class ExtensionMessageService // Sends a message from a renderer to the given port. void PostMessageFromRenderer(int port_id, const std::string& message); - // Send an event to every registered extension renderer. + // Send an event to every registered extension renderer. If + // |has_incognito_data| is true, the event is only sent to extension with the + // permission to access incognito data. If |event_url| is not empty, the + // event is only sent to extension with host permissions for this url. virtual void DispatchEventToRenderers( const std::string& event_name, const std::string& event_args, - bool has_incognito_data); + bool has_incognito_data, const GURL& event_url); // Given an extension ID, opens a channel between the given // automation "port" or DevTools service and that extension. the diff --git a/chrome/browser/extensions/extension_messages_apitest.cc b/chrome/browser/extensions/extension_messages_apitest.cc index e2e969f..cc412d9 100644 --- a/chrome/browser/extensions/extension_messages_apitest.cc +++ b/chrome/browser/extensions/extension_messages_apitest.cc @@ -3,6 +3,50 @@ // found in the LICENSE file. #include "chrome/browser/extensions/extension_apitest.h" +#include "chrome/browser/extensions/extension_message_service.h" +#include "chrome/browser/profile.h" +#include "chrome/common/notification_registrar.h" + +namespace { + +class MessageSender : public NotificationObserver { + public: + MessageSender() { + registrar_.Add(this, NotificationType::EXTENSION_HOST_DID_STOP_LOADING, + NotificationService::AllSources()); + } + + private: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + ExtensionMessageService* message_service = + Source<Profile>(source).ptr()->GetExtensionMessageService(); + + // Sends four messages to the extension. All but the third message sent + // from the origin http://b.com/ are supposed to arrive. + message_service->DispatchEventToRenderers("test.onMessage", + "[{\"lastMessage\":false,\"data\":\"no restriction\"}]", + Source<Profile>(source).ptr()->IsOffTheRecord(), + GURL()); + message_service->DispatchEventToRenderers("test.onMessage", + "[{\"lastMessage\":false,\"data\":\"http://a.com/\"}]", + Source<Profile>(source).ptr()->IsOffTheRecord(), + GURL("http://a.com/")); + message_service->DispatchEventToRenderers("test.onMessage", + "[{\"lastMessage\":false,\"data\":\"http://b.com/\"}]", + Source<Profile>(source).ptr()->IsOffTheRecord(), + GURL("http://b.com/")); + message_service->DispatchEventToRenderers("test.onMessage", + "[{\"lastMessage\":true,\"data\":\"last message\"}]", + Source<Profile>(source).ptr()->IsOffTheRecord(), + GURL()); + } + + NotificationRegistrar registrar_; +}; + +} // namespace // Tests that message passing between extensions and content scripts works. IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Messaging) { @@ -20,3 +64,10 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MessagingExternal) { ASSERT_TRUE(RunExtensionTest("messaging/connect_external")) << message_; } + +// Tests that messages with event_urls are only passed to extensions with +// appropriate permissions. +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MessagingEventURL) { + MessageSender sender; + ASSERT_TRUE(RunExtensionTest("messaging/event_url")) << message_; +} diff --git a/chrome/browser/extensions/extension_messages_unittest.cc b/chrome/browser/extensions/extension_messages_unittest.cc index 5d06654..b90e92f 100644 --- a/chrome/browser/extensions/extension_messages_unittest.cc +++ b/chrome/browser/extensions/extension_messages_unittest.cc @@ -18,14 +18,15 @@ static void DispatchOnConnect(int source_port_id, const std::string& name, args.Set(3, Value::CreateStringValue("")); // extension ID is empty for tests args.Set(4, Value::CreateStringValue("")); // extension ID is empty for tests RendererExtensionBindings::Invoke( - ExtensionMessageService::kDispatchOnConnect, args, NULL, false); + ExtensionMessageService::kDispatchOnConnect, args, NULL, false, GURL()); } static void DispatchOnDisconnect(int source_port_id) { ListValue args; args.Set(0, Value::CreateIntegerValue(source_port_id)); RendererExtensionBindings::Invoke( - ExtensionMessageService::kDispatchOnDisconnect, args, NULL, false); + ExtensionMessageService::kDispatchOnDisconnect, args, NULL, false, + GURL()); } static void DispatchOnMessage(const std::string& message, int source_port_id) { @@ -33,7 +34,7 @@ static void DispatchOnMessage(const std::string& message, int source_port_id) { args.Set(0, Value::CreateStringValue(message)); args.Set(1, Value::CreateIntegerValue(source_port_id)); RendererExtensionBindings::Invoke( - ExtensionMessageService::kDispatchOnMessage, args, NULL, false); + ExtensionMessageService::kDispatchOnMessage, args, NULL, false, GURL()); } // Tests that the bindings for opening a channel to an extension and sending diff --git a/chrome/browser/extensions/extension_popup_api.cc b/chrome/browser/extensions/extension_popup_api.cc index f73dc7f..a6f85f2 100644 --- a/chrome/browser/extensions/extension_popup_api.cc +++ b/chrome/browser/extensions/extension_popup_api.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -353,5 +353,6 @@ void PopupEventRouter::OnPopupClosed(Profile* profile, profile->GetExtensionMessageService()->DispatchEventToRenderers( full_event_name, base::JSONWriter::kEmptyArray, - profile->IsOffTheRecord()); + profile->IsOffTheRecord(), + GURL()); } diff --git a/chrome/browser/extensions/extension_toolstrip_api.cc b/chrome/browser/extensions/extension_toolstrip_api.cc index a858150..3732c68 100644 --- a/chrome/browser/extensions/extension_toolstrip_api.cc +++ b/chrome/browser/extensions/extension_toolstrip_api.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -145,7 +145,7 @@ void ToolstripEventRouter::DispatchEvent(Profile *profile, base::JSONWriter::Write(&json, false, &json_args); std::string full_event_name = StringPrintf(event_name, routing_id); profile->GetExtensionMessageService()->DispatchEventToRenderers( - full_event_name, json_args, profile->IsOffTheRecord()); + full_event_name, json_args, profile->IsOffTheRecord(), GURL()); } } |