| Index: chrome/common/extensions/permissions/permission_set.cc
|
| diff --git a/chrome/common/extensions/permissions/permission_set.cc b/chrome/common/extensions/permissions/permission_set.cc
|
| index d027605f281369a3562aea726b88d388870d2997..9c9701463d516900e2f512bdfa4dbfe3eb34f699 100644
|
| --- a/chrome/common/extensions/permissions/permission_set.cc
|
| +++ b/chrome/common/extensions/permissions/permission_set.cc
|
| @@ -8,35 +8,15 @@
|
| #include <iterator>
|
| #include <string>
|
|
|
| -#include "base/stl_util.h"
|
| -#include "chrome/common/extensions/permissions/permission_message_util.h"
|
| -#include "content/public/common/url_constants.h"
|
| -#include "extensions/common/extensions_client.h"
|
| #include "extensions/common/permissions/permissions_info.h"
|
| #include "extensions/common/url_pattern.h"
|
| #include "extensions/common/url_pattern_set.h"
|
| -#include "grit/generated_resources.h"
|
| -#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
|
| -#include "ui/base/l10n/l10n_util.h"
|
| #include "url/gurl.h"
|
|
|
| using extensions::URLPatternSet;
|
|
|
| namespace {
|
|
|
| -// Helper for GetDistinctHosts(): com > net > org > everything else.
|
| -bool RcdBetterThan(const std::string& a, const std::string& b) {
|
| - if (a == b)
|
| - return false;
|
| - if (a == "com")
|
| - return true;
|
| - if (a == "net")
|
| - return b != "com";
|
| - if (a == "org")
|
| - return b != "com" && b != "net";
|
| - return false;
|
| -}
|
| -
|
| void AddPatternsAndRemovePaths(const URLPatternSet& set, URLPatternSet* out) {
|
| DCHECK(out);
|
| for (URLPatternSet::const_iterator i = set.begin(); i != set.end(); ++i) {
|
| @@ -161,97 +141,6 @@ std::set<std::string> PermissionSet::GetAPIsAsStrings() const {
|
| return apis_str;
|
| }
|
|
|
| -PermissionMessages PermissionSet::GetPermissionMessages(
|
| - Manifest::Type extension_type) const {
|
| - PermissionMessages messages;
|
| -
|
| - if (HasEffectiveFullAccess()) {
|
| - messages.push_back(PermissionMessage(
|
| - PermissionMessage::kFullAccess,
|
| - l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS)));
|
| - return messages;
|
| - }
|
| -
|
| - std::set<PermissionMessage> host_msgs =
|
| - GetHostPermissionMessages(extension_type);
|
| - std::set<PermissionMessage> api_msgs = GetAPIPermissionMessages();
|
| - messages.insert(messages.end(), host_msgs.begin(), host_msgs.end());
|
| - messages.insert(messages.end(), api_msgs.begin(), api_msgs.end());
|
| -
|
| - return messages;
|
| -}
|
| -
|
| -std::vector<string16> PermissionSet::GetWarningMessages(
|
| - Manifest::Type extension_type) const {
|
| - std::vector<string16> messages;
|
| - PermissionMessages permissions = GetPermissionMessages(extension_type);
|
| -
|
| - bool audio_capture = false;
|
| - bool video_capture = false;
|
| - bool media_galleries_read = false;
|
| - bool media_galleries_copy_to = false;
|
| - for (PermissionMessages::const_iterator i = permissions.begin();
|
| - i != permissions.end(); ++i) {
|
| - switch (i->id()) {
|
| - case PermissionMessage::kAudioCapture:
|
| - audio_capture = true;
|
| - break;
|
| - case PermissionMessage::kVideoCapture:
|
| - video_capture = true;
|
| - break;
|
| - case PermissionMessage::kMediaGalleriesAllGalleriesRead:
|
| - media_galleries_read = true;
|
| - break;
|
| - case PermissionMessage::kMediaGalleriesAllGalleriesCopyTo:
|
| - media_galleries_copy_to = true;
|
| - break;
|
| - default:
|
| - break;
|
| - }
|
| - }
|
| -
|
| - for (PermissionMessages::const_iterator i = permissions.begin();
|
| - i != permissions.end(); ++i) {
|
| - int id = i->id();
|
| - if (audio_capture && video_capture) {
|
| - if (id == PermissionMessage::kAudioCapture) {
|
| - messages.push_back(l10n_util::GetStringUTF16(
|
| - IDS_EXTENSION_PROMPT_WARNING_AUDIO_AND_VIDEO_CAPTURE));
|
| - continue;
|
| - } else if (id == PermissionMessage::kVideoCapture) {
|
| - // The combined message will be pushed above.
|
| - continue;
|
| - }
|
| - }
|
| - if (media_galleries_read && media_galleries_copy_to) {
|
| - if (id == PermissionMessage::kMediaGalleriesAllGalleriesRead) {
|
| - messages.push_back(l10n_util::GetStringUTF16(
|
| - IDS_EXTENSION_PROMPT_WARNING_MEDIA_GALLERIES_READ_WRITE));
|
| - continue;
|
| - } else if (id == PermissionMessage::kMediaGalleriesAllGalleriesCopyTo) {
|
| - // The combined message will be pushed above.
|
| - continue;
|
| - }
|
| - }
|
| -
|
| - messages.push_back(i->message());
|
| - }
|
| -
|
| - return messages;
|
| -}
|
| -
|
| -std::vector<string16> PermissionSet::GetWarningMessagesDetails(
|
| - Manifest::Type extension_type) const {
|
| - std::vector<string16> messages;
|
| - PermissionMessages permissions = GetPermissionMessages(extension_type);
|
| -
|
| - for (PermissionMessages::const_iterator i = permissions.begin();
|
| - i != permissions.end(); ++i)
|
| - messages.push_back(i->details());
|
| -
|
| - return messages;
|
| -}
|
| -
|
| bool PermissionSet::IsEmpty() const {
|
| // Not default if any host permissions are present.
|
| if (!(explicit_hosts().is_empty() && scriptable_hosts().is_empty()))
|
| @@ -331,84 +220,8 @@ bool PermissionSet::HasEffectiveFullAccess() const {
|
| return false;
|
| }
|
|
|
| -bool PermissionSet::HasLessPrivilegesThan(
|
| - const PermissionSet* permissions,
|
| - Manifest::Type extension_type) const {
|
| - // Things can't get worse than native code access.
|
| - if (HasEffectiveFullAccess())
|
| - return false;
|
| -
|
| - // Otherwise, it's a privilege increase if the new one has full access.
|
| - if (permissions->HasEffectiveFullAccess())
|
| - return true;
|
| -
|
| - if (HasLessHostPrivilegesThan(permissions, extension_type))
|
| - return true;
|
| -
|
| - if (HasLessAPIPrivilegesThan(permissions))
|
| - return true;
|
| -
|
| - return false;
|
| -}
|
| -
|
| PermissionSet::~PermissionSet() {}
|
|
|
| -// static
|
| -std::set<std::string> PermissionSet::GetDistinctHosts(
|
| - const URLPatternSet& host_patterns,
|
| - bool include_rcd,
|
| - bool exclude_file_scheme) {
|
| - // Use a vector to preserve order (also faster than a map on small sets).
|
| - // Each item is a host split into two parts: host without RCDs and
|
| - // current best RCD.
|
| - typedef std::vector<std::pair<std::string, std::string> > HostVector;
|
| - HostVector hosts_best_rcd;
|
| - for (URLPatternSet::const_iterator i = host_patterns.begin();
|
| - i != host_patterns.end(); ++i) {
|
| - if (exclude_file_scheme && i->scheme() == chrome::kFileScheme)
|
| - continue;
|
| -
|
| - std::string host = i->host();
|
| -
|
| - // Add the subdomain wildcard back to the host, if necessary.
|
| - if (i->match_subdomains())
|
| - host = "*." + host;
|
| -
|
| - // If the host has an RCD, split it off so we can detect duplicates.
|
| - std::string rcd;
|
| - size_t reg_len = net::registry_controlled_domains::GetRegistryLength(
|
| - host,
|
| - net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES,
|
| - net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
|
| - if (reg_len && reg_len != std::string::npos) {
|
| - if (include_rcd) // else leave rcd empty
|
| - rcd = host.substr(host.size() - reg_len);
|
| - host = host.substr(0, host.size() - reg_len);
|
| - }
|
| -
|
| - // Check if we've already seen this host.
|
| - HostVector::iterator it = hosts_best_rcd.begin();
|
| - for (; it != hosts_best_rcd.end(); ++it) {
|
| - if (it->first == host)
|
| - break;
|
| - }
|
| - // If this host was found, replace the RCD if this one is better.
|
| - if (it != hosts_best_rcd.end()) {
|
| - if (include_rcd && RcdBetterThan(rcd, it->second))
|
| - it->second = rcd;
|
| - } else { // Previously unseen host, append it.
|
| - hosts_best_rcd.push_back(std::make_pair(host, rcd));
|
| - }
|
| - }
|
| -
|
| - // Build up the final vector by concatenating hosts and RCDs.
|
| - std::set<std::string> distinct_hosts;
|
| - for (HostVector::iterator it = hosts_best_rcd.begin();
|
| - it != hosts_best_rcd.end(); ++it)
|
| - distinct_hosts.insert(it->first + it->second);
|
| - return distinct_hosts;
|
| -}
|
| -
|
| void PermissionSet::InitImplicitPermissions() {
|
| // The downloads permission implies the internal version as well.
|
| if (apis_.find(APIPermission::kDownloads) != apis_.end())
|
| @@ -435,127 +248,4 @@ void PermissionSet::InitEffectiveHosts() {
|
| explicit_hosts(), scriptable_hosts(), &effective_hosts_);
|
| }
|
|
|
| -std::set<PermissionMessage> PermissionSet::GetAPIPermissionMessages() const {
|
| - std::set<PermissionMessage> messages;
|
| - for (APIPermissionSet::const_iterator permission_it = apis_.begin();
|
| - permission_it != apis_.end(); ++permission_it) {
|
| - if (permission_it->HasMessages()) {
|
| - PermissionMessages new_messages = permission_it->GetMessages();
|
| - messages.insert(new_messages.begin(), new_messages.end());
|
| - }
|
| - }
|
| -
|
| - // A special hack: If kFileSystemWriteDirectory would be displayed, hide
|
| - // kFileSystemDirectory and and kFileSystemWrite as the write directory
|
| - // message implies the other two.
|
| - // TODO(sammc): Remove this. See http://crbug.com/284849.
|
| - std::set<PermissionMessage>::iterator write_directory_message =
|
| - messages.find(PermissionMessage(
|
| - PermissionMessage::kFileSystemWriteDirectory, string16()));
|
| - if (write_directory_message != messages.end()) {
|
| - messages.erase(
|
| - PermissionMessage(PermissionMessage::kFileSystemWrite, string16()));
|
| - messages.erase(
|
| - PermissionMessage(PermissionMessage::kFileSystemDirectory, string16()));
|
| - }
|
| -
|
| - // A special hack: The warning message for declarativeWebRequest
|
| - // permissions speaks about blocking parts of pages, which is a
|
| - // subset of what the "<all_urls>" access allows. Therefore we
|
| - // display only the "<all_urls>" warning message if both permissions
|
| - // are required.
|
| - if (HasEffectiveAccessToAllHosts()) {
|
| - messages.erase(
|
| - PermissionMessage(
|
| - PermissionMessage::kDeclarativeWebRequest, string16()));
|
| - }
|
| -
|
| - return messages;
|
| -}
|
| -
|
| -std::set<PermissionMessage> PermissionSet::GetHostPermissionMessages(
|
| - Manifest::Type extension_type) const {
|
| - // Since platform apps always use isolated storage, they can't (silently)
|
| - // access user data on other domains, so there's no need to prompt.
|
| - // Note: this must remain consistent with HasLessHostPrivilegesThan.
|
| - // See crbug.com/255229.
|
| - std::set<PermissionMessage> messages;
|
| - if (extension_type == Manifest::TYPE_PLATFORM_APP)
|
| - return messages;
|
| -
|
| - if (HasEffectiveAccessToAllHosts()) {
|
| - messages.insert(PermissionMessage(
|
| - PermissionMessage::kHostsAll,
|
| - l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS)));
|
| - } else {
|
| - URLPatternSet regular_hosts;
|
| - ExtensionsClient::Get()->FilterHostPermissions(
|
| - effective_hosts_, ®ular_hosts, &messages);
|
| -
|
| - std::set<std::string> hosts = GetDistinctHosts(regular_hosts, true, true);
|
| - if (!hosts.empty())
|
| - messages.insert(permission_message_util::CreateFromHostList(hosts));
|
| - }
|
| - return messages;
|
| -}
|
| -
|
| -bool PermissionSet::HasLessAPIPrivilegesThan(
|
| - const PermissionSet* permissions) const {
|
| - if (permissions == NULL)
|
| - return false;
|
| -
|
| - typedef std::set<PermissionMessage> PermissionMsgSet;
|
| - PermissionMsgSet current_warnings = GetAPIPermissionMessages();
|
| - PermissionMsgSet new_warnings = permissions->GetAPIPermissionMessages();
|
| - PermissionMsgSet delta_warnings =
|
| - base::STLSetDifference<PermissionMsgSet>(new_warnings, current_warnings);
|
| -
|
| - // A special hack: kFileSystemWriteDirectory implies kFileSystemDirectory and
|
| - // kFileSystemWrite.
|
| - // TODO(sammc): Remove this. See http://crbug.com/284849.
|
| - if (current_warnings.find(PermissionMessage(
|
| - PermissionMessage::kFileSystemWriteDirectory, string16())) !=
|
| - current_warnings.end()) {
|
| - delta_warnings.erase(
|
| - PermissionMessage(PermissionMessage::kFileSystemDirectory, string16()));
|
| - delta_warnings.erase(
|
| - PermissionMessage(PermissionMessage::kFileSystemWrite, string16()));
|
| - }
|
| -
|
| - // We have less privileges if there are additional warnings present.
|
| - return !delta_warnings.empty();
|
| -}
|
| -
|
| -bool PermissionSet::HasLessHostPrivilegesThan(
|
| - const PermissionSet* permissions,
|
| - Manifest::Type extension_type) const {
|
| - // Platform apps host permission changes do not count as privilege increases.
|
| - // Note: this must remain consistent with GetHostPermissionMessages.
|
| - if (extension_type == Manifest::TYPE_PLATFORM_APP)
|
| - return false;
|
| -
|
| - // If this permission set can access any host, then it can't be elevated.
|
| - if (HasEffectiveAccessToAllHosts())
|
| - return false;
|
| -
|
| - // Likewise, if the other permission set has full host access, then it must be
|
| - // a privilege increase.
|
| - if (permissions->HasEffectiveAccessToAllHosts())
|
| - return true;
|
| -
|
| - const URLPatternSet& old_list = effective_hosts();
|
| - const URLPatternSet& new_list = permissions->effective_hosts();
|
| -
|
| - // TODO(jstritar): This is overly conservative with respect to subdomains.
|
| - // For example, going from *.google.com to www.google.com will be
|
| - // considered an elevation, even though it is not (http://crbug.com/65337).
|
| - std::set<std::string> new_hosts_set(GetDistinctHosts(new_list, false, false));
|
| - std::set<std::string> old_hosts_set(GetDistinctHosts(old_list, false, false));
|
| - std::set<std::string> new_hosts_only =
|
| - base::STLSetDifference<std::set<std::string> >(new_hosts_set,
|
| - old_hosts_set);
|
| -
|
| - return !new_hosts_only.empty();
|
| -}
|
| -
|
| } // namespace extensions
|
|
|