Chromium Code Reviews| Index: extensions/renderer/dispatcher.cc |
| diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc |
| index fcfb5a3a2b4cd526e5bb2407e38ef6fe86b203be..3c9afeb8b2eb5a36ac2201de66409bc7a82f34f3 100644 |
| --- a/extensions/renderer/dispatcher.cc |
| +++ b/extensions/renderer/dispatcher.cc |
| @@ -77,6 +77,7 @@ |
| #include "extensions/renderer/script_injection_manager.h" |
| #include "extensions/renderer/send_request_natives.h" |
| #include "extensions/renderer/set_icon_natives.h" |
| +#include "extensions/renderer/tab_finder.h" |
| #include "extensions/renderer/test_features_native_handler.h" |
| #include "extensions/renderer/user_gestures_native_handler.h" |
| #include "extensions/renderer/utils_native_handler.h" |
| @@ -769,6 +770,10 @@ bool Dispatcher::OnControlMessageReceived(const IPC::Message& message) { |
| IPC_MESSAGE_HANDLER(ExtensionMsg_TransferBlobs, OnTransferBlobs) |
| IPC_MESSAGE_HANDLER(ExtensionMsg_Unloaded, OnUnloaded) |
| IPC_MESSAGE_HANDLER(ExtensionMsg_UpdatePermissions, OnUpdatePermissions) |
| + IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateTabSpecificPermissions, |
| + OnUpdateTabSpecificPermissions) |
| + IPC_MESSAGE_HANDLER(ExtensionMsg_ClearTabSpecificPermissions, |
| + OnClearTabSpecificPermissions) |
| IPC_MESSAGE_HANDLER(ExtensionMsg_UsingWebRequestAPI, OnUsingWebRequestAPI) |
| IPC_MESSAGE_FORWARD(ExtensionMsg_WatchPages, |
| content_watcher_.get(), |
| @@ -1028,17 +1033,65 @@ void Dispatcher::OnUpdatePermissions( |
| scoped_refptr<const PermissionSet> withheld = |
| params.withheld_permissions.ToPermissionSet(); |
| - if (is_webkit_initialized_) { |
| - UpdateOriginPermissions( |
| - extension, |
| - extension->permissions_data()->GetEffectiveHostPermissions(), |
| - active->effective_hosts()); |
| - } |
| - |
| + URLPatternSet old_effective = |
| + extension->permissions_data()->GetEffectiveHostPermissions(); |
| extension->permissions_data()->SetPermissions(active, withheld); |
| + |
| + if (is_webkit_initialized_) |
| + UpdateOriginPermissions(extension, old_effective); |
| + |
| UpdateBindings(extension->id()); |
| } |
| +void Dispatcher::OnUpdateTabSpecificPermissions( |
| + const GURL& visible_url, |
| + const std::string& extension_id, |
| + const URLPatternSet& new_hosts, |
| + int tab_id) { |
| + // Check against the URL to avoid races. If we can't find the tab, it's |
| + // because this is an extension's background page (run in a different |
| + // process) - in this case, we can't perform the security check. However, |
| + // since activeTab is only granted via user action, this isn't a huge concern. |
| + content::RenderView* render_view = TabFinder::Find(tab_id); |
| + if (render_view && |
| + render_view->GetWebView()->mainFrame()->document().url() != visible_url) { |
| + return; |
| + } |
| + |
| + const Extension* extension = extensions_.GetByID(extension_id); |
| + if (!extension) |
| + return; |
| + |
| + URLPatternSet old_effective = |
| + extension->permissions_data()->GetEffectiveHostPermissions(); |
| + extension->permissions_data()->UpdateTabSpecificPermissions( |
| + tab_id, |
| + new extensions::PermissionSet(extensions::APIPermissionSet(), |
| + extensions::ManifestPermissionSet(), |
| + new_hosts, |
| + extensions::URLPatternSet())); |
| + |
| + if (is_webkit_initialized_ && |
| + ExtensionHelper::GetBackgroundPage(extension_id)) { |
| + UpdateOriginPermissions(extension, old_effective); |
|
not at google - send to devlin
2015/02/03 19:29:12
I was wondering why this is only happening for the
Devlin
2015/02/04 22:26:02
As discussed offline, we don't want to update the
|
| + } |
| +} |
| + |
| +void Dispatcher::OnClearTabSpecificPermissions( |
| + const std::vector<std::string>& extension_ids, |
| + int tab_id) { |
| + for (const std::string& id : extension_ids) { |
| + const Extension* extension = extensions_.GetByID(id); |
| + if (extension) { |
| + URLPatternSet old_effective = |
| + extension->permissions_data()->GetEffectiveHostPermissions(); |
| + extension->permissions_data()->ClearTabSpecificPermissions(tab_id); |
| + if (ExtensionHelper::GetBackgroundPage(id)) |
| + UpdateOriginPermissions(extension, old_effective); |
| + } |
| + } |
| +} |
| + |
| void Dispatcher::OnUsingWebRequestAPI(bool webrequest_used) { |
| webrequest_used_ = webrequest_used; |
| } |
| @@ -1058,16 +1111,11 @@ void Dispatcher::UpdateActiveExtensions() { |
| void Dispatcher::InitOriginPermissions(const Extension* extension) { |
| delegate_->InitOriginPermissions(extension, |
| IsExtensionActive(extension->id())); |
| - UpdateOriginPermissions( |
| - extension, |
| - URLPatternSet(), // No old permissions. |
| - extension->permissions_data()->GetEffectiveHostPermissions()); |
| + UpdateOriginPermissions(extension, URLPatternSet()); // No old permissions. |
| } |
| -void Dispatcher::UpdateOriginPermissions( |
| - const Extension* extension, |
| - const URLPatternSet& old_patterns, |
| - const URLPatternSet& new_patterns) { |
| +void Dispatcher::UpdateOriginPermissions(const Extension* extension, |
|
not at google - send to devlin
2015/02/03 19:29:12
Even though this method can determine new_patterns
Devlin
2015/02/04 22:26:02
Dumbified.
|
| + const URLPatternSet& old_patterns) { |
| static const char* kSchemes[] = { |
| url::kHttpScheme, |
| url::kHttpsScheme, |
| @@ -1075,28 +1123,36 @@ void Dispatcher::UpdateOriginPermissions( |
| content::kChromeUIScheme, |
| url::kFtpScheme, |
| }; |
| + URLPatternSet new_patterns = |
| + extension->permissions_data()->GetEffectiveHostPermissions(); |
| + |
| + // Remove those patterns that aren't present in the current permissions... |
| + URLPatternSet to_remove; |
| + URLPatternSet::CreateDifference(old_patterns, new_patterns, &to_remove); |
| + |
| + // ...And add the new ones. |
| + URLPatternSet to_add; |
| + URLPatternSet::CreateDifference(new_patterns, old_patterns, &to_add); |
| + |
| for (size_t i = 0; i < arraysize(kSchemes); ++i) { |
| const char* scheme = kSchemes[i]; |
| - // Remove all old patterns... |
| - for (URLPatternSet::const_iterator pattern = old_patterns.begin(); |
| - pattern != old_patterns.end(); ++pattern) { |
| - if (pattern->MatchesScheme(scheme)) { |
| + for (const URLPattern& pattern : to_remove) { |
| + if (pattern.MatchesScheme(scheme)) { |
| WebSecurityPolicy::removeOriginAccessWhitelistEntry( |
| extension->url(), |
| WebString::fromUTF8(scheme), |
| - WebString::fromUTF8(pattern->host()), |
| - pattern->match_subdomains()); |
| + WebString::fromUTF8(pattern.host()), |
| + pattern.match_subdomains()); |
| } |
| } |
| - // ...And add the new ones. |
| - for (URLPatternSet::const_iterator pattern = new_patterns.begin(); |
| - pattern != new_patterns.end(); ++pattern) { |
| - if (pattern->MatchesScheme(scheme)) { |
| + |
| + for (const URLPattern& pattern : to_add) { |
| + if (pattern.MatchesScheme(scheme)) { |
| WebSecurityPolicy::addOriginAccessWhitelistEntry( |
| extension->url(), |
| WebString::fromUTF8(scheme), |
| - WebString::fromUTF8(pattern->host()), |
| - pattern->match_subdomains()); |
| + WebString::fromUTF8(pattern.host()), |
| + pattern.match_subdomains()); |
| } |
| } |
| } |