Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(341)

Side by Side Diff: extensions/common/permissions/api_permission_set.cc

Issue 51433002: Enable permission warnings from ManifestHandlers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Working on adding ManifestPermissionSet to PermissionSet. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698