| OLD | NEW |
| 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 "chrome/browser/extensions/active_tab_permission_granter.h" | 5 #include "chrome/browser/extensions/active_tab_permission_granter.h" |
| 6 | 6 |
| 7 #include "chrome/browser/extensions/active_script_controller.h" | 7 #include "chrome/browser/extensions/active_script_controller.h" |
| 8 #include "chrome/browser/profiles/profile.h" | 8 #include "chrome/browser/profiles/profile.h" |
| 9 #include "content/public/browser/navigation_details.h" | 9 #include "content/public/browser/navigation_details.h" |
| 10 #include "content/public/browser/navigation_entry.h" | 10 #include "content/public/browser/navigation_entry.h" |
| 11 #include "content/public/browser/render_process_host.h" |
| 11 #include "content/public/browser/render_view_host.h" | 12 #include "content/public/browser/render_view_host.h" |
| 12 #include "content/public/browser/web_contents.h" | 13 #include "content/public/browser/web_contents.h" |
| 13 #include "extensions/browser/extension_registry.h" | 14 #include "extensions/browser/extension_registry.h" |
| 15 #include "extensions/browser/process_manager.h" |
| 14 #include "extensions/common/extension_messages.h" | 16 #include "extensions/common/extension_messages.h" |
| 15 #include "extensions/common/feature_switch.h" | 17 #include "extensions/common/feature_switch.h" |
| 16 #include "extensions/common/permissions/permission_set.h" | 18 #include "extensions/common/permissions/permission_set.h" |
| 17 #include "extensions/common/permissions/permissions_data.h" | 19 #include "extensions/common/permissions/permissions_data.h" |
| 18 #include "extensions/common/user_script.h" | 20 #include "extensions/common/user_script.h" |
| 19 #include "url/gurl.h" | 21 #include "url/gurl.h" |
| 20 | 22 |
| 21 using content::RenderProcessHost; | 23 namespace extensions { |
| 22 using content::WebContentsObserver; | |
| 23 | 24 |
| 24 namespace extensions { | 25 namespace { |
| 26 |
| 27 using CreateMessageFunction = base::Callback<IPC::Message*(bool)>; |
| 28 |
| 29 // Creates a new IPC message for updating tab-specific permissions. |
| 30 IPC::Message* CreateUpdateMessage(const GURL& visible_url, |
| 31 const std::string& extension_id, |
| 32 const URLPatternSet& new_hosts, |
| 33 int tab_id, |
| 34 bool update_whitelist) { |
| 35 return new ExtensionMsg_UpdateTabSpecificPermissions( |
| 36 visible_url, extension_id, new_hosts, update_whitelist, tab_id); |
| 37 } |
| 38 |
| 39 // Creates a new IPC message for clearing tab-specific permissions. |
| 40 IPC::Message* CreateClearMessage(const std::vector<std::string>& ids, |
| 41 int tab_id, |
| 42 bool update_whitelist) { |
| 43 return new ExtensionMsg_ClearTabSpecificPermissions( |
| 44 ids, update_whitelist, tab_id); |
| 45 } |
| 46 |
| 47 // Sends a message exactly once to each render process host owning one of the |
| 48 // given |view_hosts| and |tab_process|. If |tab_process| doesn't own any of the |
| 49 // |view_hosts|, it will not be signaled to update its origin whitelist. |
| 50 void SendMessageToProcesses( |
| 51 const std::set<content::RenderViewHost*>& view_hosts, |
| 52 content::RenderProcessHost* tab_process, |
| 53 const CreateMessageFunction& create_message) { |
| 54 std::set<content::RenderProcessHost*> sent_to_hosts; |
| 55 for (content::RenderViewHost* view_host : view_hosts) { |
| 56 content::RenderProcessHost* process_host = view_host->GetProcess(); |
| 57 if (sent_to_hosts.count(process_host) == 0) { |
| 58 // Extension processes have to update the origin whitelists. |
| 59 process_host->Send(create_message.Run(true)); |
| 60 sent_to_hosts.insert(view_host->GetProcess()); |
| 61 } |
| 62 } |
| 63 // If the tab wasn't one of those processes already updated (it likely |
| 64 // wasn't), update it. Tabs don't need to update the origin whitelist. |
| 65 if (sent_to_hosts.count(tab_process) == 0) |
| 66 tab_process->Send(create_message.Run(false)); |
| 67 } |
| 68 |
| 69 } // namespace |
| 25 | 70 |
| 26 ActiveTabPermissionGranter::ActiveTabPermissionGranter( | 71 ActiveTabPermissionGranter::ActiveTabPermissionGranter( |
| 27 content::WebContents* web_contents, | 72 content::WebContents* web_contents, |
| 28 int tab_id, | 73 int tab_id, |
| 29 Profile* profile) | 74 Profile* profile) |
| 30 : WebContentsObserver(web_contents), | 75 : content::WebContentsObserver(web_contents), |
| 31 tab_id_(tab_id), | 76 tab_id_(tab_id), |
| 32 extension_registry_observer_(this) { | 77 extension_registry_observer_(this) { |
| 33 extension_registry_observer_.Add(ExtensionRegistry::Get(profile)); | 78 extension_registry_observer_.Add(ExtensionRegistry::Get(profile)); |
| 34 } | 79 } |
| 35 | 80 |
| 36 ActiveTabPermissionGranter::~ActiveTabPermissionGranter() {} | 81 ActiveTabPermissionGranter::~ActiveTabPermissionGranter() {} |
| 37 | 82 |
| 38 void ActiveTabPermissionGranter::GrantIfRequested(const Extension* extension) { | 83 void ActiveTabPermissionGranter::GrantIfRequested(const Extension* extension) { |
| 39 if (granted_extensions_.Contains(extension->id())) | 84 if (granted_extensions_.Contains(extension->id())) |
| 40 return; | 85 return; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 59 | 104 |
| 60 if (!new_apis.empty() || !new_hosts.is_empty()) { | 105 if (!new_apis.empty() || !new_hosts.is_empty()) { |
| 61 granted_extensions_.Insert(extension); | 106 granted_extensions_.Insert(extension); |
| 62 scoped_refptr<const PermissionSet> new_permissions = | 107 scoped_refptr<const PermissionSet> new_permissions = |
| 63 new PermissionSet(new_apis, ManifestPermissionSet(), | 108 new PermissionSet(new_apis, ManifestPermissionSet(), |
| 64 new_hosts, URLPatternSet()); | 109 new_hosts, URLPatternSet()); |
| 65 permissions_data->UpdateTabSpecificPermissions(tab_id_, new_permissions); | 110 permissions_data->UpdateTabSpecificPermissions(tab_id_, new_permissions); |
| 66 const content::NavigationEntry* navigation_entry = | 111 const content::NavigationEntry* navigation_entry = |
| 67 web_contents()->GetController().GetVisibleEntry(); | 112 web_contents()->GetController().GetVisibleEntry(); |
| 68 if (navigation_entry) { | 113 if (navigation_entry) { |
| 69 content::RenderViewHost* render_view_host = | 114 // We update all extension render views with the new tab permissions, and |
| 70 web_contents()->GetRenderViewHost(); | 115 // also the tab itself. |
| 71 render_view_host->Send(new ExtensionMsg_UpdateTabSpecificPermissions( | 116 CreateMessageFunction update_message = |
| 72 render_view_host->GetRoutingID(), | 117 base::Bind(&CreateUpdateMessage, |
| 73 navigation_entry->GetURL(), | 118 navigation_entry->GetURL(), |
| 74 extension->id(), | 119 extension->id(), |
| 75 new_hosts)); | 120 new_hosts, |
| 121 tab_id_); |
| 122 SendMessageToProcesses( |
| 123 ProcessManager::Get(web_contents()->GetBrowserContext())-> |
| 124 GetRenderViewHostsForExtension(extension->id()), |
| 125 web_contents()->GetRenderProcessHost(), |
| 126 update_message); |
| 127 |
| 76 // If more things ever need to know about this, we should consider making | 128 // If more things ever need to know about this, we should consider making |
| 77 // an observer class. | 129 // an observer class. |
| 78 // It's important that this comes after the IPC is sent to the renderer, | 130 // It's important that this comes after the IPC is sent to the renderer, |
| 79 // so that any tasks executing in the renderer occur after it has the | 131 // so that any tasks executing in the renderer occur after it has the |
| 80 // updated permissions. | 132 // updated permissions. |
| 81 ActiveScriptController::GetForWebContents(web_contents()) | 133 ActiveScriptController::GetForWebContents(web_contents()) |
| 82 ->OnActiveTabPermissionGranted(extension); | 134 ->OnActiveTabPermissionGranted(extension); |
| 83 } | 135 } |
| 84 } | 136 } |
| 85 } | 137 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 UnloadedExtensionInfo::Reason reason) { | 173 UnloadedExtensionInfo::Reason reason) { |
| 122 // Note: don't need to clear the permissions (nor tell the renderer about it) | 174 // Note: don't need to clear the permissions (nor tell the renderer about it) |
| 123 // because it's being unloaded anyway. | 175 // because it's being unloaded anyway. |
| 124 granted_extensions_.Remove(extension->id()); | 176 granted_extensions_.Remove(extension->id()); |
| 125 } | 177 } |
| 126 | 178 |
| 127 void ActiveTabPermissionGranter::ClearActiveExtensionsAndNotify() { | 179 void ActiveTabPermissionGranter::ClearActiveExtensionsAndNotify() { |
| 128 if (granted_extensions_.is_empty()) | 180 if (granted_extensions_.is_empty()) |
| 129 return; | 181 return; |
| 130 | 182 |
| 183 std::set<content::RenderViewHost*> view_hosts; |
| 131 std::vector<std::string> extension_ids; | 184 std::vector<std::string> extension_ids; |
| 132 | 185 ProcessManager* process_manager = |
| 133 for (ExtensionSet::const_iterator it = granted_extensions_.begin(); | 186 ProcessManager::Get(web_contents()->GetBrowserContext()); |
| 134 it != granted_extensions_.end(); ++it) { | 187 for (const scoped_refptr<const Extension>& extension : granted_extensions_) { |
| 135 it->get()->permissions_data()->ClearTabSpecificPermissions(tab_id_); | 188 extension->permissions_data()->ClearTabSpecificPermissions(tab_id_); |
| 136 extension_ids.push_back((*it)->id()); | 189 extension_ids.push_back(extension->id()); |
| 190 std::set<content::RenderViewHost*> extension_view_hosts = |
| 191 process_manager->GetRenderViewHostsForExtension(extension->id()); |
| 192 view_hosts.insert(extension_view_hosts.begin(), extension_view_hosts.end()); |
| 137 } | 193 } |
| 138 | 194 |
| 139 content::RenderViewHost* render_view_host = | 195 CreateMessageFunction clear_message = |
| 140 web_contents()->GetRenderViewHost(); | 196 base::Bind(&CreateClearMessage, extension_ids, tab_id_); |
| 141 render_view_host->Send(new ExtensionMsg_ClearTabSpecificPermissions( | 197 SendMessageToProcesses(view_hosts, |
| 142 render_view_host->GetRoutingID(), extension_ids)); | 198 web_contents()->GetRenderProcessHost(), |
| 199 clear_message); |
| 200 |
| 143 granted_extensions_.Clear(); | 201 granted_extensions_.Clear(); |
| 144 } | 202 } |
| 145 | 203 |
| 146 } // namespace extensions | 204 } // namespace extensions |
| OLD | NEW |