| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef CHROME_COMMON_EXTENSIONS_PERMISSIONS_SET_DISJUNCTION_PERMISSION_H_ | |
| 6 #define CHROME_COMMON_EXTENSIONS_PERMISSIONS_SET_DISJUNCTION_PERMISSION_H_ | |
| 7 | |
| 8 #include <algorithm> | |
| 9 #include <set> | |
| 10 #include <string> | |
| 11 | |
| 12 #include "base/memory/scoped_ptr.h" | |
| 13 #include "base/values.h" | |
| 14 #include "extensions/common/extension_messages.h" | |
| 15 #include "extensions/common/permissions/api_permission.h" | |
| 16 #include "ipc/ipc_message.h" | |
| 17 #include "ipc/ipc_message_utils.h" | |
| 18 | |
| 19 namespace extensions { | |
| 20 | |
| 21 // An abstract base class for permissions that are represented by the | |
| 22 // disjunction of a set of conditions. Each condition is represented by a | |
| 23 // |PermissionDataType| (e.g. SocketPermissionData). If an | |
| 24 // APIPermission::CheckParam matches any of the conditions in the set, the | |
| 25 // permission is granted. | |
| 26 // | |
| 27 // For an example of how to use this class, see SocketPermission. | |
| 28 template <class PermissionDataType, class DerivedType> | |
| 29 class SetDisjunctionPermission : public APIPermission { | |
| 30 public: | |
| 31 explicit SetDisjunctionPermission(const APIPermissionInfo* info) | |
| 32 : APIPermission(info) { | |
| 33 } | |
| 34 | |
| 35 ~SetDisjunctionPermission() { | |
| 36 } | |
| 37 | |
| 38 // APIPermission overrides | |
| 39 virtual bool HasMessages() const OVERRIDE { | |
| 40 return !data_set_.empty(); | |
| 41 } | |
| 42 | |
| 43 virtual bool Check(const APIPermission::CheckParam* param) const OVERRIDE { | |
| 44 for (typename std::set<PermissionDataType>::const_iterator i = | |
| 45 data_set_.begin(); i != data_set_.end(); ++i) { | |
| 46 if (i->Check(param)) | |
| 47 return true; | |
| 48 } | |
| 49 return false; | |
| 50 } | |
| 51 | |
| 52 virtual bool Contains(const APIPermission* rhs) const OVERRIDE { | |
| 53 CHECK(rhs->info() == info()); | |
| 54 const SetDisjunctionPermission* perm = | |
| 55 static_cast<const SetDisjunctionPermission*>(rhs); | |
| 56 return std::includes( | |
| 57 data_set_.begin(), data_set_.end(), | |
| 58 perm->data_set_.begin(), perm->data_set_.end()); | |
| 59 } | |
| 60 | |
| 61 virtual bool Equal(const APIPermission* rhs) const OVERRIDE { | |
| 62 CHECK(rhs->info() == info()); | |
| 63 const SetDisjunctionPermission* perm = | |
| 64 static_cast<const SetDisjunctionPermission*>(rhs); | |
| 65 return data_set_ == perm->data_set_; | |
| 66 } | |
| 67 | |
| 68 virtual APIPermission* Clone() const OVERRIDE { | |
| 69 SetDisjunctionPermission* result = new DerivedType(info()); | |
| 70 result->data_set_ = data_set_; | |
| 71 return result; | |
| 72 } | |
| 73 | |
| 74 virtual APIPermission* Diff(const APIPermission* rhs) const OVERRIDE { | |
| 75 CHECK(rhs->info() == info()); | |
| 76 const SetDisjunctionPermission* perm = | |
| 77 static_cast<const SetDisjunctionPermission*>(rhs); | |
| 78 scoped_ptr<SetDisjunctionPermission> result(new DerivedType(info())); | |
| 79 std::set_difference( | |
| 80 data_set_.begin(), data_set_.end(), | |
| 81 perm->data_set_.begin(), perm->data_set_.end(), | |
| 82 std::inserter<std::set<PermissionDataType> >( | |
| 83 result->data_set_, result->data_set_.begin())); | |
| 84 return result->data_set_.empty() ? NULL : result.release(); | |
| 85 } | |
| 86 | |
| 87 virtual APIPermission* Union(const APIPermission* rhs) const OVERRIDE { | |
| 88 CHECK(rhs->info() == info()); | |
| 89 const SetDisjunctionPermission* perm = | |
| 90 static_cast<const SetDisjunctionPermission*>(rhs); | |
| 91 scoped_ptr<SetDisjunctionPermission> result(new DerivedType(info())); | |
| 92 std::set_union( | |
| 93 data_set_.begin(), data_set_.end(), | |
| 94 perm->data_set_.begin(), perm->data_set_.end(), | |
| 95 std::inserter<std::set<PermissionDataType> >( | |
| 96 result->data_set_, result->data_set_.begin())); | |
| 97 return result.release(); | |
| 98 } | |
| 99 | |
| 100 virtual APIPermission* Intersect(const APIPermission* rhs) const OVERRIDE { | |
| 101 CHECK(rhs->info() == info()); | |
| 102 const SetDisjunctionPermission* perm = | |
| 103 static_cast<const SetDisjunctionPermission*>(rhs); | |
| 104 scoped_ptr<SetDisjunctionPermission> result(new DerivedType(info())); | |
| 105 std::set_intersection( | |
| 106 data_set_.begin(), data_set_.end(), | |
| 107 perm->data_set_.begin(), perm->data_set_.end(), | |
| 108 std::inserter<std::set<PermissionDataType> >( | |
| 109 result->data_set_, result->data_set_.begin())); | |
| 110 return result->data_set_.empty() ? NULL : result.release(); | |
| 111 } | |
| 112 | |
| 113 virtual bool FromValue(const base::Value* value, | |
| 114 std::string* error) OVERRIDE { | |
| 115 data_set_.clear(); | |
| 116 const base::ListValue* list = NULL; | |
| 117 | |
| 118 if (!value || !value->GetAsList(&list) || list->GetSize() == 0) { | |
| 119 if (error) | |
| 120 *error = "NULL or empty permission list"; | |
| 121 return false; | |
| 122 } | |
| 123 | |
| 124 for (size_t i = 0; i < list->GetSize(); ++i) { | |
| 125 const base::Value* item_value = NULL; | |
| 126 bool got_item = list->Get(i, &item_value); | |
| 127 DCHECK(got_item); | |
| 128 DCHECK(item_value); | |
| 129 | |
| 130 PermissionDataType data; | |
| 131 if (!data.FromValue(item_value)) { | |
| 132 if (error) | |
| 133 *error = "Cannot parse an item from the permission list"; | |
| 134 return false; | |
| 135 } | |
| 136 | |
| 137 data_set_.insert(data); | |
| 138 } | |
| 139 return true; | |
| 140 } | |
| 141 | |
| 142 virtual scoped_ptr<base::Value> ToValue() const OVERRIDE { | |
| 143 base::ListValue* list = new base::ListValue(); | |
| 144 typename std::set<PermissionDataType>::const_iterator i; | |
| 145 for (i = data_set_.begin(); i != data_set_.end(); ++i) { | |
| 146 scoped_ptr<base::Value> item_value(i->ToValue()); | |
| 147 list->Append(item_value.release()); | |
| 148 } | |
| 149 return scoped_ptr<base::Value>(list); | |
| 150 } | |
| 151 | |
| 152 virtual void Write(IPC::Message* m) const OVERRIDE { | |
| 153 IPC::WriteParam(m, data_set_); | |
| 154 } | |
| 155 | |
| 156 virtual bool Read(const IPC::Message* m, PickleIterator* iter) OVERRIDE { | |
| 157 return IPC::ReadParam(m, iter, &data_set_); | |
| 158 } | |
| 159 | |
| 160 virtual void Log(std::string* log) const OVERRIDE { | |
| 161 IPC::LogParam(data_set_, log); | |
| 162 } | |
| 163 | |
| 164 protected: | |
| 165 std::set<PermissionDataType> data_set_; | |
| 166 }; | |
| 167 | |
| 168 } // namespace extensions | |
| 169 | |
| 170 #endif // CHROME_COMMON_EXTENSIONS_PERMISSIONS_SET_DISJUNCTION_PERMISSION_H_ | |
| OLD | NEW |