diff options
author | bryeung@chromium.org <bryeung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-06 19:30:25 +0000 |
---|---|---|
committer | bryeung@chromium.org <bryeung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-06 19:30:25 +0000 |
commit | f3cc80630260b4638c9dbe92d06dc7a8213e92da (patch) | |
tree | 9ebac78d617c12347bcc687f24ce2113b6f2034f | |
parent | a7ed0caee52c25c7df1031bbf9aa965def8f57cf (diff) | |
download | chromium_src-f3cc80630260b4638c9dbe92d06dc7a8213e92da.zip chromium_src-f3cc80630260b4638c9dbe92d06dc7a8213e92da.tar.gz chromium_src-f3cc80630260b4638c9dbe92d06dc7a8213e92da.tar.bz2 |
Refactor (Socket|BlueoothDevice)Permission.
This eliminates much code duplication between specialized extension
permission types.
BUG=147531
TBR=sky@chromium.org
Review URL: https://chromiumcodereview.appspot.com/11418315
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@171559 0039d316-1c4b-4281-b951-d872f2087c98
13 files changed, 391 insertions, 383 deletions
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index 1bbf113..315f6ca 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -192,12 +192,15 @@ 'common/extensions/permissions/api_permission_set.h', 'common/extensions/permissions/bluetooth_device_permission.cc', 'common/extensions/permissions/bluetooth_device_permission.h', + 'common/extensions/permissions/bluetooth_device_permission_data.cc', + 'common/extensions/permissions/bluetooth_device_permission_data.h', 'common/extensions/permissions/permission_message.cc', 'common/extensions/permissions/permission_message.h', 'common/extensions/permissions/permission_set.cc', 'common/extensions/permissions/permission_set.h', 'common/extensions/permissions/permissions_info.cc', 'common/extensions/permissions/permissions_info.h', + 'common/extensions/permissions/set_disjunction_permission.h', 'common/extensions/permissions/socket_permission.cc', 'common/extensions/permissions/socket_permission.h', 'common/extensions/permissions/socket_permission_data.cc', diff --git a/chrome/common/extensions/extension_messages.cc b/chrome/common/extensions/extension_messages.cc index 088faa5..95ae472 100644 --- a/chrome/common/extensions/extension_messages.cc +++ b/chrome/common/extensions/extension_messages.cc @@ -14,6 +14,7 @@ using extensions::APIPermission; using extensions::APIPermissionInfo; using extensions::APIPermissionMap; using extensions::APIPermissionSet; +using extensions::BluetoothDevicePermissionData; using extensions::Extension; using extensions::PermissionSet; using extensions::SocketPermissionData; @@ -207,6 +208,25 @@ void ParamTraits<SocketPermissionData>::Log( LogParam(std::string("<SocketPermissionData>"), l); } +void ParamTraits<BluetoothDevicePermissionData>::Write( + Message* m, const param_type& p) { + WriteParam(m, p.GetAsString()); +} + +bool ParamTraits<BluetoothDevicePermissionData>::Read( + const Message* m, PickleIterator* iter, param_type* r) { + std::string spec; + if (!ReadParam(m, iter, &spec)) + return false; + + return r->Parse(spec); +} + +void ParamTraits<BluetoothDevicePermissionData>::Log( + const param_type& p, std::string* l) { + LogParam(std::string("<BluetoothDevicePermissionData>"), l); +} + void ParamTraits<ExtensionMsg_Loaded_Params>::Write(Message* m, const param_type& p) { WriteParam(m, p.location); diff --git a/chrome/common/extensions/extension_messages.h b/chrome/common/extensions/extension_messages.h index 1a07eef..6058fbf 100644 --- a/chrome/common/extensions/extension_messages.h +++ b/chrome/common/extensions/extension_messages.h @@ -9,6 +9,7 @@ #include "base/values.h" #include "chrome/common/extensions/draggable_region.h" #include "chrome/common/extensions/extension.h" +#include "chrome/common/extensions/permissions/bluetooth_device_permission_data.h" #include "chrome/common/extensions/permissions/permission_set.h" #include "chrome/common/extensions/permissions/socket_permission_data.h" #include "chrome/common/view_type.h" @@ -201,6 +202,14 @@ struct ParamTraits<ExtensionMsg_Loaded_Params> { static void Log(const param_type& p, std::string* l); }; +template <> +struct ParamTraits<extensions::BluetoothDevicePermissionData> { + typedef extensions::BluetoothDevicePermissionData param_type; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static void Log(const param_type& p, std::string* l); +}; + } // namespace IPC #endif // CHROME_COMMON_EXTENSIONS_EXTENSION_MESSAGES_H_ diff --git a/chrome/common/extensions/permissions/bluetooth_device_permission.cc b/chrome/common/extensions/permissions/bluetooth_device_permission.cc index d0597e3..83e2bd6 100644 --- a/chrome/common/extensions/permissions/bluetooth_device_permission.cc +++ b/chrome/common/extensions/permissions/bluetooth_device_permission.cc @@ -13,8 +13,7 @@ #include "base/string16.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/common/extensions/extension_messages.h" +#include "chrome/common/extensions/permissions/bluetooth_device_permission_data.h" #include "chrome/common/extensions/permissions/permissions_info.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_adapter_factory.h" @@ -31,7 +30,9 @@ const char* kSeparator = "|"; namespace extensions { BluetoothDevicePermission::BluetoothDevicePermission( - const APIPermissionInfo* info) : APIPermission(info) { + const APIPermissionInfo* info) + : SetDisjunctionPermission<BluetoothDevicePermissionData, + BluetoothDevicePermission>(info) { } BluetoothDevicePermission::~BluetoothDevicePermission() { @@ -43,16 +44,16 @@ void BluetoothDevicePermission::AddDevicesFromString( Tokenize(devices_string, kSeparator, &devices); for (std::vector<std::string>::const_iterator i = devices.begin(); i != devices.end(); ++i) { - devices_.insert(*i); + data_set_.insert(BluetoothDevicePermissionData(*i)); } } std::string BluetoothDevicePermission::ToString() const { std::vector<std::string> parts; parts.push_back(name()); - for (std::set<std::string>::const_iterator i = devices_.begin(); - i != devices_.end(); ++i) { - parts.push_back(*i); + for (std::set<BluetoothDevicePermissionData>::const_iterator i = + data_set_.begin(); i != data_set_.end(); ++i) { + parts.push_back(i->GetAsString()); } return JoinString(parts, kSeparator); } @@ -61,10 +62,6 @@ bool BluetoothDevicePermission::ManifestEntryForbidden() const { return true; } -bool BluetoothDevicePermission::HasMessages() const { - return !devices_.empty(); -} - PermissionMessages BluetoothDevicePermission::GetMessages() const { DCHECK(HasMessages()); PermissionMessages result; @@ -72,18 +69,21 @@ PermissionMessages BluetoothDevicePermission::GetMessages() const { scoped_refptr<device::BluetoothAdapter> bluetooth_adapter = device::BluetoothAdapterFactory::DefaultAdapter(); - for (std::set<std::string>::const_iterator i = devices_.begin(); - i != devices_.end(); ++i) { + for (std::set<BluetoothDevicePermissionData>::const_iterator i = + data_set_.begin(); i != data_set_.end(); ++i) { + const std::string& device_address = i->GetAsString(); string16 device_identifier; if (bluetooth_adapter) { - device::BluetoothDevice* device = bluetooth_adapter->GetDevice(*i); + device::BluetoothDevice* device = + bluetooth_adapter->GetDevice(device_address); if (device) device_identifier = device->GetName(); } if (device_identifier.length() == 0) { - UTF8ToUTF16(i->c_str(), i->length(), &device_identifier); + UTF8ToUTF16(device_address.c_str(), device_address.length(), + &device_identifier); } result.push_back(PermissionMessage( @@ -96,125 +96,4 @@ PermissionMessages BluetoothDevicePermission::GetMessages() const { return result; } -bool BluetoothDevicePermission::Check( - const APIPermission::CheckParam* param) const { - const CheckParam* bluetooth_device_parameter = - static_cast<const CheckParam*>(param); - for (std::set<std::string>::const_iterator i = devices_.begin(); - i != devices_.end(); ++i) { - if (*i == bluetooth_device_parameter->device_address) - return true; - } - return false; -} - -bool BluetoothDevicePermission::Contains(const APIPermission* rhs) const { - CHECK(rhs->info() == info()); - const BluetoothDevicePermission* perm = - static_cast<const BluetoothDevicePermission*>(rhs); - return std::includes( - devices_.begin(), devices_.end(), - perm->devices_.begin(), perm->devices_.end()); -} - -bool BluetoothDevicePermission::Equal(const APIPermission* rhs) const { - CHECK(rhs->info() == info()); - const BluetoothDevicePermission* perm = - static_cast<const BluetoothDevicePermission*>(rhs); - return devices_ == perm->devices_; -} - -bool BluetoothDevicePermission::FromValue(const base::Value* value) { - devices_.clear(); - const base::ListValue* list = NULL; - - if (!value) - return false; - - if (!value->GetAsList(&list) || list->GetSize() == 0) - return false; - - for (size_t i = 0; i < list->GetSize(); ++i) { - std::string device_address; - if (!list->GetString(i, &device_address)) - return false; - devices_.insert(device_address); - } - - return true; -} - -void BluetoothDevicePermission::ToValue(base::Value** value) const { - base::ListValue* list = new ListValue(); - std::set<std::string>::const_iterator i; - for (std::set<std::string>::const_iterator i = devices_.begin(); - i != devices_.end(); ++i) { - list->Append(base::Value::CreateStringValue(*i)); - } - *value = list; -} - -APIPermission* BluetoothDevicePermission::Clone() const { - BluetoothDevicePermission* result = new BluetoothDevicePermission(info()); - result->devices_ = devices_; - return result; -} - -APIPermission* BluetoothDevicePermission::Diff(const APIPermission* rhs) const { - CHECK(rhs->info() == info()); - const BluetoothDevicePermission* perm = - static_cast<const BluetoothDevicePermission*>(rhs); - scoped_ptr<BluetoothDevicePermission> result( - new BluetoothDevicePermission(info())); - std::set_difference( - devices_.begin(), devices_.end(), - perm->devices_.begin(), perm->devices_.end(), - std::inserter<std::set<std::string> >( - result->devices_, result->devices_.begin())); - return result->devices_.empty() ? NULL : result.release(); -} - -APIPermission* BluetoothDevicePermission::Union( - const APIPermission* rhs) const { - CHECK(rhs->info() == info()); - const BluetoothDevicePermission* perm = - static_cast<const BluetoothDevicePermission*>(rhs); - scoped_ptr<BluetoothDevicePermission> result( - new BluetoothDevicePermission(info())); - std::set_union( - devices_.begin(), devices_.end(), - perm->devices_.begin(), perm->devices_.end(), - std::inserter<std::set<std::string> >( - result->devices_, result->devices_.begin())); - return result->devices_.empty() ? NULL : result.release(); -} - -APIPermission* BluetoothDevicePermission::Intersect( - const APIPermission* rhs) const { - CHECK(rhs->info() == info()); - const BluetoothDevicePermission* perm = - static_cast<const BluetoothDevicePermission*>(rhs); - scoped_ptr<BluetoothDevicePermission> result( - new BluetoothDevicePermission(info())); - std::set_intersection( - devices_.begin(), devices_.end(), - perm->devices_.begin(), perm->devices_.end(), - std::inserter<std::set<std::string> >( - result->devices_, result->devices_.begin())); - return result->devices_.empty() ? NULL : result.release(); -} - -void BluetoothDevicePermission::Write(IPC::Message* m) const { - IPC::WriteParam(m, devices_); -} - -bool BluetoothDevicePermission::Read( - const IPC::Message* m, PickleIterator* iter) { - return IPC::ReadParam(m, iter, &devices_); -} - -void BluetoothDevicePermission::Log(std::string* log) const { - IPC::LogParam(devices_, log); -} - } // namespace extensions diff --git a/chrome/common/extensions/permissions/bluetooth_device_permission.h b/chrome/common/extensions/permissions/bluetooth_device_permission.h index fbbd431..d12cada 100644 --- a/chrome/common/extensions/permissions/bluetooth_device_permission.h +++ b/chrome/common/extensions/permissions/bluetooth_device_permission.h @@ -9,28 +9,25 @@ #include <string> #include "chrome/common/extensions/permissions/api_permission.h" - -namespace base { -class Value; -} - -namespace IPC { -class Message; -} +#include "chrome/common/extensions/permissions/bluetooth_device_permission_data.h" +#include "chrome/common/extensions/permissions/set_disjunction_permission.h" namespace extensions { -// There's room to share code with related classes, see http://crbug.com/147531 -class BluetoothDevicePermission : public APIPermission { +// BluetoothDevicePermission represents the permission to access a specific +// Bluetooth Device. +class BluetoothDevicePermission + : public SetDisjunctionPermission<BluetoothDevicePermissionData, + BluetoothDevicePermission> { public: - struct CheckParam : public APIPermission::CheckParam { - explicit CheckParam(const std::string& device_address) + // A Bluetooth device address that should be check for permission to access. + struct CheckParam : APIPermission::CheckParam { + explicit CheckParam(std::string device_address) : device_address(device_address) {} const std::string device_address; }; explicit BluetoothDevicePermission(const APIPermissionInfo* info); - virtual ~BluetoothDevicePermission(); // Adds BluetoothDevices from |devices| to the set of allowed devices. @@ -40,24 +37,7 @@ class BluetoothDevicePermission : public APIPermission { // APIPermission overrides virtual std::string ToString() const OVERRIDE; virtual bool ManifestEntryForbidden() const OVERRIDE; - virtual bool HasMessages() const OVERRIDE; virtual PermissionMessages GetMessages() const OVERRIDE; - virtual bool Check( - const APIPermission::CheckParam* param) const OVERRIDE; - virtual bool Contains(const APIPermission* rhs) const OVERRIDE; - virtual bool Equal(const APIPermission* rhs) const OVERRIDE; - virtual bool FromValue(const base::Value* value) OVERRIDE; - virtual void ToValue(base::Value** value) const OVERRIDE; - virtual APIPermission* Clone() const OVERRIDE; - virtual APIPermission* Diff(const APIPermission* rhs) const OVERRIDE; - virtual APIPermission* Union(const APIPermission* rhs) const OVERRIDE; - virtual APIPermission* Intersect(const APIPermission* rhs) const OVERRIDE; - virtual void Write(IPC::Message* m) const OVERRIDE; - virtual bool Read(const IPC::Message* m, PickleIterator* iter) OVERRIDE; - virtual void Log(std::string* log) const OVERRIDE; - - private: - std::set<std::string> devices_; }; } // namespace extensions diff --git a/chrome/common/extensions/permissions/bluetooth_device_permission_data.cc b/chrome/common/extensions/permissions/bluetooth_device_permission_data.cc new file mode 100644 index 0000000..fc9edee --- /dev/null +++ b/chrome/common/extensions/permissions/bluetooth_device_permission_data.cc @@ -0,0 +1,49 @@ +// Copyright (c) 2012 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. + +#include "chrome/common/extensions/permissions/bluetooth_device_permission_data.h" + +#include <string> + +#include "chrome/common/extensions/permissions/bluetooth_device_permission.h" + +namespace extensions { + +BluetoothDevicePermissionData::BluetoothDevicePermissionData() + : device_address_("") { +} + +BluetoothDevicePermissionData::BluetoothDevicePermissionData( + const std::string& device_address) : device_address_(device_address) { +} + +bool BluetoothDevicePermissionData::Check( + const APIPermission::CheckParam* param) const { + if (!param) + return false; + const BluetoothDevicePermission::CheckParam& specific_param = + *static_cast<const BluetoothDevicePermission::CheckParam*>(param); + return device_address_ == specific_param.device_address; +} + +bool BluetoothDevicePermissionData::Parse(const std::string& spec) { + device_address_ = spec; + return true; +} + +const std::string &BluetoothDevicePermissionData::GetAsString() const { + return device_address_; +} + +bool BluetoothDevicePermissionData::operator<( + const BluetoothDevicePermissionData& rhs) const { + return device_address_ < rhs.device_address_; +} + +bool BluetoothDevicePermissionData::operator==( + const BluetoothDevicePermissionData& rhs) const { + return device_address_ == rhs.device_address_; +} + +} // namespace extensions diff --git a/chrome/common/extensions/permissions/bluetooth_device_permission_data.h b/chrome/common/extensions/permissions/bluetooth_device_permission_data.h new file mode 100644 index 0000000..31e5660 --- /dev/null +++ b/chrome/common/extensions/permissions/bluetooth_device_permission_data.h @@ -0,0 +1,40 @@ +// Copyright (c) 2012 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. + +#ifndef CHROME_COMMON_EXTENSIONS_PERMISSIONS_BLUETOOTH_DEVICE_PERMISSION_DATA_H_ +#define CHROME_COMMON_EXTENSIONS_PERMISSIONS_BLUETOOTH_DEVICE_PERMISSION_DATA_H_ + +#include <string> + +#include "chrome/common/extensions/permissions/api_permission.h" + +namespace extensions { + +// A pattern that can be used to match a Bluetooth device permission. +// Must be of the format: "XX:XX:XX:XX:XX:XX", where XX are hexadecimal digits. +class BluetoothDevicePermissionData { + public: + BluetoothDevicePermissionData(); + explicit BluetoothDevicePermissionData(const std::string& device_address); + + // Check if |param| (which must be a BluetoothDevicePermission::CheckParam) + // matches the address of this object.. + bool Check(const APIPermission::CheckParam* param) const; + + // Populate the address from a string. + bool Parse(const std::string& spec); + + // Return the address. + const std::string& GetAsString() const; + + bool operator<(const BluetoothDevicePermissionData& rhs) const; + bool operator==(const BluetoothDevicePermissionData& rhs) const; + + private: + std::string device_address_; +}; + +} // namespace extensions + +#endif // CHROME_COMMON_EXTENSIONS_PERMISSIONS_BLUETOOTH_DEVICE_PERMISSION_DATA_H_ diff --git a/chrome/common/extensions/permissions/set_disjunction_permission.h b/chrome/common/extensions/permissions/set_disjunction_permission.h new file mode 100644 index 0000000..ac9f4ef --- /dev/null +++ b/chrome/common/extensions/permissions/set_disjunction_permission.h @@ -0,0 +1,160 @@ +// Copyright (c) 2012 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. + +#ifndef CHROME_COMMON_EXTENSIONS_PERMISSIONS_SET_DISJUNCTION_PERMISSION_H_ +#define CHROME_COMMON_EXTENSIONS_PERMISSIONS_SET_DISJUNCTION_PERMISSION_H_ + +#include <algorithm> +#include <set> +#include <string> + +#include "base/memory/scoped_ptr.h" +#include "base/values.h" +#include "chrome/common/extensions/extension_messages.h" +#include "chrome/common/extensions/permissions/api_permission.h" +#include "ipc/ipc_message.h" +#include "ipc/ipc_message_utils.h" + +namespace extensions { + +// An abstract base class for permissions that are represented by the +// disjunction of a set of conditions. Each condition is represented by a +// |PermissionDataType| (e.g. SocketPermissionData). If an +// APIPermission::CheckParam matches any of the conditions in the set, the +// permission is granted. +// +// For an example of how to use this class, see SocketPermission. +template <class PermissionDataType, class DerivedType> +class SetDisjunctionPermission : public APIPermission { + public: + explicit SetDisjunctionPermission(const APIPermissionInfo* info) + : APIPermission(info) { + } + + ~SetDisjunctionPermission() { + } + + // APIPermission overrides + virtual bool HasMessages() const OVERRIDE { + return !data_set_.empty(); + } + + virtual bool Check(const APIPermission::CheckParam* param) const OVERRIDE { + for (typename std::set<PermissionDataType>::const_iterator i = + data_set_.begin(); i != data_set_.end(); ++i) { + if (i->Check(param)) + return true; + } + return false; + } + + virtual bool Contains(const APIPermission* rhs) const OVERRIDE { + CHECK(rhs->info() == info()); + const SetDisjunctionPermission* perm = + static_cast<const SetDisjunctionPermission*>(rhs); + return std::includes( + data_set_.begin(), data_set_.end(), + perm->data_set_.begin(), perm->data_set_.end()); + } + + virtual bool Equal(const APIPermission* rhs) const OVERRIDE { + CHECK(rhs->info() == info()); + const SetDisjunctionPermission* perm = + static_cast<const SetDisjunctionPermission*>(rhs); + return data_set_ == perm->data_set_; + } + + virtual APIPermission* Clone() const OVERRIDE { + SetDisjunctionPermission* result = new DerivedType(info()); + result->data_set_ = data_set_; + return result; + } + + virtual APIPermission* Diff(const APIPermission* rhs) const OVERRIDE { + CHECK(rhs->info() == info()); + const SetDisjunctionPermission* perm = + static_cast<const SetDisjunctionPermission*>(rhs); + scoped_ptr<SetDisjunctionPermission> result(new DerivedType(info())); + std::set_difference( + data_set_.begin(), data_set_.end(), + perm->data_set_.begin(), perm->data_set_.end(), + std::inserter<std::set<PermissionDataType> >( + result->data_set_, result->data_set_.begin())); + return result->data_set_.empty() ? NULL : result.release(); + } + + virtual APIPermission* Union(const APIPermission* rhs) const OVERRIDE { + CHECK(rhs->info() == info()); + const SetDisjunctionPermission* perm = + static_cast<const SetDisjunctionPermission*>(rhs); + scoped_ptr<SetDisjunctionPermission> result(new DerivedType(info())); + std::set_union( + data_set_.begin(), data_set_.end(), + perm->data_set_.begin(), perm->data_set_.end(), + std::inserter<std::set<PermissionDataType> >( + result->data_set_, result->data_set_.begin())); + return result.release(); + } + + virtual APIPermission* Intersect(const APIPermission* rhs) const OVERRIDE { + CHECK(rhs->info() == info()); + const SetDisjunctionPermission* perm = + static_cast<const SetDisjunctionPermission*>(rhs); + scoped_ptr<SetDisjunctionPermission> result(new DerivedType(info())); + std::set_intersection( + data_set_.begin(), data_set_.end(), + perm->data_set_.begin(), perm->data_set_.end(), + std::inserter<std::set<PermissionDataType> >( + result->data_set_, result->data_set_.begin())); + return result->data_set_.empty() ? NULL : result.release(); + } + + virtual bool FromValue(const base::Value* value) OVERRIDE { + data_set_.clear(); + const base::ListValue* list = NULL; + + if (!value) + return false; + + if (!value->GetAsList(&list) || list->GetSize() == 0) + return false; + + for (size_t i = 0; i < list->GetSize(); ++i) { + std::string str; + PermissionDataType data; + if (!list->GetString(i, &str) || !data.Parse(str)) + return false; + data_set_.insert(data); + } + return true; + } + + virtual void ToValue(base::Value** value) const OVERRIDE { + base::ListValue* list = new ListValue(); + typename std::set<PermissionDataType>::const_iterator i; + for (i = data_set_.begin(); i != data_set_.end(); ++i) { + list->Append(base::Value::CreateStringValue(i->GetAsString())); + } + *value = list; + } + + virtual void Write(IPC::Message* m) const OVERRIDE { + IPC::WriteParam(m, data_set_); + } + + virtual bool Read(const IPC::Message* m, PickleIterator* iter) OVERRIDE { + return IPC::ReadParam(m, iter, &data_set_); + } + + virtual void Log(std::string* log) const OVERRIDE { + IPC::LogParam(data_set_, log); + } + + protected: + std::set<PermissionDataType> data_set_; +}; + +} // namespace extensions + +#endif // CHROME_COMMON_EXTENSIONS_PERMISSIONS_SET_DISJUNCTION_PERMISSION_H_ diff --git a/chrome/common/extensions/permissions/socket_permission.cc b/chrome/common/extensions/permissions/socket_permission.cc index 5a087f5..c2eb84c 100644 --- a/chrome/common/extensions/permissions/socket_permission.cc +++ b/chrome/common/extensions/permissions/socket_permission.cc @@ -9,25 +9,20 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/common/extensions/extension_messages.h" #include "chrome/common/extensions/permissions/permissions_info.h" +#include "chrome/common/extensions/permissions/set_disjunction_permission.h" #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" namespace extensions { SocketPermission::SocketPermission(const APIPermissionInfo* info) - : APIPermission(info) { + : SetDisjunctionPermission<SocketPermissionData, SocketPermission>(info) { } SocketPermission::~SocketPermission() { } -bool SocketPermission::HasMessages() const { - return !data_set_.empty(); -} - PermissionMessages SocketPermission::GetMessages() const { DCHECK(HasMessages()); PermissionMessages result; @@ -97,109 +92,4 @@ void SocketPermission::AddSpecificHostMessage(PermissionMessages& messages) } } -bool SocketPermission::Check( - const APIPermission::CheckParam* param) const { - const CheckParam* socket_param = static_cast<const CheckParam*>(param); - std::set<SocketPermissionData>::const_iterator i; - for (i = data_set_.begin(); i != data_set_.end(); ++i) { - if (i->Match(socket_param->request)) - return true; - } - return false; -} - -bool SocketPermission::Contains(const APIPermission* rhs) const { - CHECK(rhs->info() == info()); - const SocketPermission* perm = static_cast<const SocketPermission*>(rhs); - return std::includes(data_set_.begin(), data_set_.end(), - perm->data_set_.begin(), perm->data_set_.end()); -} - -bool SocketPermission::Equal(const APIPermission* rhs) const { - CHECK(rhs->info() == info()); - const SocketPermission* perm = static_cast<const SocketPermission*>(rhs); - return data_set_ == perm->data_set_; -} - -bool SocketPermission::FromValue(const base::Value* value) { - data_set_.clear(); - const base::ListValue* list = NULL; - - if (!value) - return false; - - if (!value->GetAsList(&list) || list->GetSize() == 0) - return false; - - for (size_t i = 0; i < list->GetSize(); ++i) { - std::string str; - SocketPermissionData data; - if (!list->GetString(i, &str) || !data.Parse(str)) - return false; - data_set_.insert(data); - } - return true; -} - -void SocketPermission::ToValue(base::Value** value) const { - base::ListValue* list = new ListValue(); - std::set<SocketPermissionData>::const_iterator i; - for (i = data_set_.begin(); i != data_set_.end(); ++i) { - list->Append(base::Value::CreateStringValue(i->GetAsString())); - } - *value = list; -} - -APIPermission* SocketPermission::Clone() const { - SocketPermission* result = new SocketPermission(info()); - result->data_set_ = data_set_; - return result; -} - -APIPermission* SocketPermission::Diff(const APIPermission* rhs) const { - CHECK(rhs->info() == info()); - const SocketPermission* perm = static_cast<const SocketPermission*>(rhs); - scoped_ptr<SocketPermission> result(new SocketPermission(info())); - std::set_difference(data_set_.begin(), data_set_.end(), - perm->data_set_.begin(), perm->data_set_.end(), - std::inserter<std::set<SocketPermissionData> >( - result->data_set_, result->data_set_.begin())); - return result->data_set_.empty() ? NULL : result.release(); -} - -APIPermission* SocketPermission::Union(const APIPermission* rhs) const { - CHECK(rhs->info() == info()); - const SocketPermission* perm = static_cast<const SocketPermission*>(rhs); - scoped_ptr<SocketPermission> result(new SocketPermission(info())); - std::set_union(data_set_.begin(), data_set_.end(), - perm->data_set_.begin(), perm->data_set_.end(), - std::inserter<std::set<SocketPermissionData> >( - result->data_set_, result->data_set_.begin())); - return result->data_set_.empty() ? NULL : result.release(); -} - -APIPermission* SocketPermission::Intersect(const APIPermission* rhs) const { - CHECK(rhs->info() == info()); - const SocketPermission* perm = static_cast<const SocketPermission*>(rhs); - scoped_ptr<SocketPermission> result(new SocketPermission(info())); - std::set_intersection(data_set_.begin(), data_set_.end(), - perm->data_set_.begin(), perm->data_set_.end(), - std::inserter<std::set<SocketPermissionData> >( - result->data_set_, result->data_set_.begin())); - return result->data_set_.empty() ? NULL : result.release(); -} - -void SocketPermission::Write(IPC::Message* m) const { - IPC::WriteParam(m, data_set_); -} - -bool SocketPermission::Read(const IPC::Message* m, PickleIterator* iter) { - return IPC::ReadParam(m, iter, &data_set_); -} - -void SocketPermission::Log(std::string* log) const { - IPC::LogParam(data_set_, log); -} - } // namespace extensions - diff --git a/chrome/common/extensions/permissions/socket_permission.h b/chrome/common/extensions/permissions/socket_permission.h index e148379..49d3c3b 100644 --- a/chrome/common/extensions/permissions/socket_permission.h +++ b/chrome/common/extensions/permissions/socket_permission.h @@ -5,25 +5,16 @@ #ifndef CHROME_COMMON_EXTENSIONS_PERMISSIONS_SOCKET_PERMISSION_H_ #define CHROME_COMMON_EXTENSIONS_PERMISSIONS_SOCKET_PERMISSION_H_ -#include <set> #include <string> #include "chrome/common/extensions/permissions/api_permission.h" +#include "chrome/common/extensions/permissions/set_disjunction_permission.h" #include "chrome/common/extensions/permissions/socket_permission_data.h" -namespace base { -class Value; -} - -namespace IPC { -class Message; -} - namespace extensions { -// There's room to share code with related classes, see http://crbug.com/147531 - -class SocketPermission : public APIPermission { +class SocketPermission : public SetDisjunctionPermission<SocketPermissionData, + SocketPermission> { public: struct CheckParam : APIPermission::CheckParam { CheckParam(content::SocketPermissionRequest::OperationType type, @@ -37,58 +28,13 @@ class SocketPermission : public APIPermission { virtual ~SocketPermission(); - // Returns true if this permission has PermissionMessages. - virtual bool HasMessages() const OVERRIDE; - // Returns the localized permission messages of this permission. virtual PermissionMessages GetMessages() const OVERRIDE; - // Returns true if the given permission in param is allowed. - virtual bool Check( - const APIPermission::CheckParam* param) const OVERRIDE; - - // Returns true if |rhs| is a subset of this. - virtual bool Contains(const APIPermission* rhs) const OVERRIDE; - - // Returns true if |rhs| is equal to this. - virtual bool Equal(const APIPermission* rhs) const OVERRIDE; - - // Parses the rhs from |value|. Returns false if error happens. - virtual bool FromValue(const base::Value* value) OVERRIDE; - - // Stores this into a new created |value|. - virtual void ToValue(base::Value** value) const OVERRIDE; - - // Clones this. - virtual APIPermission* Clone() const OVERRIDE; - - // Returns a new API permission rhs which equals this - |rhs|. - virtual APIPermission* Diff(const APIPermission* rhs) const OVERRIDE; - - // Returns a new API permission rhs which equals the union of this and - // |rhs|. - virtual APIPermission* Union(const APIPermission* rhs) const OVERRIDE; - - // Returns a new API permission rhs which equals the intersect of this and - // |rhs|. - virtual APIPermission* Intersect(const APIPermission* rhs) const OVERRIDE; - - // IPC functions - // Writes this into the given IPC message |m|. - virtual void Write(IPC::Message* m) const OVERRIDE; - - // Reads from the given IPC message |m|. - virtual bool Read(const IPC::Message* m, PickleIterator* iter) OVERRIDE; - - // Logs this rhs. - virtual void Log(std::string* log) const OVERRIDE; - private: bool AddAnyHostMessage(PermissionMessages& messages) const; void AddSubdomainHostMessage(PermissionMessages& messages) const; void AddSpecificHostMessage(PermissionMessages& messages) const; - - std::set<SocketPermissionData> data_set_; }; } // namespace extensions diff --git a/chrome/common/extensions/permissions/socket_permission_data.cc b/chrome/common/extensions/permissions/socket_permission_data.cc index bd9f041..bbf4523 100644 --- a/chrome/common/extensions/permissions/socket_permission_data.cc +++ b/chrome/common/extensions/permissions/socket_permission_data.cc @@ -12,6 +12,8 @@ #include "base/string_number_conversions.h" #include "base/string_split.h" #include "base/string_util.h" +#include "chrome/common/extensions/permissions/api_permission.h" +#include "chrome/common/extensions/permissions/socket_permission.h" #include "googleurl/src/url_canon.h" namespace { @@ -27,7 +29,7 @@ const char kTCPConnect[] = "tcp-connect"; const char kTCPListen[] = "tcp-listen"; const char kUDPBind[] = "udp-bind"; const char kUDPSendTo[] = "udp-send-to"; -const int kAnyPort = 0; +const int kWildcardPortNumber = 0; const int kInvalidPort = -1; SocketPermissionRequest::OperationType StringToType(const std::string& s) { @@ -105,7 +107,14 @@ bool SocketPermissionData::operator==(const SocketPermissionData& rhs) const { (pattern_.port == rhs.pattern_.port); } -bool SocketPermissionData::Match(SocketPermissionRequest request) const { +bool SocketPermissionData::Check( + const APIPermission::CheckParam* param) const { + if (!param) + return false; + const SocketPermission::CheckParam& specific_param = + *static_cast<const SocketPermission::CheckParam*>(param); + const SocketPermissionRequest &request = specific_param.request; + if (pattern_.type != request.type) return false; @@ -137,7 +146,7 @@ bool SocketPermissionData::Match(SocketPermissionRequest request) const { } } - if (pattern_.port != request.port && pattern_.port != kAnyPort) + if (pattern_.port != request.port && pattern_.port != kWildcardPortNumber) return false; return true; @@ -147,7 +156,7 @@ bool SocketPermissionData::Parse(const std::string& permission) { do { pattern_.host.clear(); match_subdomains_ = true; - pattern_.port = kAnyPort; + pattern_.port = kWildcardPortNumber; spec_.clear(); std::vector<std::string> tokens; @@ -224,7 +233,7 @@ const std::string& SocketPermissionData::GetAsString() const { spec_.append(1, kColon).append(pattern_.host); } - if (pattern_.port == kAnyPort) + if (pattern_.port == kWildcardPortNumber) spec_.append(1, kColon).append(kWildcard); else spec_.append(1, kColon).append(base::IntToString(pattern_.port)); diff --git a/chrome/common/extensions/permissions/socket_permission_data.h b/chrome/common/extensions/permissions/socket_permission_data.h index a98d41a..3eb8d3d 100644 --- a/chrome/common/extensions/permissions/socket_permission_data.h +++ b/chrome/common/extensions/permissions/socket_permission_data.h @@ -6,6 +6,7 @@ #include <string> +#include "chrome/common/extensions/permissions/api_permission.h" #include "content/public/common/socket_permission_request.h" namespace extensions { @@ -41,7 +42,7 @@ class SocketPermissionData { bool operator<(const SocketPermissionData& rhs) const; bool operator==(const SocketPermissionData& rhs) const; - bool Match(content::SocketPermissionRequest request) const; + bool Check(const APIPermission::CheckParam* param) const; bool Parse(const std::string& permission); diff --git a/chrome/common/extensions/permissions/socket_permission_unittest.cc b/chrome/common/extensions/permissions/socket_permission_unittest.cc index 7ed1a52..a730254 100644 --- a/chrome/common/extensions/permissions/socket_permission_unittest.cc +++ b/chrome/common/extensions/permissions/socket_permission_unittest.cc @@ -138,61 +138,83 @@ TEST(SocketPermissionTest, Parse) { TEST(SocketPermissionTest, Match) { SocketPermissionData data; + scoped_ptr<SocketPermission::CheckParam> param; CHECK(data.Parse("tcp-connect")); - EXPECT_TRUE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80))); - EXPECT_FALSE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::UDP_SEND_TO, "www.example.com", 80))); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80)); + EXPECT_TRUE(data.Check(param.get())); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::UDP_SEND_TO, "www.example.com", 80)); + EXPECT_FALSE(data.Check(param.get())); CHECK(data.Parse("udp-send-to::8800")); - EXPECT_TRUE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::UDP_SEND_TO, "www.example.com", 8800))); - EXPECT_TRUE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::UDP_SEND_TO, "smtp.example.com", 8800))); - EXPECT_FALSE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80))); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::UDP_SEND_TO, "www.example.com", 8800)); + EXPECT_TRUE(data.Check(param.get())); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::UDP_SEND_TO, "smtp.example.com", 8800)); + EXPECT_TRUE(data.Check(param.get())); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80)); + EXPECT_FALSE(data.Check(param.get())); CHECK(data.Parse("udp-send-to:*.example.com:8800")); - EXPECT_TRUE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::UDP_SEND_TO, "www.example.com", 8800))); - EXPECT_TRUE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::UDP_SEND_TO, "smtp.example.com", 8800))); - EXPECT_TRUE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::UDP_SEND_TO, "SMTP.example.com", 8800))); - EXPECT_FALSE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80))); - EXPECT_FALSE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::UDP_SEND_TO, "www.google.com", 8800))); - EXPECT_FALSE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::UDP_SEND_TO, "wwwexample.com", 8800))); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::UDP_SEND_TO, "www.example.com", 8800)); + EXPECT_TRUE(data.Check(param.get())); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::UDP_SEND_TO, "smtp.example.com", 8800)); + EXPECT_TRUE(data.Check(param.get())); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::UDP_SEND_TO, "SMTP.example.com", 8800)); + EXPECT_TRUE(data.Check(param.get())); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80)); + EXPECT_FALSE(data.Check(param.get())); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::UDP_SEND_TO, "www.google.com", 8800)); + EXPECT_FALSE(data.Check(param.get())); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::UDP_SEND_TO, "wwwexample.com", 8800)); + EXPECT_FALSE(data.Check(param.get())); CHECK(data.Parse("udp-send-to:*.ExAmPlE.cOm:8800")); - EXPECT_TRUE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::UDP_SEND_TO, "www.example.com", 8800))); - EXPECT_TRUE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::UDP_SEND_TO, "smtp.example.com", 8800))); - EXPECT_TRUE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::UDP_SEND_TO, "SMTP.example.com", 8800))); - EXPECT_FALSE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80))); - EXPECT_FALSE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::UDP_SEND_TO, "www.google.com", 8800))); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::UDP_SEND_TO, "www.example.com", 8800)); + EXPECT_TRUE(data.Check(param.get())); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::UDP_SEND_TO, "smtp.example.com", 8800)); + EXPECT_TRUE(data.Check(param.get())); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::UDP_SEND_TO, "SMTP.example.com", 8800)); + EXPECT_TRUE(data.Check(param.get())); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80)); + EXPECT_FALSE(data.Check(param.get())); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::UDP_SEND_TO, "www.google.com", 8800)); + EXPECT_FALSE(data.Check(param.get())); CHECK(data.Parse("udp-bind::8800")); - EXPECT_TRUE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::UDP_BIND, "127.0.0.1", 8800))); - EXPECT_FALSE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::UDP_BIND, "127.0.0.1", 8888))); - EXPECT_FALSE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80))); - EXPECT_FALSE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::UDP_SEND_TO, "www.google.com", 8800))); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::UDP_BIND, "127.0.0.1", 8800)); + EXPECT_TRUE(data.Check(param.get())); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::UDP_BIND, "127.0.0.1", 8888)); + EXPECT_FALSE(data.Check(param.get())); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80)); + EXPECT_FALSE(data.Check(param.get())); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::UDP_SEND_TO, "www.google.com", 8800)); + EXPECT_FALSE(data.Check(param.get())); // Do not wildcard part of ip address. CHECK(data.Parse("tcp-connect:*.168.0.1:8800")); - EXPECT_FALSE(data.Match(SocketPermissionRequest( - SocketPermissionRequest::TCP_CONNECT, "192.168.0.1", 8800))); + param.reset(new SocketPermission::CheckParam( + SocketPermissionRequest::TCP_CONNECT, "192.168.0.1", 8800)); + EXPECT_FALSE(data.Check(param.get())); } TEST(SocketPermissionTest, IPC) { |