Commit 3dd05ace authored by sashab's avatar sashab Committed by Commit bot

Added PermissionIDSet to APIPermissions

Added a GetPermissions() method to APIPermissions, which returns the
PermissionIDSet for that API permission. This will be used for the new
permission messages system, which can generate
CoalescedPermissionMessages from these permissions.

BUG=398257

Review URL: https://codereview.chromium.org/795543002

Cr-Commit-Position: refs/heads/master@{#308034}
parent 6c7a2468
......@@ -318,15 +318,11 @@ void SocketsManifestPermission::AddSubdomainHostMessage(
std::vector<base::string16>(domains.begin(), domains.end()),
' '))));
// TODO(sashab): Add rules to ChromePermissionMessageProvider:
// kSocketDomainHostsSingular ->
// IDS_EXTENSION_PROMPT_WARNING_SOCKET_HOSTS_IN_DOMAIN
// kSocketDomainHostsPlural ->
// IDS_EXTENSION_PROMPT_WARNING_SOCKET_HOSTS_IN_DOMAINS
APIPermission::ID pid = (domains.size() == 1)
? APIPermission::kSocketDomainHostsSingular
: APIPermission::kSocketDomainHostsPlural;
// kSocketDomainHosts ->
// IDS_EXTENSION_PROMPT_WARNING_SOCKET_HOSTS_IN_DOMAIN if 1
// IDS_EXTENSION_PROMPT_WARNING_SOCKET_HOSTS_IN_DOMAINS if many
for (const auto& domain : domains)
ids.insert(pid, domain);
ids.insert(APIPermission::kSocketDomainHosts, domain);
}
}
......@@ -354,15 +350,11 @@ void SocketsManifestPermission::AddSpecificHostMessage(
std::vector<base::string16>(hostnames.begin(), hostnames.end()),
' '))));
// TODO(sashab): Add rules to ChromePermissionMessageProvider:
// kSocketSpecificHostsSingular ->
// IDS_EXTENSION_PROMPT_WARNING_SOCKET_SPECIFIC_HOST
// kSocketSpecificHostsPlural ->
// IDS_EXTENSION_PROMPT_WARNING_SOCKET_SPECIFIC_HOSTS
APIPermission::ID pid = (hostnames.size() == 1)
? APIPermission::kSocketSpecificHostsSingular
: APIPermission::kSocketSpecificHostsPlural;
// kSocketSpecificHosts ->
// IDS_EXTENSION_PROMPT_WARNING_SOCKET_SPECIFIC_HOST if 1
// IDS_EXTENSION_PROMPT_WARNING_SOCKET_SPECIFIC_HOSTS if many
for (const auto& hostname : hostnames)
ids.insert(pid, hostname);
ids.insert(APIPermission::kSocketSpecificHosts, hostname);
}
}
......
......@@ -4,6 +4,7 @@
#include "extensions/common/permissions/api_permission.h"
#include "extensions/common/permissions/api_permission_set.h"
#include "ui/base/l10n/l10n_util.h"
namespace {
......@@ -20,6 +21,10 @@ class SimpleAPIPermission : public APIPermission {
~SimpleAPIPermission() override {}
extensions::PermissionIDSet GetPermissions() const override {
return extensions::PermissionIDSet(id());
}
bool HasMessages() const override {
return info()->message_id() > PermissionMessage::kNone;
}
......
......@@ -21,6 +21,7 @@ class Message;
namespace extensions {
class PermissionIDSet;
class APIPermissionInfo;
class ChromeAPIPermissions;
......@@ -214,13 +215,18 @@ class APIPermission {
kHostReadWrite,
kHostsAll,
kHostsAllReadOnly,
kMediaGalleriesAllGalleriesCopyTo,
kMediaGalleriesAllGalleriesDelete,
kMediaGalleriesAllGalleriesRead,
kNetworkState,
kOverrideBookmarksUI,
kShouldWarnAllHosts,
kSocketAnyHost,
kSocketDomainHostsSingular,
kSocketDomainHostsPlural,
kSocketSpecificHostsSingular,
kSocketSpecificHostsPlural,
kNetworkState,
kSocketDomainHosts,
kSocketSpecificHosts,
kUsbDeviceList,
kUsbDeviceUnknownProduct,
kUsbDeviceUnknownVendor,
kEnumBoundary
};
......@@ -243,10 +249,33 @@ class APIPermission {
return info_;
}
// The set of permissions an app/extension with this API permission has. These
// permissions are used by PermissionMessageProvider to generate meaningful
// permission messages for the app/extension.
//
// For simple API permissions, this will return a set containing only the ID
// of the permission. More complex permissions might have multiple IDs, one
// for each of the capabilities the API permission has (e.g. read, write and
// copy, in the case of the media gallery permission). Permissions that
// require parameters may also contain a parameter string (along with the
// permission's ID) which can be substituted into the permission message if a
// rule is defined to do so.
//
// Permissions with multiple values, such as host permissions, are represented
// by multiple entries in this set. Each permission in the subset has the same
// ID (e.g. kHostReadOnly) but a different parameter (e.g. google.com). These
// are grouped to form different kinds of permission messages (e.g. 'Access to
// 2 hosts') depending on the number that are in the set. The rules that
// define the grouping of related permissions with the same ID is defined in
// ChromePermissionMessageProvider.
virtual PermissionIDSet GetPermissions() const = 0;
// Returns true if this permission has any PermissionMessages.
// TODO(sashab): Deprecate this in favor of GetPermissions() above.
virtual bool HasMessages() const = 0;
// Returns the localized permission messages of this permission.
// TODO(sashab): Deprecate this in favor of GetPermissions() above.
virtual PermissionMessages GetMessages() const = 0;
// Returns true if the given permission is allowed.
......
......@@ -183,47 +183,91 @@ void APIPermissionSet::AddImpliedPermissions() {
}
}
PermissionIDSet::PermissionIDSet() : permissions() {
PermissionID::PermissionID(APIPermission::ID id)
: std::pair<APIPermission::ID, base::string16>(id, base::string16()) {
}
PermissionID::PermissionID(APIPermission::ID id,
const base::string16& parameter)
: std::pair<APIPermission::ID, base::string16>(id, parameter) {
}
PermissionID::~PermissionID() {
}
PermissionIDSet::PermissionIDSet() : permissions_() {
}
PermissionIDSet::~PermissionIDSet() {
}
PermissionIDSet::PermissionIDSet(APIPermission::ID permission_one) {
PermissionIDSet::PermissionIDSet(APIPermission::ID permission_one)
: permissions_() {
insert(permission_one);
}
PermissionIDSet::PermissionIDSet(APIPermission::ID permission_one,
APIPermission::ID permission_two)
: permissions_() {
insert(permission_one);
insert(permission_two);
}
PermissionIDSet::PermissionIDSet(APIPermission::ID permission_one,
APIPermission::ID permission_two,
APIPermission::ID permission_three)
: permissions_() {
insert(permission_one);
insert(permission_two);
insert(permission_three);
}
PermissionIDSet::PermissionIDSet(APIPermission::ID permission_one,
APIPermission::ID permission_two) {
APIPermission::ID permission_two,
APIPermission::ID permission_three,
APIPermission::ID permission_four)
: permissions_() {
insert(permission_one);
insert(permission_two);
insert(permission_three);
insert(permission_four);
}
PermissionIDSet::PermissionIDSet(APIPermission::ID permission_one,
APIPermission::ID permission_two,
APIPermission::ID permission_three) {
APIPermission::ID permission_three,
APIPermission::ID permission_four,
APIPermission::ID permission_five)
: permissions_() {
insert(permission_one);
insert(permission_two);
insert(permission_three);
insert(permission_four);
insert(permission_five);
}
PermissionIDSet::PermissionIDSet(APIPermission::ID permission_one,
APIPermission::ID permission_two,
APIPermission::ID permission_three,
APIPermission::ID permission_four) {
APIPermission::ID permission_four,
APIPermission::ID permission_five,
APIPermission::ID permission_six)
: permissions_() {
insert(permission_one);
insert(permission_two);
insert(permission_three);
insert(permission_four);
insert(permission_five);
insert(permission_six);
}
void PermissionIDSet::insert(APIPermission::ID permission) {
permissions.insert(PermissionID(permission, base::string16()));
void PermissionIDSet::insert(APIPermission::ID permission_id) {
permissions_.insert(PermissionID(permission_id, base::string16()));
}
void PermissionIDSet::insert(APIPermission::ID permission,
base::string16 permission_detail) {
permissions.insert(PermissionID(permission, permission_detail));
void PermissionIDSet::insert(APIPermission::ID permission_id,
base::string16 permission_parameter) {
permissions_.insert(PermissionID(permission_id, permission_parameter));
}
} // namespace extensions
......@@ -15,8 +15,9 @@ class ListValue;
namespace extensions {
class Extension;
class APIPermissionSet;
class Extension;
class PermissionIDSet;
template<>
struct BaseSetOperatorsTraits<APIPermissionSet> {
......@@ -60,6 +61,29 @@ class APIPermissionSet : public BaseSetOperators<APIPermissionSet> {
void AddImpliedPermissions();
};
// An ID representing a single permission that belongs to an app or extension.
//
// Each PermissionID has a required ID to identify the permission. For most
// permissions, this is all they have.
//
// Some more complex permissions have a parameter, which acts like an argument
// for the permission. For example, host permissions might have the ID
// kReadOnlyHost and the argument 'www.google.com' (the host which is
// read-only). Parameters are passed to the permission message rules for this
// permission, so they can affect the displayed message.
//
// TODO(sashab): Move this to the same file as PermissionIDSet once that moves
// to its own file.
class PermissionID : public std::pair<APIPermission::ID, base::string16> {
public:
PermissionID(APIPermission::ID id);
PermissionID(APIPermission::ID id, const base::string16& parameter);
virtual ~PermissionID();
const APIPermission::ID& id() const { return this->first; }
const base::string16& parameter() const { return this->second; }
};
// A set of permissions for an app or extension. Used for passing around groups
// of permissions, such as required or optional permissions. Has convenience
// constructors so that it can be constructed inline.
......@@ -76,14 +100,15 @@ class APIPermissionSet : public BaseSetOperators<APIPermissionSet> {
// PermissionIDSet p(APIPermission::kBluetooth, APIPermission::kFavicon);
// // Add a permission to the set.
// p.insertPermission(APIPermission::kNetworkState);
// // Add a permission with a detail to the set.
// // Add a permission with a parameter to the set.
// p.insertPermission(APIPermission::kHostReadOnly,
// base::ASCIIToUTF16("http://www.google.com"));
//
// TODO(sashab): Move this to its own file and rename it to PermissionSet after
// APIPermission is removed, the current PermissionSet is no longer used, and
// APIPermission::ID is the only type of Permission ID.
typedef std::pair<APIPermission::ID, base::string16> PermissionID;
// TODO(sashab): Change BaseSetOperators to support storing plain objects
// instead of pointers and change this to extend BaseSetOperators<PermissionID>.
class PermissionIDSet {
public:
PermissionIDSet();
......@@ -100,13 +125,25 @@ class PermissionIDSet {
APIPermission::ID permission_two,
APIPermission::ID permission_three,
APIPermission::ID permission_four);
PermissionIDSet(APIPermission::ID permission_one,
APIPermission::ID permission_two,
APIPermission::ID permission_three,
APIPermission::ID permission_four,
APIPermission::ID permission_five);
PermissionIDSet(APIPermission::ID permission_one,
APIPermission::ID permission_two,
APIPermission::ID permission_three,
APIPermission::ID permission_four,
APIPermission::ID permission_five,
APIPermission::ID permission_six);
// Adds the given permission, and an optional permission detail, to the set.
void insert(APIPermission::ID permission);
void insert(APIPermission::ID permission, base::string16 permission_detail);
// Adds the given permission, and an optional parameter, to the set.
void insert(APIPermission::ID permission_id);
void insert(APIPermission::ID permission_id,
base::string16 permission_parameter);
private:
std::set<PermissionID> permissions;
std::set<PermissionID> permissions_;
};
} // namespace extensions
......
......@@ -5,11 +5,9 @@
#ifndef EXTENSIONS_COMMON_PERMISSIONS_COALESCED_PERMISSION_MESSAGE_H_
#define EXTENSIONS_COMMON_PERMISSIONS_COALESCED_PERMISSION_MESSAGE_H_
#include <set>
#include <list>
#include <string>
#include "base/memory/scoped_vector.h"
#include "extensions/common/permissions/api_permission.h"
#include "extensions/common/permissions/api_permission_set.h"
namespace extensions {
......@@ -59,11 +57,11 @@ class CoalescedPermissionMessage {
const base::string16 message_;
const PermissionIDSet permissions_;
const std::vector<base::string16> submessages_;
DISALLOW_COPY_AND_ASSIGN(CoalescedPermissionMessage);
};
typedef std::vector<CoalescedPermissionMessage> CoalescedPermissionMessages;
// Use a linked list to store our list of messages, since we will commonly be
// iterating/removing elements but should never be accessing by index.
typedef std::list<CoalescedPermissionMessage> CoalescedPermissionMessages;
} // namespace extensions
......
......@@ -13,6 +13,8 @@
#include "grit/extensions_strings.h"
#include "ui/base/l10n/l10n_util.h"
namespace extensions {
namespace {
// copyTo permission requires delete permission as a prerequisite.
......@@ -36,9 +38,83 @@ bool IsValidPermissionSet(bool has_read, bool has_copy_to, bool has_delete,
return true;
}
} // namespace
// Adds the permissions from the |data_set| to the permission lists that are
// not NULL. If NULL, that list is ignored.
void AddPermissionsToLists(
const std::set<MediaGalleriesPermissionData>& data_set,
PermissionIDSet* ids,
PermissionMessages* messages) {
// TODO(sashab): Once GetMessages() is deprecated, move this logic back into
// GetPermissions().
bool has_all_auto_detected = false;
bool has_read = false;
bool has_copy_to = false;
bool has_delete = false;
namespace extensions {
for (std::set<MediaGalleriesPermissionData>::const_iterator it =
data_set.begin();
it != data_set.end(); ++it) {
if (it->permission() ==
MediaGalleriesPermission::kAllAutoDetectedPermission)
has_all_auto_detected = true;
else if (it->permission() == MediaGalleriesPermission::kReadPermission)
has_read = true;
else if (it->permission() == MediaGalleriesPermission::kCopyToPermission)
has_copy_to = true;
else if (it->permission() == MediaGalleriesPermission::kDeletePermission)
has_delete = true;
}
if (!IsValidPermissionSet(has_read, has_copy_to, has_delete, NULL)) {
NOTREACHED();
return;
}
// If |has_all_auto_detected| is false, then Chrome will prompt the user at
// runtime when the extension call the getMediaGalleries API.
if (!has_all_auto_detected)
return;
// No access permission case.
if (!has_read)
return;
// Separate PermissionMessage IDs for read, copyTo, and delete. Otherwise an
// extension can silently gain new access capabilities.
if (messages) {
messages->push_back(PermissionMessage(
PermissionMessage::kMediaGalleriesAllGalleriesRead,
l10n_util::GetStringUTF16(
IDS_EXTENSION_PROMPT_WARNING_MEDIA_GALLERIES_READ)));
}
if (ids)
ids->insert(APIPermission::kMediaGalleriesAllGalleriesRead);
// For copyTo and delete, the proper combined permission message will be
// derived in ChromePermissionMessageProvider::GetWarningMessages(), such
// that the user get 1 entry for all media galleries access permissions,
// rather than several separate entries.
if (has_copy_to) {
if (messages) {
messages->push_back(PermissionMessage(
PermissionMessage::kMediaGalleriesAllGalleriesCopyTo,
base::string16()));
}
if (ids)
ids->insert(APIPermission::kMediaGalleriesAllGalleriesCopyTo);
}
if (has_delete) {
if (messages) {
messages->push_back(PermissionMessage(
PermissionMessage::kMediaGalleriesAllGalleriesDelete,
base::string16()));
}
if (ids)
ids->insert(APIPermission::kMediaGalleriesAllGalleriesDelete);
}
return;
}
} // namespace
const char MediaGalleriesPermission::kAllAutoDetectedPermission[] =
"allAutoDetected";
......@@ -110,61 +186,17 @@ bool MediaGalleriesPermission::FromValue(
return IsValidPermissionSet(has_read, has_copy_to, has_delete, error);
}
PermissionIDSet MediaGalleriesPermission::GetPermissions() const {
DCHECK(HasMessages());
PermissionIDSet result;
AddPermissionsToLists(data_set_, &result, NULL);
return result;
}
PermissionMessages MediaGalleriesPermission::GetMessages() const {
DCHECK(HasMessages());
PermissionMessages result;
bool has_all_auto_detected = false;
bool has_read = false;
bool has_copy_to = false;
bool has_delete = false;
for (std::set<MediaGalleriesPermissionData>::const_iterator it =
data_set_.begin(); it != data_set_.end(); ++it) {
if (it->permission() == kAllAutoDetectedPermission)
has_all_auto_detected = true;
else if (it->permission() == kReadPermission)
has_read = true;
else if (it->permission() == kCopyToPermission)
has_copy_to = true;
else if (it->permission() == kDeletePermission)
has_delete = true;
}
if (!IsValidPermissionSet(has_read, has_copy_to, has_delete, NULL)) {
NOTREACHED();
return result;
}
// If |has_all_auto_detected| is false, then Chrome will prompt the user at
// runtime when the extension call the getMediaGalleries API.
if (!has_all_auto_detected)
return result;
// No access permission case.
if (!has_read)
return result;
// Separate PermissionMessage IDs for read, copyTo, and delete. Otherwise an
// extension can silently gain new access capabilities.
result.push_back(PermissionMessage(
PermissionMessage::kMediaGalleriesAllGalleriesRead,
l10n_util::GetStringUTF16(
IDS_EXTENSION_PROMPT_WARNING_MEDIA_GALLERIES_READ)));
// For copyTo and delete, the proper combined permission message will be
// derived in ChromePermissionMessageProvider::GetWarningMessages(), such
// that the user get 1 entry for all media galleries access permissions,
// rather than several separate entries.
if (has_copy_to) {
result.push_back(PermissionMessage(
PermissionMessage::kMediaGalleriesAllGalleriesCopyTo,
base::string16()));
}
if (has_delete) {
result.push_back(PermissionMessage(
PermissionMessage::kMediaGalleriesAllGalleriesDelete,
base::string16()));
}
AddPermissionsToLists(data_set_, NULL, &result);
return result;
}
......
......@@ -43,6 +43,7 @@ class MediaGalleriesPermission
std::vector<std::string>* unhandled_permissions) override;
// APIPermission overrides.
PermissionIDSet GetPermissions() const override;
PermissionMessages GetMessages() const override;
// Permission strings.
......
......@@ -5,6 +5,7 @@
#include "extensions/common/permissions/settings_override_permission.h"
#include "base/strings/utf_string_conversions.h"
#include "extensions/common/permissions/api_permission_set.h"
#include "grit/extensions_strings.h"
#include "ui/base/l10n/l10n_util.h"
......@@ -17,6 +18,12 @@ SettingsOverrideAPIPermission::SettingsOverrideAPIPermission(
SettingsOverrideAPIPermission::~SettingsOverrideAPIPermission() {}
PermissionIDSet SettingsOverrideAPIPermission::GetPermissions() const {
PermissionIDSet permissions;
permissions.insert(info()->id(), base::UTF8ToUTF16(setting_value_));
return permissions;
}
bool SettingsOverrideAPIPermission::HasMessages() const {
return info()->message_id() > PermissionMessage::kNone;
}
......@@ -24,16 +31,26 @@ bool SettingsOverrideAPIPermission::HasMessages() const {
PermissionMessages SettingsOverrideAPIPermission::GetMessages() const {
DCHECK(HasMessages());
int string_id = -1;
// Warning: when modifying this function, be sure to modify the correct rule
// in ChromePermissionMessageProvider.
switch (id()) {
case kHomepage: {
// TODO(sashab): Add a parameter rule in ChromePermissionMessageProvider:
// kHomepage -> IDS_EXTENSION_PROMPT_WARNING_HOME_PAGE_SETTING_OVERRIDE
string_id = IDS_EXTENSION_PROMPT_WARNING_HOME_PAGE_SETTING_OVERRIDE;
break;
}
case kStartupPages: {
// TODO(sashab): Add a parameter rule in ChromePermissionMessageProvider:
// kStartupPages ->
// IDS_EXTENSION_PROMPT_WARNING_START_PAGE_SETTING_OVERRIDE
string_id = IDS_EXTENSION_PROMPT_WARNING_START_PAGE_SETTING_OVERRIDE;
break;
}
case kSearchProvider: {
// TODO(sashab): Add a parameter rule in ChromePermissionMessageProvider:
// kSearchProvider ->
// IDS_EXTENSION_PROMPT_WARNING_SEARCH_SETTINGS_OVERRIDE
string_id = IDS_EXTENSION_PROMPT_WARNING_SEARCH_SETTINGS_OVERRIDE;
break;
}
......
......@@ -20,6 +20,7 @@ class SettingsOverrideAPIPermission : public APIPermission {
~SettingsOverrideAPIPermission() override;
// APIPermission overrides.
PermissionIDSet GetPermissions() const override;
bool HasMessages() const override;
PermissionMessages GetMessages() const override;
bool Check(const APIPermission::CheckParam* param) const override;
......
......@@ -21,18 +21,34 @@ SocketPermission::SocketPermission(const APIPermissionInfo* info)
SocketPermission::~SocketPermission() {}
PermissionIDSet SocketPermission::GetPermissions() const {
PermissionMessages messages;
PermissionIDSet ids;
AddAllHostMessages(messages, ids);
return ids;
}
PermissionMessages SocketPermission::GetMessages() const {
DCHECK(HasMessages());
PermissionMessages result;
if (!AddAnyHostMessage(result)) {
AddSpecificHostMessage(result);
AddSubdomainHostMessage(result);
PermissionMessages messages;
PermissionIDSet ids;
AddAllHostMessages(messages, ids);
return messages;
}
void SocketPermission::AddAllHostMessages(PermissionMessages& messages,
PermissionIDSet& ids) const {
// TODO(rpaquay): This function and callees is (almost) a copy/paste from
// extensions::SocketsManifestPermission.
if (!AddAnyHostMessage(messages, ids)) {
AddSpecificHostMessage(messages, ids);
AddSubdomainHostMessage(messages, ids);
}
AddNetworkListMessage(result);
return result;
AddNetworkListMessage(messages, ids);
}
bool SocketPermission::AddAnyHostMessage(PermissionMessages& messages) const {
bool SocketPermission::AddAnyHostMessage(PermissionMessages& messages,
PermissionIDSet& ids) const {
std::set<SocketPermissionData>::const_iterator i;
for (i = data_set_.begin(); i != data_set_.end(); ++i) {
if (i->entry().IsAddressBoundType() &&
......@@ -41,14 +57,15 @@ bool SocketPermission::AddAnyHostMessage(PermissionMessages& messages) const {
PermissionMessage(PermissionMessage::kSocketAnyHost,
l10n_util::GetStringUTF16(
IDS_EXTENSION_PROMPT_WARNING_SOCKET_ANY_HOST)));
ids.insert(APIPermission::kSocketAnyHost);
return true;
}
}
return false;
}
void SocketPermission::AddSubdomainHostMessage(
PermissionMessages& messages) const {
void SocketPermission::AddSubdomainHostMessage(PermissionMessages& messages,
PermissionIDSet& ids) const {
std::set<base::string16> domains;
std::set<SocketPermissionData>::const_iterator i;
for (i = data_set_.begin(); i != data_set_.end(); ++i) {
......@@ -66,11 +83,13 @@ void SocketPermission::AddSubdomainHostMessage(
JoinString(
std::vector<base::string16>(domains.begin(), domains.end()),
' '))));
for (const auto& domain : domains)
ids.insert(APIPermission::kSocketDomainHosts, domain);
}
}
void SocketPermission::AddSpecificHostMessage(
PermissionMessages& messages) const {
void SocketPermission::AddSpecificHostMessage(PermissionMessages& messages,
PermissionIDSet& ids) const {
std::set<base::string16> hostnames;
std::set<SocketPermissionData>::const_iterator i;
for (i = data_set_.begin(); i != data_set_.end(); ++i) {
......@@ -88,11 +107,13 @@ void SocketPermission::AddSpecificHostMessage(
JoinString(
std::vector<base::string16>(hostnames.begin(), hostnames.end()),
' '))));
for (const auto& hostname : hostnames)
ids.insert(APIPermission::kSocketSpecificHosts, hostname);
}
}
void SocketPermission::AddNetworkListMessage(
PermissionMessages& messages) const {
void SocketPermission::AddNetworkListMessage(PermissionMessages& messages,
PermissionIDSet& ids) const {
std::set<SocketPermissionData>::const_iterator i;
for (i = data_set_.begin(); i != data_set_.end(); ++i) {
if (i->entry().pattern().type ==
......@@ -101,6 +122,7 @@ void SocketPermission::AddNetworkListMessage(
PermissionMessage(PermissionMessage::kNetworkState,
l10n_util::GetStringUTF16(
IDS_EXTENSION_PROMPT_WARNING_NETWORK_STATE)));
ids.insert(APIPermission::kNetworkState);
}
}
}
......
......@@ -28,14 +28,26 @@ class SocketPermission
~SocketPermission() override;
PermissionIDSet GetPermissions() const override;
// Returns the localized permission messages of this permission.
PermissionMessages GetMessages() const override;
private:
bool AddAnyHostMessage(PermissionMessages& messages) const;
void AddSubdomainHostMessage(PermissionMessages& messages) const;
void AddSpecificHostMessage(PermissionMessages& messages) const;
void AddNetworkListMessage(PermissionMessages& messages) const;
// Add all host messages for this manifest permission into the given lists.
// TODO(sashab): Remove the |messages| argument from these methods, and remove
// the AddAllHostMessages() function (move all the logic into GetPermissions()
// above).
void AddAllHostMessages(PermissionMessages& messages,
PermissionIDSet& ids) const;
bool AddAnyHostMessage(PermissionMessages& messages,
PermissionIDSet& ids) const;
void AddSubdomainHostMessage(PermissionMessages& messages,
PermissionIDSet& ids) const;
void AddSpecificHostMessage(PermissionMessages& messages,
PermissionIDSet& ids) const;
void AddNetworkListMessage(PermissionMessages& messages,
PermissionIDSet& ids) const;
};
} // namespace extensions
......
......@@ -19,59 +19,80 @@
namespace extensions {
UsbDevicePermission::UsbDevicePermission(
const APIPermissionInfo* info)
: SetDisjunctionPermission<UsbDevicePermissionData,
UsbDevicePermission>(info) {
}
UsbDevicePermission::~UsbDevicePermission() {
}
namespace {
PermissionMessages UsbDevicePermission::GetMessages() const {
DCHECK(HasMessages());
PermissionMessages result;
if (data_set_.size() == 1) {
const UsbDevicePermissionData& data = *data_set_.begin();
// Adds the permissions from the |data_set| to the permission lists that are
// not NULL. If NULL, that list is ignored.
void AddPermissionsToLists(const std::set<UsbDevicePermissionData>& data_set,
PermissionIDSet* ids,
PermissionMessages* messages) {
// TODO(sashab): Once GetMessages() is deprecated, move this logic back into
// GetPermissions().
// TODO(sashab, reillyg): Once GetMessages() is deprecated, rework the
// permission message logic for USB devices to generate more meaningful
// messages and better fit the current rules system.
if (data_set.size() == 1) {
const UsbDevicePermissionData& data = *data_set.begin();
const char* vendor = device::UsbIds::GetVendorName(data.vendor_id());
if (vendor) {
const char* product =
device::UsbIds::GetProductName(data.vendor_id(), data.product_id());
if (product) {
result.push_back(PermissionMessage(
PermissionMessage::kUsbDevice,
l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE,
base::UTF8ToUTF16(product),
base::UTF8ToUTF16(vendor))));
base::string16 product_name_and_vendor = l10n_util::GetStringFUTF16(
IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_PRODUCT_NAME_AND_VENDOR,
base::UTF8ToUTF16(product), base::UTF8ToUTF16(vendor));
if (messages) {
messages->push_back(
PermissionMessage(PermissionMessage::kUsbDevice,
l10n_util::GetStringFUTF16(
IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE,
product_name_and_vendor)));
}
if (ids)
ids->insert(APIPermission::kUsbDevice, product_name_and_vendor);
} else {
result.push_back(PermissionMessage(
PermissionMessage::kUsbDevice,
l10n_util::GetStringFUTF16(
IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_UNKNOWN_PRODUCT,
base::UTF8ToUTF16(vendor))));
if (messages) {
messages->push_back(PermissionMessage(
PermissionMessage::kUsbDevice,
l10n_util::GetStringFUTF16(
IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_UNKNOWN_PRODUCT,
base::UTF8ToUTF16(vendor))));
}
if (ids) {
ids->insert(APIPermission::kUsbDeviceUnknownProduct,
base::UTF8ToUTF16(vendor));
}
}
} else {
result.push_back(PermissionMessage(
PermissionMessage::kUsbDevice,
l10n_util::GetStringUTF16(
IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_UNKNOWN_VENDOR)));
if (messages) {
messages->push_back(PermissionMessage(
PermissionMessage::kUsbDevice,
l10n_util::GetStringUTF16(
IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_UNKNOWN_VENDOR)));
}
if (ids) {
ids->insert(APIPermission::kUsbDeviceUnknownVendor);
}
} else if (data_set_.size() > 1) {
}
} else if (data_set.size() > 1) {
std::vector<base::string16> details;
std::set<uint16> unknown_product_vendors;
bool found_unknown_vendor = false;
for (const UsbDevicePermissionData& data : data_set_) {
for (const UsbDevicePermissionData& data : data_set) {
const char* vendor = device::UsbIds::GetVendorName(data.vendor_id());
if (vendor) {
const char* product =
device::UsbIds::GetProductName(data.vendor_id(), data.product_id());
if (product) {
base::string16 product_name_and_vendor = l10n_util::GetStringFUTF16(
IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_PRODUCT_NAME_AND_VENDOR,
base::UTF8ToUTF16(product), base::UTF8ToUTF16(vendor));
details.push_back(l10n_util::GetStringFUTF16(
IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_LIST_ITEM,
base::UTF8ToUTF16(product), base::UTF8ToUTF16(vendor)));
product_name_and_vendor));
} else {
unknown_product_vendors.insert(data.vendor_id());
}
......@@ -95,13 +116,41 @@ PermissionMessages UsbDevicePermission::GetMessages() const {
IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_LIST_ITEM_UNKNOWN_VENDOR));
}
result.push_back(PermissionMessage(
PermissionMessage::kUsbDevice,
l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_LIST),
JoinString(details, base::char16('\n'))));
if (messages) {
messages->push_back(
PermissionMessage(PermissionMessage::kUsbDevice,
l10n_util::GetStringUTF16(
IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_LIST),
JoinString(details, base::char16('\n'))));
}
if (ids) {
for (const auto& detail : details)
ids->insert(APIPermission::kUsbDeviceList, detail);
}
}
}
} // namespace
UsbDevicePermission::UsbDevicePermission(const APIPermissionInfo* info)
: SetDisjunctionPermission<UsbDevicePermissionData, UsbDevicePermission>(
info) {
}
return result;
UsbDevicePermission::~UsbDevicePermission() {
}
PermissionIDSet UsbDevicePermission::GetPermissions() const {
PermissionIDSet ids;
AddPermissionsToLists(data_set_, &ids, NULL);
return ids;
}
PermissionMessages UsbDevicePermission::GetMessages() const {
DCHECK(HasMessages());
PermissionMessages messages;
AddPermissionsToLists(data_set_, NULL, &messages);
return messages;
}
} // namespace extensions
......@@ -30,6 +30,7 @@ class UsbDevicePermission
~UsbDevicePermission() override;
// APIPermission overrides
PermissionIDSet GetPermissions() const override;
PermissionMessages GetMessages() const override;
};
......
......@@ -355,8 +355,11 @@
<message name="IDS_EXTENSION_PROMPT_WARNING_VPN" desc="Permission string for access to VPN API.">
Access your network traffic
</message>
<message name="IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_PRODUCT_NAME_AND_VENDOR" desc="USB device name and vendor string, used in various permission messages for USB devices.">
<ph name="PRODUCT_NAME">$1<ex>SoundKnob</ex></ph> from <ph name="VENDOR_NAME">$2<ex>Griffin Technology</ex></ph>
</message>
<message name="IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE" desc="Permission string for access to a specific USB device.">
Access any <ph name="PRODUCT_NAME">$1<ex>SoundKnob</ex></ph> from <ph name="VENDOR_NAME">$2<ex>Griffin Technology</ex></ph> via USB
Access any <ph name="PRODUCT_NAME_AND_VENDOR">$1<ex>SoundKnob from Griffin Technology</ex></ph> via USB
</message>
<message name="IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_UNKNOWN_PRODUCT" desc="Permission string for access to a specific USB device with an unknown product ID.">
Access USB devices from <ph name="VENDOR_NAME">$1<ex>Griffin Technology</ex></ph>
......@@ -368,7 +371,7 @@
Access any of these USB devices
</message>
<message name="IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_LIST_ITEM" desc="Line item for a USB device listed under IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_LIST.">
<ph name="PRODUCT_NAME">$1<ex>SoundKnob</ex></ph> from <ph name="VENDOR_NAME">$2<ex>Griffin Technology</ex></ph>
<ph name="PRODUCT_NAME_AND_VENDOR">$1<ex>SoundKnob from Griffin Technology</ex></ph>
</message>
<message name="IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_LIST_ITEM_UNKNOWN_PRODUCT" desc="Line item for a USB device listed under IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_LIST that has an unknown product ID.">
unknown devices from <ph name="VENDOR_NAME">$1<ex>Griffin Technology</ex></ph>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment