Chromium Code Reviews| Index: extensions/common/permissions/api_permission_set.cc |
| diff --git a/extensions/common/permissions/api_permission_set.cc b/extensions/common/permissions/api_permission_set.cc |
| index ebaf8d8bca40f11383501590c8be1bbeec4ed218..d59708d011a71a47832386a1c52e6f3d92ced659 100644 |
| --- a/extensions/common/permissions/api_permission_set.cc |
| +++ b/extensions/common/permissions/api_permission_set.cc |
| @@ -109,6 +109,155 @@ bool ParseChildPermissions(const std::string& base_name, |
| } // namespace |
| +template <typename T> |
| +class SetOperations { |
| + public: |
| + typedef typename T::const_iterator const_iterator; |
| + |
| + static T& Assign(T& lhs, const T& rhs) { |
| + const_iterator it = rhs.begin(); |
| + const const_iterator end = rhs.end(); |
| + while (it != end) { |
| + lhs.insert(it->Clone()); |
| + ++it; |
| + } |
| + return lhs; |
| + } |
| + |
| + static bool Equal(const T& lhs, const T& rhs) { |
| + const_iterator it = lhs.begin(); |
| + const_iterator rhs_it = rhs.begin(); |
| + const_iterator it_end = lhs.end(); |
| + const_iterator rhs_it_end = rhs.end(); |
| + |
| + while (it != it_end && rhs_it != rhs_it_end) { |
| + if (!it->Equal(*rhs_it)) |
| + return false; |
| + ++it; |
| + ++rhs_it; |
| + } |
| + return it == it_end && rhs_it == rhs_it_end; |
| + } |
| + |
| + static bool Contains(const T& lhs, const T& rhs) { |
| + const_iterator it1 = lhs.begin(); |
| + const_iterator it2 = rhs.begin(); |
| + const_iterator end1 = lhs.end(); |
| + const_iterator end2 = rhs.end(); |
| + |
| + while (it1 != end1 && it2 != end2) { |
| + if (it1->id() > it2->id()) { |
| + return false; |
| + } else if (it1->id() < it2->id()) { |
| + ++it1; |
| + } else { |
| + if (!it1->Contains(*it2)) |
| + return false; |
| + ++it1; |
| + ++it2; |
| + } |
| + } |
| + |
| + return it2 == end2; |
| + } |
| + |
| + template <typename U> |
| + static void Difference(const T& set1, const T& set2, T* set3) { |
| + CHECK(set3); |
| + set3->clear(); |
| + |
| + const_iterator it1 = set1.begin(); |
| + const_iterator it2 = set2.begin(); |
| + const const_iterator end1 = set1.end(); |
| + const const_iterator end2 = set2.end(); |
| + |
| + while (it1 != end1 && it2 != end2) { |
| + if (it1->id() < it2->id()) { |
| + set3->insert(it1->Clone()); |
| + ++it1; |
| + } else if (it1->id() > it2->id()) { |
| + ++it2; |
| + } else { |
| + U* p = it1->Diff(*it2); |
| + if (p) |
| + set3->insert(p); |
| + ++it1; |
| + ++it2; |
| + } |
| + } |
| + |
| + while (it1 != end1) { |
| + set3->insert(it1->Clone()); |
| + ++it1; |
| + } |
| + } |
| + |
| + template<typename U> |
| + static void Intersection(const T& set1, const T& set2, T* set3) { |
| + DCHECK(set3); |
| + set3->clear(); |
| + |
| + const_iterator it1 = set1.begin(); |
| + const_iterator it2 = set2.begin(); |
| + const const_iterator end1 = set1.end(); |
| + const const_iterator end2 = set2.end(); |
| + |
| + while (it1 != end1 && it2 != end2) { |
| + if (it1->id() < it2->id()) { |
| + ++it1; |
| + } else if (it1->id() > it2->id()) { |
| + ++it2; |
| + } else { |
| + U* p = it1->Intersect(*it2); |
| + if (p) |
| + set3->insert(p); |
| + ++it1; |
| + ++it2; |
| + } |
| + } |
| + } |
| + |
| + template<typename U> |
| + static void Union(const T& set1, const T& set2, T* set3) { |
| + DCHECK(set3); |
| + set3->clear(); |
| + |
| + const_iterator it1 = set1.begin(); |
| + const_iterator it2 = set2.begin(); |
| + const const_iterator end1 = set1.end(); |
| + const const_iterator end2 = set2.end(); |
| + |
| + while (true) { |
| + if (it1 == end1) { |
| + while (it2 != end2) { |
| + set3->insert(it2->Clone()); |
| + ++it2; |
| + } |
| + break; |
| + } |
| + if (it2 == end2) { |
| + while (it1 != end1) { |
| + set3->insert(it1->Clone()); |
| + ++it1; |
| + } |
| + break; |
| + } |
| + if (it1->id() < it2->id()) { |
| + set3->insert(it1->Clone()); |
| + ++it1; |
| + } else if (it1->id() > it2->id()) { |
| + set3->insert(it2->Clone()); |
| + ++it2; |
| + } else { |
| + set3->insert(it1->Union(*it2)); |
| + ++it1; |
| + ++it2; |
| + } |
| + } |
| + } |
| +}; |
| + |
| + |
| APIPermissionSet::APIPermissionSet() { |
| } |
| @@ -130,28 +279,11 @@ APIPermissionSet::const_iterator::const_iterator( |
| } |
| APIPermissionSet& APIPermissionSet::operator=(const APIPermissionSet& rhs) { |
| - const_iterator it = rhs.begin(); |
| - const const_iterator end = rhs.end(); |
| - while (it != end) { |
| - insert(it->Clone()); |
| - ++it; |
| - } |
| - return *this; |
| + return SetOperations<APIPermissionSet>::Assign(*this, rhs); |
| } |
| bool APIPermissionSet::operator==(const APIPermissionSet& rhs) const { |
| - const_iterator it = begin(); |
| - const_iterator rhs_it = rhs.begin(); |
| - const_iterator it_end = end(); |
| - const_iterator rhs_it_end = rhs.end(); |
| - |
| - while (it != it_end && rhs_it != rhs_it_end) { |
| - if (!it->Equal(*rhs_it)) |
| - return false; |
| - ++it; |
| - ++rhs_it; |
| - } |
| - return it == it_end && rhs_it == rhs_it_end; |
| + return SetOperations<APIPermissionSet>::Equal(*this, rhs); |
| } |
| void APIPermissionSet::insert(APIPermission::ID id) { |
| @@ -165,126 +297,29 @@ void APIPermissionSet::insert(APIPermission* permission) { |
| } |
| bool APIPermissionSet::Contains(const APIPermissionSet& rhs) const { |
| - APIPermissionSet::const_iterator it1 = begin(); |
| - APIPermissionSet::const_iterator it2 = rhs.begin(); |
| - APIPermissionSet::const_iterator end1 = end(); |
| - APIPermissionSet::const_iterator end2 = rhs.end(); |
| - |
| - while (it1 != end1 && it2 != end2) { |
| - if (it1->id() > it2->id()) { |
| - return false; |
| - } else if (it1->id() < it2->id()) { |
| - ++it1; |
| - } else { |
| - if (!it1->Contains(*it2)) |
| - return false; |
| - ++it1; |
| - ++it2; |
| - } |
| - } |
| - |
| - return it2 == end2; |
| + return SetOperations<APIPermissionSet>::Contains(*this, rhs); |
| } |
| void APIPermissionSet::Difference( |
| const APIPermissionSet& set1, |
| const APIPermissionSet& set2, |
| APIPermissionSet* set3) { |
| - CHECK(set3); |
| - set3->clear(); |
| - |
| - APIPermissionSet::const_iterator it1 = set1.begin(); |
| - APIPermissionSet::const_iterator it2 = set2.begin(); |
| - const APIPermissionSet::const_iterator end1 = set1.end(); |
| - const APIPermissionSet::const_iterator end2 = set2.end(); |
| - |
| - while (it1 != end1 && it2 != end2) { |
| - if (it1->id() < it2->id()) { |
| - set3->insert(it1->Clone()); |
| - ++it1; |
| - } else if (it1->id() > it2->id()) { |
| - ++it2; |
| - } else { |
| - APIPermission* p = it1->Diff(*it2); |
| - if (p) |
| - set3->insert(p); |
| - ++it1; |
| - ++it2; |
| - } |
| - } |
| - |
| - while (it1 != end1) { |
| - set3->insert(it1->Clone()); |
| - ++it1; |
| - } |
| + SetOperations<APIPermissionSet>::Difference<APIPermission>(set1, set2, set3); |
| } |
| void APIPermissionSet::Intersection( |
| const APIPermissionSet& set1, |
| const APIPermissionSet& set2, |
| APIPermissionSet* set3) { |
| - DCHECK(set3); |
| - set3->clear(); |
| - |
| - APIPermissionSet::const_iterator it1 = set1.begin(); |
| - APIPermissionSet::const_iterator it2 = set2.begin(); |
| - const APIPermissionSet::const_iterator end1 = set1.end(); |
| - const APIPermissionSet::const_iterator end2 = set2.end(); |
| - |
| - while (it1 != end1 && it2 != end2) { |
| - if (it1->id() < it2->id()) { |
| - ++it1; |
| - } else if (it1->id() > it2->id()) { |
| - ++it2; |
| - } else { |
| - APIPermission* p = it1->Intersect(*it2); |
| - if (p) |
| - set3->insert(p); |
| - ++it1; |
| - ++it2; |
| - } |
| - } |
| + SetOperations<APIPermissionSet>::Intersection<APIPermission>( |
| + set1, set2, set3); |
| } |
| void APIPermissionSet::Union( |
| const APIPermissionSet& set1, |
| const APIPermissionSet& set2, |
| APIPermissionSet* set3) { |
| - DCHECK(set3); |
| - set3->clear(); |
| - |
| - APIPermissionSet::const_iterator it1 = set1.begin(); |
| - APIPermissionSet::const_iterator it2 = set2.begin(); |
| - const APIPermissionSet::const_iterator end1 = set1.end(); |
| - const APIPermissionSet::const_iterator end2 = set2.end(); |
| - |
| - while (true) { |
| - if (it1 == end1) { |
| - while (it2 != end2) { |
| - set3->insert(it2->Clone()); |
| - ++it2; |
| - } |
| - break; |
| - } |
| - if (it2 == end2) { |
| - while (it1 != end1) { |
| - set3->insert(it1->Clone()); |
| - ++it1; |
| - } |
| - break; |
| - } |
| - if (it1->id() < it2->id()) { |
| - set3->insert(it1->Clone()); |
| - ++it1; |
| - } else if (it1->id() > it2->id()) { |
| - set3->insert(it2->Clone()); |
| - ++it2; |
| - } else { |
| - set3->insert(it1->Union(*it2)); |
| - ++it1; |
| - ++it2; |
| - } |
| - } |
| + SetOperations<APIPermissionSet>::Union<APIPermission>(set1, set2, set3); |
| } |
| // static |
| @@ -340,4 +375,159 @@ void APIPermissionSet::AddImpliedPermissions() { |
| } |
| } |
| +ManifestPermissionSet::ManifestPermissionSet() { |
| +} |
| + |
| +ManifestPermissionSet::ManifestPermissionSet( |
| + const ManifestPermissionSet& set) { |
| + this->operator=(set); |
| +} |
| + |
| +ManifestPermissionSet::~ManifestPermissionSet() { |
| +} |
| + |
| +ManifestPermissionSet::const_iterator::const_iterator( |
| + const ManifestPermissionMap::const_iterator& it) |
| + : it_(it) { |
| +} |
| + |
| +ManifestPermissionSet::const_iterator::const_iterator( |
| + const const_iterator& ids_it) |
| + : it_(ids_it.it_) { |
| +} |
| + |
| +ManifestPermissionSet& ManifestPermissionSet::operator=( |
| + const ManifestPermissionSet& rhs) { |
| + return SetOperations<ManifestPermissionSet>::Assign(*this, rhs); |
| +} |
| + |
| +bool ManifestPermissionSet::operator==(const ManifestPermissionSet& rhs) |
| + const { |
| + return SetOperations<ManifestPermissionSet>::Equal(*this, rhs); |
| +} |
| + |
| +void ManifestPermissionSet::insert(std::string id) { |
| + // TODO(rpaquay) |
| + //const APIPermissionInfo* permission_info = |
| + // PermissionsInfo::GetInstance()->GetByID(id); |
| + //insert(permission_info->CreateAPIPermission()); |
| +} |
| + |
| +void ManifestPermissionSet::insert(ManifestPermission* permission) { |
| + // TODO(rpaquay) |
| + //map_[permission->id()].reset(permission); |
| +} |
| + |
| +bool ManifestPermissionSet::Contains(const ManifestPermissionSet& rhs) |
| + const { |
| + return SetOperations<ManifestPermissionSet>::Contains(*this, rhs); |
| +} |
| + |
| +void ManifestPermissionSet::Difference( |
| + const ManifestPermissionSet& set1, |
| + const ManifestPermissionSet& set2, |
| + ManifestPermissionSet* set3) { |
| + SetOperations<ManifestPermissionSet>::Difference<ManifestPermission>( |
| + set1, set2, set3); |
| +} |
| + |
| +void ManifestPermissionSet::Intersection( |
| + const ManifestPermissionSet& set1, |
| + const ManifestPermissionSet& set2, |
| + ManifestPermissionSet* set3) { |
| + SetOperations<ManifestPermissionSet>::Intersection<ManifestPermission>( |
| + set1, set2, set3); |
| +} |
| + |
| +void ManifestPermissionSet::Union( |
| + const ManifestPermissionSet& set1, |
| + const ManifestPermissionSet& set2, |
| + ManifestPermissionSet* set3) { |
| + SetOperations<ManifestPermissionSet>::Union<ManifestPermission>( |
| + set1, set2, set3); |
| +} |
| + |
| +// static |
| +bool ManifestPermissionSet::ParseFromJSON( |
| + const base::ListValue* permissions, |
| + ManifestPermissionSet* manifest_permissions, |
| + string16* error, |
| + std::vector<std::string>* unhandled_permissions) { |
| + // TODO(rpaquay): Update name of local variables to reflect we are dealing |
| + // with manifest_permissions entries. |
| + for (size_t i = 0; i < permissions->GetSize(); ++i) { |
| + std::string permission_name; |
| + const base::Value* permission_value = NULL; |
| + if (!permissions->GetString(i, &permission_name)) { |
| + const base::DictionaryValue* dict = NULL; |
| + // permission should be a string or a single key dict. |
|
Yoyo Zhou
2013/11/06 04:02:36
Is this still true?
rpaquay
2013/11/06 16:16:16
I am not 100% sure yet, but i think it is. Either
|
| + if (!permissions->GetDictionary(i, &dict) || dict->size() != 1) { |
| + if (error) { |
| + *error = ErrorUtils::FormatErrorMessageUTF16( |
| + errors::kInvalidPermission, base::IntToString(i)); |
| + return false; |
| + } |
| + LOG(WARNING) << "Permission is not a string or single key dict."; |
| + continue; |
| + } |
| + base::DictionaryValue::Iterator it(*dict); |
| + permission_name = it.key(); |
| + permission_value = &it.value(); |
| + } |
| + |
| + if (!CreateManifestPermission(permission_name, permission_value, |
| + manifest_permissions, error, |
| + unhandled_permissions)) |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| +// static |
| +bool ManifestPermissionSet::CreateManifestPermission( |
| + const std::string& permission_name, |
| + const base::Value* permission_value, |
| + ManifestPermissionSet* manifest_permissions, |
| + string16* error, |
| + std::vector<std::string>* unhandled_permissions) { |
| +#if 0 |
| + const ManifestPermission* permission = |
| + ManifestHandler::CreateManifestPermission(permission_name, |
| + permission_value); |
| + const APIPermissionInfo* permission_info = |
| + PermissionsInfo::GetInstance()->GetByName(permission_str); |
| + if (permission_info) { |
| + scoped_ptr<APIPermission> permission( |
| + permission_info->CreateAPIPermission()); |
| + if (source != APIPermissionSet::kAllowInternalPermissions && |
| + permission_info->is_internal()) { |
| + // An internal permission specified in permissions list is an error. |
| + if (error) { |
| + *error = ErrorUtils::FormatErrorMessageUTF16( |
| + errors::kPermissionNotAllowedInManifest, permission_str); |
| + } |
| + return false; |
| + } |
| + |
| + if (!permission->FromValue(permission_value)) { |
| + if (error) { |
| + *error = ErrorUtils::FormatErrorMessageUTF16( |
| + errors::kInvalidPermission, permission_info->name()); |
| + return false; |
| + } |
| + LOG(WARNING) << "Parse permission failed."; |
| + } else { |
| + api_permissions->insert(permission.release()); |
| + } |
| + return true; |
| + } |
| + |
| + if (unhandled_permissions) |
| + unhandled_permissions->push_back(permission_str); |
| + else |
| + LOG(WARNING) << "Unknown permission[" << permission_str << "]."; |
| +#endif |
| + return true; |
| +} |
| + |
| } // namespace extensions |