OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "extensions/common/permissions/api_permission_set.h" | 5 #include "extensions/common/permissions/api_permission_set.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
102 return false; | 102 return false; |
103 } | 103 } |
104 } | 104 } |
105 | 105 |
106 return CreateAPIPermission(base_name, NULL, source, | 106 return CreateAPIPermission(base_name, NULL, source, |
107 api_permissions, error, NULL); | 107 api_permissions, error, NULL); |
108 } | 108 } |
109 | 109 |
110 } // namespace | 110 } // namespace |
111 | 111 |
112 template <typename T> | |
113 class SetOperations { | |
114 public: | |
115 typedef typename T::const_iterator const_iterator; | |
116 | |
117 static T& Assign(T& lhs, const T& rhs) { | |
118 const_iterator it = rhs.begin(); | |
119 const const_iterator end = rhs.end(); | |
120 while (it != end) { | |
121 lhs.insert(it->Clone()); | |
122 ++it; | |
123 } | |
124 return lhs; | |
125 } | |
126 | |
127 static bool Equal(const T& lhs, const T& rhs) { | |
128 const_iterator it = lhs.begin(); | |
129 const_iterator rhs_it = rhs.begin(); | |
130 const_iterator it_end = lhs.end(); | |
131 const_iterator rhs_it_end = rhs.end(); | |
132 | |
133 while (it != it_end && rhs_it != rhs_it_end) { | |
134 if (!it->Equal(*rhs_it)) | |
135 return false; | |
136 ++it; | |
137 ++rhs_it; | |
138 } | |
139 return it == it_end && rhs_it == rhs_it_end; | |
140 } | |
141 | |
142 static bool Contains(const T& lhs, const T& rhs) { | |
143 const_iterator it1 = lhs.begin(); | |
144 const_iterator it2 = rhs.begin(); | |
145 const_iterator end1 = lhs.end(); | |
146 const_iterator end2 = rhs.end(); | |
147 | |
148 while (it1 != end1 && it2 != end2) { | |
149 if (it1->id() > it2->id()) { | |
150 return false; | |
151 } else if (it1->id() < it2->id()) { | |
152 ++it1; | |
153 } else { | |
154 if (!it1->Contains(*it2)) | |
155 return false; | |
156 ++it1; | |
157 ++it2; | |
158 } | |
159 } | |
160 | |
161 return it2 == end2; | |
162 } | |
163 | |
164 template <typename U> | |
165 static void Difference(const T& set1, const T& set2, T* set3) { | |
166 CHECK(set3); | |
167 set3->clear(); | |
168 | |
169 const_iterator it1 = set1.begin(); | |
170 const_iterator it2 = set2.begin(); | |
171 const const_iterator end1 = set1.end(); | |
172 const const_iterator end2 = set2.end(); | |
173 | |
174 while (it1 != end1 && it2 != end2) { | |
175 if (it1->id() < it2->id()) { | |
176 set3->insert(it1->Clone()); | |
177 ++it1; | |
178 } else if (it1->id() > it2->id()) { | |
179 ++it2; | |
180 } else { | |
181 U* p = it1->Diff(*it2); | |
182 if (p) | |
183 set3->insert(p); | |
184 ++it1; | |
185 ++it2; | |
186 } | |
187 } | |
188 | |
189 while (it1 != end1) { | |
190 set3->insert(it1->Clone()); | |
191 ++it1; | |
192 } | |
193 } | |
194 | |
195 template<typename U> | |
196 static void Intersection(const T& set1, const T& set2, T* set3) { | |
197 DCHECK(set3); | |
198 set3->clear(); | |
199 | |
200 const_iterator it1 = set1.begin(); | |
201 const_iterator it2 = set2.begin(); | |
202 const const_iterator end1 = set1.end(); | |
203 const const_iterator end2 = set2.end(); | |
204 | |
205 while (it1 != end1 && it2 != end2) { | |
206 if (it1->id() < it2->id()) { | |
207 ++it1; | |
208 } else if (it1->id() > it2->id()) { | |
209 ++it2; | |
210 } else { | |
211 U* p = it1->Intersect(*it2); | |
212 if (p) | |
213 set3->insert(p); | |
214 ++it1; | |
215 ++it2; | |
216 } | |
217 } | |
218 } | |
219 | |
220 template<typename U> | |
221 static void Union(const T& set1, const T& set2, T* set3) { | |
222 DCHECK(set3); | |
223 set3->clear(); | |
224 | |
225 const_iterator it1 = set1.begin(); | |
226 const_iterator it2 = set2.begin(); | |
227 const const_iterator end1 = set1.end(); | |
228 const const_iterator end2 = set2.end(); | |
229 | |
230 while (true) { | |
231 if (it1 == end1) { | |
232 while (it2 != end2) { | |
233 set3->insert(it2->Clone()); | |
234 ++it2; | |
235 } | |
236 break; | |
237 } | |
238 if (it2 == end2) { | |
239 while (it1 != end1) { | |
240 set3->insert(it1->Clone()); | |
241 ++it1; | |
242 } | |
243 break; | |
244 } | |
245 if (it1->id() < it2->id()) { | |
246 set3->insert(it1->Clone()); | |
247 ++it1; | |
248 } else if (it1->id() > it2->id()) { | |
249 set3->insert(it2->Clone()); | |
250 ++it2; | |
251 } else { | |
252 set3->insert(it1->Union(*it2)); | |
253 ++it1; | |
254 ++it2; | |
255 } | |
256 } | |
257 } | |
258 }; | |
259 | |
260 | |
112 APIPermissionSet::APIPermissionSet() { | 261 APIPermissionSet::APIPermissionSet() { |
113 } | 262 } |
114 | 263 |
115 APIPermissionSet::APIPermissionSet(const APIPermissionSet& set) { | 264 APIPermissionSet::APIPermissionSet(const APIPermissionSet& set) { |
116 this->operator=(set); | 265 this->operator=(set); |
117 } | 266 } |
118 | 267 |
119 APIPermissionSet::~APIPermissionSet() { | 268 APIPermissionSet::~APIPermissionSet() { |
120 } | 269 } |
121 | 270 |
122 APIPermissionSet::const_iterator::const_iterator( | 271 APIPermissionSet::const_iterator::const_iterator( |
123 const APIPermissionMap::const_iterator& it) | 272 const APIPermissionMap::const_iterator& it) |
124 : it_(it) { | 273 : it_(it) { |
125 } | 274 } |
126 | 275 |
127 APIPermissionSet::const_iterator::const_iterator( | 276 APIPermissionSet::const_iterator::const_iterator( |
128 const const_iterator& ids_it) | 277 const const_iterator& ids_it) |
129 : it_(ids_it.it_) { | 278 : it_(ids_it.it_) { |
130 } | 279 } |
131 | 280 |
132 APIPermissionSet& APIPermissionSet::operator=(const APIPermissionSet& rhs) { | 281 APIPermissionSet& APIPermissionSet::operator=(const APIPermissionSet& rhs) { |
133 const_iterator it = rhs.begin(); | 282 return SetOperations<APIPermissionSet>::Assign(*this, rhs); |
134 const const_iterator end = rhs.end(); | |
135 while (it != end) { | |
136 insert(it->Clone()); | |
137 ++it; | |
138 } | |
139 return *this; | |
140 } | 283 } |
141 | 284 |
142 bool APIPermissionSet::operator==(const APIPermissionSet& rhs) const { | 285 bool APIPermissionSet::operator==(const APIPermissionSet& rhs) const { |
143 const_iterator it = begin(); | 286 return SetOperations<APIPermissionSet>::Equal(*this, rhs); |
144 const_iterator rhs_it = rhs.begin(); | |
145 const_iterator it_end = end(); | |
146 const_iterator rhs_it_end = rhs.end(); | |
147 | |
148 while (it != it_end && rhs_it != rhs_it_end) { | |
149 if (!it->Equal(*rhs_it)) | |
150 return false; | |
151 ++it; | |
152 ++rhs_it; | |
153 } | |
154 return it == it_end && rhs_it == rhs_it_end; | |
155 } | 287 } |
156 | 288 |
157 void APIPermissionSet::insert(APIPermission::ID id) { | 289 void APIPermissionSet::insert(APIPermission::ID id) { |
158 const APIPermissionInfo* permission_info = | 290 const APIPermissionInfo* permission_info = |
159 PermissionsInfo::GetInstance()->GetByID(id); | 291 PermissionsInfo::GetInstance()->GetByID(id); |
160 insert(permission_info->CreateAPIPermission()); | 292 insert(permission_info->CreateAPIPermission()); |
161 } | 293 } |
162 | 294 |
163 void APIPermissionSet::insert(APIPermission* permission) { | 295 void APIPermissionSet::insert(APIPermission* permission) { |
164 map_[permission->id()].reset(permission); | 296 map_[permission->id()].reset(permission); |
165 } | 297 } |
166 | 298 |
167 bool APIPermissionSet::Contains(const APIPermissionSet& rhs) const { | 299 bool APIPermissionSet::Contains(const APIPermissionSet& rhs) const { |
168 APIPermissionSet::const_iterator it1 = begin(); | 300 return SetOperations<APIPermissionSet>::Contains(*this, rhs); |
169 APIPermissionSet::const_iterator it2 = rhs.begin(); | |
170 APIPermissionSet::const_iterator end1 = end(); | |
171 APIPermissionSet::const_iterator end2 = rhs.end(); | |
172 | |
173 while (it1 != end1 && it2 != end2) { | |
174 if (it1->id() > it2->id()) { | |
175 return false; | |
176 } else if (it1->id() < it2->id()) { | |
177 ++it1; | |
178 } else { | |
179 if (!it1->Contains(*it2)) | |
180 return false; | |
181 ++it1; | |
182 ++it2; | |
183 } | |
184 } | |
185 | |
186 return it2 == end2; | |
187 } | 301 } |
188 | 302 |
189 void APIPermissionSet::Difference( | 303 void APIPermissionSet::Difference( |
190 const APIPermissionSet& set1, | 304 const APIPermissionSet& set1, |
191 const APIPermissionSet& set2, | 305 const APIPermissionSet& set2, |
192 APIPermissionSet* set3) { | 306 APIPermissionSet* set3) { |
193 CHECK(set3); | 307 SetOperations<APIPermissionSet>::Difference<APIPermission>(set1, set2, set3); |
194 set3->clear(); | |
195 | |
196 APIPermissionSet::const_iterator it1 = set1.begin(); | |
197 APIPermissionSet::const_iterator it2 = set2.begin(); | |
198 const APIPermissionSet::const_iterator end1 = set1.end(); | |
199 const APIPermissionSet::const_iterator end2 = set2.end(); | |
200 | |
201 while (it1 != end1 && it2 != end2) { | |
202 if (it1->id() < it2->id()) { | |
203 set3->insert(it1->Clone()); | |
204 ++it1; | |
205 } else if (it1->id() > it2->id()) { | |
206 ++it2; | |
207 } else { | |
208 APIPermission* p = it1->Diff(*it2); | |
209 if (p) | |
210 set3->insert(p); | |
211 ++it1; | |
212 ++it2; | |
213 } | |
214 } | |
215 | |
216 while (it1 != end1) { | |
217 set3->insert(it1->Clone()); | |
218 ++it1; | |
219 } | |
220 } | 308 } |
221 | 309 |
222 void APIPermissionSet::Intersection( | 310 void APIPermissionSet::Intersection( |
223 const APIPermissionSet& set1, | 311 const APIPermissionSet& set1, |
224 const APIPermissionSet& set2, | 312 const APIPermissionSet& set2, |
225 APIPermissionSet* set3) { | 313 APIPermissionSet* set3) { |
226 DCHECK(set3); | 314 SetOperations<APIPermissionSet>::Intersection<APIPermission>( |
227 set3->clear(); | 315 set1, set2, set3); |
228 | |
229 APIPermissionSet::const_iterator it1 = set1.begin(); | |
230 APIPermissionSet::const_iterator it2 = set2.begin(); | |
231 const APIPermissionSet::const_iterator end1 = set1.end(); | |
232 const APIPermissionSet::const_iterator end2 = set2.end(); | |
233 | |
234 while (it1 != end1 && it2 != end2) { | |
235 if (it1->id() < it2->id()) { | |
236 ++it1; | |
237 } else if (it1->id() > it2->id()) { | |
238 ++it2; | |
239 } else { | |
240 APIPermission* p = it1->Intersect(*it2); | |
241 if (p) | |
242 set3->insert(p); | |
243 ++it1; | |
244 ++it2; | |
245 } | |
246 } | |
247 } | 316 } |
248 | 317 |
249 void APIPermissionSet::Union( | 318 void APIPermissionSet::Union( |
250 const APIPermissionSet& set1, | 319 const APIPermissionSet& set1, |
251 const APIPermissionSet& set2, | 320 const APIPermissionSet& set2, |
252 APIPermissionSet* set3) { | 321 APIPermissionSet* set3) { |
253 DCHECK(set3); | 322 SetOperations<APIPermissionSet>::Union<APIPermission>(set1, set2, set3); |
254 set3->clear(); | |
255 | |
256 APIPermissionSet::const_iterator it1 = set1.begin(); | |
257 APIPermissionSet::const_iterator it2 = set2.begin(); | |
258 const APIPermissionSet::const_iterator end1 = set1.end(); | |
259 const APIPermissionSet::const_iterator end2 = set2.end(); | |
260 | |
261 while (true) { | |
262 if (it1 == end1) { | |
263 while (it2 != end2) { | |
264 set3->insert(it2->Clone()); | |
265 ++it2; | |
266 } | |
267 break; | |
268 } | |
269 if (it2 == end2) { | |
270 while (it1 != end1) { | |
271 set3->insert(it1->Clone()); | |
272 ++it1; | |
273 } | |
274 break; | |
275 } | |
276 if (it1->id() < it2->id()) { | |
277 set3->insert(it1->Clone()); | |
278 ++it1; | |
279 } else if (it1->id() > it2->id()) { | |
280 set3->insert(it2->Clone()); | |
281 ++it2; | |
282 } else { | |
283 set3->insert(it1->Union(*it2)); | |
284 ++it1; | |
285 ++it2; | |
286 } | |
287 } | |
288 } | 323 } |
289 | 324 |
290 // static | 325 // static |
291 bool APIPermissionSet::ParseFromJSON( | 326 bool APIPermissionSet::ParseFromJSON( |
292 const base::ListValue* permissions, | 327 const base::ListValue* permissions, |
293 APIPermissionSet::ParseSource source, | 328 APIPermissionSet::ParseSource source, |
294 APIPermissionSet* api_permissions, | 329 APIPermissionSet* api_permissions, |
295 string16* error, | 330 string16* error, |
296 std::vector<std::string>* unhandled_permissions) { | 331 std::vector<std::string>* unhandled_permissions) { |
297 for (size_t i = 0; i < permissions->GetSize(); ++i) { | 332 for (size_t i = 0; i < permissions->GetSize(); ++i) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
333 void APIPermissionSet::AddImpliedPermissions() { | 368 void APIPermissionSet::AddImpliedPermissions() { |
334 // The fileSystem.write and fileSystem.directory permissions imply | 369 // The fileSystem.write and fileSystem.directory permissions imply |
335 // fileSystem.writeDirectory. | 370 // fileSystem.writeDirectory. |
336 // TODO(sammc): Remove this. See http://crbug.com/284849. | 371 // TODO(sammc): Remove this. See http://crbug.com/284849. |
337 if (ContainsKey(map_, APIPermission::kFileSystemWrite) && | 372 if (ContainsKey(map_, APIPermission::kFileSystemWrite) && |
338 ContainsKey(map_, APIPermission::kFileSystemDirectory)) { | 373 ContainsKey(map_, APIPermission::kFileSystemDirectory)) { |
339 insert(APIPermission::kFileSystemWriteDirectory); | 374 insert(APIPermission::kFileSystemWriteDirectory); |
340 } | 375 } |
341 } | 376 } |
342 | 377 |
378 ManifestPermissionSet::ManifestPermissionSet() { | |
379 } | |
380 | |
381 ManifestPermissionSet::ManifestPermissionSet( | |
382 const ManifestPermissionSet& set) { | |
383 this->operator=(set); | |
384 } | |
385 | |
386 ManifestPermissionSet::~ManifestPermissionSet() { | |
387 } | |
388 | |
389 ManifestPermissionSet::const_iterator::const_iterator( | |
390 const ManifestPermissionMap::const_iterator& it) | |
391 : it_(it) { | |
392 } | |
393 | |
394 ManifestPermissionSet::const_iterator::const_iterator( | |
395 const const_iterator& ids_it) | |
396 : it_(ids_it.it_) { | |
397 } | |
398 | |
399 ManifestPermissionSet& ManifestPermissionSet::operator=( | |
400 const ManifestPermissionSet& rhs) { | |
401 return SetOperations<ManifestPermissionSet>::Assign(*this, rhs); | |
402 } | |
403 | |
404 bool ManifestPermissionSet::operator==(const ManifestPermissionSet& rhs) | |
405 const { | |
406 return SetOperations<ManifestPermissionSet>::Equal(*this, rhs); | |
407 } | |
408 | |
409 void ManifestPermissionSet::insert(std::string id) { | |
410 // TODO(rpaquay) | |
411 //const APIPermissionInfo* permission_info = | |
412 // PermissionsInfo::GetInstance()->GetByID(id); | |
413 //insert(permission_info->CreateAPIPermission()); | |
414 } | |
415 | |
416 void ManifestPermissionSet::insert(ManifestPermission* permission) { | |
417 // TODO(rpaquay) | |
418 //map_[permission->id()].reset(permission); | |
419 } | |
420 | |
421 bool ManifestPermissionSet::Contains(const ManifestPermissionSet& rhs) | |
422 const { | |
423 return SetOperations<ManifestPermissionSet>::Contains(*this, rhs); | |
424 } | |
425 | |
426 void ManifestPermissionSet::Difference( | |
427 const ManifestPermissionSet& set1, | |
428 const ManifestPermissionSet& set2, | |
429 ManifestPermissionSet* set3) { | |
430 SetOperations<ManifestPermissionSet>::Difference<ManifestPermission>( | |
431 set1, set2, set3); | |
432 } | |
433 | |
434 void ManifestPermissionSet::Intersection( | |
435 const ManifestPermissionSet& set1, | |
436 const ManifestPermissionSet& set2, | |
437 ManifestPermissionSet* set3) { | |
438 SetOperations<ManifestPermissionSet>::Intersection<ManifestPermission>( | |
439 set1, set2, set3); | |
440 } | |
441 | |
442 void ManifestPermissionSet::Union( | |
443 const ManifestPermissionSet& set1, | |
444 const ManifestPermissionSet& set2, | |
445 ManifestPermissionSet* set3) { | |
446 SetOperations<ManifestPermissionSet>::Union<ManifestPermission>( | |
447 set1, set2, set3); | |
448 } | |
449 | |
450 // static | |
451 bool ManifestPermissionSet::ParseFromJSON( | |
452 const base::ListValue* permissions, | |
453 ManifestPermissionSet* manifest_permissions, | |
454 string16* error, | |
455 std::vector<std::string>* unhandled_permissions) { | |
456 // TODO(rpaquay): Update name of local variables to reflect we are dealing | |
457 // with manifest_permissions entries. | |
458 for (size_t i = 0; i < permissions->GetSize(); ++i) { | |
459 std::string permission_name; | |
460 const base::Value* permission_value = NULL; | |
461 if (!permissions->GetString(i, &permission_name)) { | |
462 const base::DictionaryValue* dict = NULL; | |
463 // 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
| |
464 if (!permissions->GetDictionary(i, &dict) || dict->size() != 1) { | |
465 if (error) { | |
466 *error = ErrorUtils::FormatErrorMessageUTF16( | |
467 errors::kInvalidPermission, base::IntToString(i)); | |
468 return false; | |
469 } | |
470 LOG(WARNING) << "Permission is not a string or single key dict."; | |
471 continue; | |
472 } | |
473 base::DictionaryValue::Iterator it(*dict); | |
474 permission_name = it.key(); | |
475 permission_value = &it.value(); | |
476 } | |
477 | |
478 if (!CreateManifestPermission(permission_name, permission_value, | |
479 manifest_permissions, error, | |
480 unhandled_permissions)) | |
481 return false; | |
482 } | |
483 return true; | |
484 } | |
485 | |
486 // static | |
487 bool ManifestPermissionSet::CreateManifestPermission( | |
488 const std::string& permission_name, | |
489 const base::Value* permission_value, | |
490 ManifestPermissionSet* manifest_permissions, | |
491 string16* error, | |
492 std::vector<std::string>* unhandled_permissions) { | |
493 #if 0 | |
494 const ManifestPermission* permission = | |
495 ManifestHandler::CreateManifestPermission(permission_name, | |
496 permission_value); | |
497 const APIPermissionInfo* permission_info = | |
498 PermissionsInfo::GetInstance()->GetByName(permission_str); | |
499 if (permission_info) { | |
500 scoped_ptr<APIPermission> permission( | |
501 permission_info->CreateAPIPermission()); | |
502 if (source != APIPermissionSet::kAllowInternalPermissions && | |
503 permission_info->is_internal()) { | |
504 // An internal permission specified in permissions list is an error. | |
505 if (error) { | |
506 *error = ErrorUtils::FormatErrorMessageUTF16( | |
507 errors::kPermissionNotAllowedInManifest, permission_str); | |
508 } | |
509 return false; | |
510 } | |
511 | |
512 if (!permission->FromValue(permission_value)) { | |
513 if (error) { | |
514 *error = ErrorUtils::FormatErrorMessageUTF16( | |
515 errors::kInvalidPermission, permission_info->name()); | |
516 return false; | |
517 } | |
518 LOG(WARNING) << "Parse permission failed."; | |
519 } else { | |
520 api_permissions->insert(permission.release()); | |
521 } | |
522 return true; | |
523 } | |
524 | |
525 if (unhandled_permissions) | |
526 unhandled_permissions->push_back(permission_str); | |
527 else | |
528 LOG(WARNING) << "Unknown permission[" << permission_str << "]."; | |
529 #endif | |
530 return true; | |
531 } | |
532 | |
343 } // namespace extensions | 533 } // namespace extensions |
OLD | NEW |