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

Side by Side Diff: chrome/browser/extensions/extension_permissions_api.cc

Issue 8493017: Cleanup extension permissions module. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "chrome/browser/extensions/extension_permissions_api.h" 5 #include "chrome/browser/extensions/extension_permissions_api.h"
6 6
7 #include "base/json/json_writer.h" 7 #include "base/json/json_writer.h"
8 #include "base/values.h" 8 #include "base/values.h"
9 #include "chrome/browser/extensions/extension_event_router.h" 9 #include "chrome/browser/extensions/extension_event_router.h"
10 #include "chrome/browser/extensions/extension_prefs.h" 10 #include "chrome/browser/extensions/extension_prefs.h"
11 #include "chrome/browser/extensions/extension_service.h" 11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/common/chrome_notification_types.h" 13 #include "chrome/common/chrome_notification_types.h"
14 #include "chrome/common/extensions/extension.h" 14 #include "chrome/common/extensions/extension.h"
15 #include "chrome/common/extensions/extension_error_utils.h" 15 #include "chrome/common/extensions/extension_error_utils.h"
16 #include "chrome/common/extensions/extension_messages.h" 16 #include "chrome/common/extensions/extension_messages.h"
17 #include "chrome/common/extensions/extension_permission_set.h"
18 #include "chrome/common/extensions/url_pattern_set.h" 17 #include "chrome/common/extensions/url_pattern_set.h"
18 #include "content/browser/renderer_host/render_process_host.h"
19 #include "content/public/browser/notification_service.h" 19 #include "content/public/browser/notification_service.h"
20 #include "googleurl/src/gurl.h" 20 #include "googleurl/src/gurl.h"
21 21
22 namespace { 22 namespace {
23 23
24 const char kApisKey[] = "permissions"; 24 const char kApisKey[] = "permissions";
25 const char kOriginsKey[] = "origins"; 25 const char kOriginsKey[] = "origins";
26 26
27 const char kCantRemoveRequiredPermissionsError[] = 27 const char kCantRemoveRequiredPermissionsError[] =
28 "You cannot remove required permissions."; 28 "You cannot remove required permissions.";
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 origins.AddPattern(origin); 128 origins.AddPattern(origin);
129 } 129 }
130 } 130 }
131 131
132 *ptr = new ExtensionPermissionSet(apis, origins, URLPatternSet()); 132 *ptr = new ExtensionPermissionSet(apis, origins, URLPatternSet());
133 return true; 133 return true;
134 } 134 }
135 135
136 } // namespace 136 } // namespace
137 137
138 ExtensionPermissionsManager::ExtensionPermissionsManager( 138 ExtensionPermissionsUpdater::ExtensionPermissionsUpdater(
139 ExtensionService* extension_service) 139 ExtensionService* extension_service)
140 : extension_service_(extension_service) {} 140 : extension_service_(extension_service) {}
141 141
142 ExtensionPermissionsManager::~ExtensionPermissionsManager() {} 142 ExtensionPermissionsUpdater::~ExtensionPermissionsUpdater() {}
143 143
144 void ExtensionPermissionsManager::AddPermissions( 144 void ExtensionPermissionsUpdater::AddPermissions(
145 const Extension* extension, const ExtensionPermissionSet* permissions) { 145 const Extension* extension, const ExtensionPermissionSet* permissions) {
146 scoped_refptr<const ExtensionPermissionSet> existing( 146 scoped_refptr<const ExtensionPermissionSet> existing(
147 extension->GetActivePermissions()); 147 extension->GetActivePermissions());
148 scoped_refptr<ExtensionPermissionSet> total( 148 scoped_refptr<ExtensionPermissionSet> total(
149 ExtensionPermissionSet::CreateUnion(existing, permissions)); 149 ExtensionPermissionSet::CreateUnion(existing, permissions));
150 scoped_refptr<ExtensionPermissionSet> added( 150 scoped_refptr<ExtensionPermissionSet> added(
151 ExtensionPermissionSet::CreateDifference(total.get(), existing)); 151 ExtensionPermissionSet::CreateDifference(total.get(), existing));
152 152
153 extension_service_->UpdateActivePermissions(extension, total.get()); 153 extension_service_->UpdateActivePermissions(extension, total.get());
154 154
155 // Update the granted permissions so we don't auto-disable the extension. 155 // Update the granted permissions so we don't auto-disable the extension.
156 extension_service_->GrantPermissions(extension); 156 extension_service_->GrantPermissions(extension);
157 157
158 NotifyPermissionsUpdated(ADDED, extension, added.get()); 158 NotifyPermissionsUpdated(ADDED, extension, added.get());
159 } 159 }
160 160
161 void ExtensionPermissionsManager::RemovePermissions( 161 void ExtensionPermissionsUpdater::RemovePermissions(
162 const Extension* extension, const ExtensionPermissionSet* permissions) { 162 const Extension* extension, const ExtensionPermissionSet* permissions) {
163 scoped_refptr<const ExtensionPermissionSet> existing( 163 scoped_refptr<const ExtensionPermissionSet> existing(
164 extension->GetActivePermissions()); 164 extension->GetActivePermissions());
165 scoped_refptr<ExtensionPermissionSet> total( 165 scoped_refptr<ExtensionPermissionSet> total(
166 ExtensionPermissionSet::CreateDifference(existing, permissions)); 166 ExtensionPermissionSet::CreateDifference(existing, permissions));
167 scoped_refptr<ExtensionPermissionSet> removed( 167 scoped_refptr<ExtensionPermissionSet> removed(
168 ExtensionPermissionSet::CreateDifference(existing, total.get())); 168 ExtensionPermissionSet::CreateDifference(existing, total.get()));
169 169
170 // We update the active permissions, and not the granted permissions, because 170 // We update the active permissions, and not the granted permissions, because
171 // the extension, not the user, removed the permissions. This allows the 171 // the extension, not the user, removed the permissions. This allows the
172 // extension to add them again without prompting the user. 172 // extension to add them again without prompting the user.
173 extension_service_->UpdateActivePermissions(extension, total.get()); 173 extension_service_->UpdateActivePermissions(extension, total.get());
174 174
175 NotifyPermissionsUpdated(REMOVED, extension, removed.get()); 175 NotifyPermissionsUpdated(REMOVED, extension, removed.get());
176 } 176 }
177 177
178 void ExtensionPermissionsManager::DispatchEvent( 178 void ExtensionPermissionsUpdater::DispatchEvent(
179 const std::string& extension_id, 179 const std::string& extension_id,
180 const char* event_name, 180 const char* event_name,
181 const ExtensionPermissionSet* changed_permissions) { 181 const ExtensionPermissionSet* changed_permissions) {
182 Profile* profile = extension_service_->profile(); 182 Profile* profile = extension_service_->profile();
183 if (profile && profile->GetExtensionEventRouter()) { 183 if (profile && profile->GetExtensionEventRouter()) {
184 ListValue value; 184 ListValue value;
185 value.Append(PackPermissionsToValue(changed_permissions)); 185 value.Append(PackPermissionsToValue(changed_permissions));
186 std::string json_value; 186 std::string json_value;
187 base::JSONWriter::Write(&value, false, &json_value); 187 base::JSONWriter::Write(&value, false, &json_value);
188 profile->GetExtensionEventRouter()->DispatchEventToExtension( 188 profile->GetExtensionEventRouter()->DispatchEventToExtension(
189 extension_id, event_name, json_value, profile, GURL()); 189 extension_id, event_name, json_value, profile, GURL());
190 } 190 }
191 } 191 }
192 192
193 void ExtensionPermissionsManager::NotifyPermissionsUpdated( 193 void ExtensionPermissionsUpdater::NotifyPermissionsUpdated(
194 EventType event_type, 194 EventType event_type,
195 const Extension* extension, 195 const Extension* extension,
196 const ExtensionPermissionSet* changed) { 196 const ExtensionPermissionSet* changed) {
197 if (!changed || changed->IsEmpty()) 197 if (!changed || changed->IsEmpty())
198 return; 198 return;
199 199
200 UpdatedExtensionPermissionsInfo::Reason reason; 200 UpdatedExtensionPermissionsInfo::Reason reason;
201 const char* event_name = NULL; 201 const char* event_name = NULL;
202 202
203 if (event_type == REMOVED) { 203 if (event_type == REMOVED) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args)); 263 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
264 if (!args) 264 if (!args)
265 return false; 265 return false;
266 266
267 scoped_refptr<ExtensionPermissionSet> permissions; 267 scoped_refptr<ExtensionPermissionSet> permissions;
268 if (!UnpackPermissionsFromValue(args, &permissions, &bad_message_, &error_)) 268 if (!UnpackPermissionsFromValue(args, &permissions, &bad_message_, &error_))
269 return false; 269 return false;
270 CHECK(permissions.get()); 270 CHECK(permissions.get());
271 271
272 const Extension* extension = GetExtension(); 272 const Extension* extension = GetExtension();
273 ExtensionPermissionsManager* perms_manager =
274 profile()->GetExtensionService()->permissions_manager();
275 ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); 273 ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance();
276 274
277 // Make sure they're only trying to remove permissions supported by this API. 275 // Make sure they're only trying to remove permissions supported by this API.
278 ExtensionAPIPermissionSet apis = permissions->apis(); 276 ExtensionAPIPermissionSet apis = permissions->apis();
279 for (ExtensionAPIPermissionSet::const_iterator i = apis.begin(); 277 for (ExtensionAPIPermissionSet::const_iterator i = apis.begin();
280 i != apis.end(); ++i) { 278 i != apis.end(); ++i) {
281 const ExtensionAPIPermission* api = info->GetByID(*i); 279 const ExtensionAPIPermission* api = info->GetByID(*i);
282 if (!api->supports_optional()) { 280 if (!api->supports_optional()) {
283 error_ = ExtensionErrorUtils::FormatErrorMessage( 281 error_ = ExtensionErrorUtils::FormatErrorMessage(
284 kNotWhitelistedError, api->name()); 282 kNotWhitelistedError, api->name());
285 return false; 283 return false;
286 } 284 }
287 } 285 }
288 286
289 // Make sure we don't remove any required pemissions. 287 // Make sure we don't remove any required pemissions.
290 const ExtensionPermissionSet* required = extension->required_permission_set(); 288 const ExtensionPermissionSet* required = extension->required_permission_set();
291 scoped_refptr<ExtensionPermissionSet> intersection( 289 scoped_refptr<ExtensionPermissionSet> intersection(
292 ExtensionPermissionSet::CreateIntersection(permissions.get(), required)); 290 ExtensionPermissionSet::CreateIntersection(permissions.get(), required));
293 if (!intersection->IsEmpty()) { 291 if (!intersection->IsEmpty()) {
294 error_ = kCantRemoveRequiredPermissionsError; 292 error_ = kCantRemoveRequiredPermissionsError;
295 result_.reset(Value::CreateBooleanValue(false)); 293 result_.reset(Value::CreateBooleanValue(false));
296 return false; 294 return false;
297 } 295 }
298 296
299 perms_manager->RemovePermissions(extension, permissions.get()); 297 ExtensionPermissionsUpdater perms_updater(profile()->GetExtensionService());
298 perms_updater.RemovePermissions(extension, permissions.get());
300 result_.reset(Value::CreateBooleanValue(true)); 299 result_.reset(Value::CreateBooleanValue(true));
301 return true; 300 return true;
302 } 301 }
303 302
304 // static 303 // static
305 void RequestPermissionsFunction::SetAutoConfirmForTests(bool should_proceed) { 304 void RequestPermissionsFunction::SetAutoConfirmForTests(bool should_proceed) {
306 auto_confirm_for_tests = should_proceed ? PROCEED : ABORT; 305 auto_confirm_for_tests = should_proceed ? PROCEED : ABORT;
307 } 306 }
308 307
309 // static 308 // static
(...skipping 14 matching lines...) Expand all
324 DictionaryValue* args = NULL; 323 DictionaryValue* args = NULL;
325 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args)); 324 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
326 if (!args) 325 if (!args)
327 return false; 326 return false;
328 327
329 if (!UnpackPermissionsFromValue( 328 if (!UnpackPermissionsFromValue(
330 args, &requested_permissions_, &bad_message_, &error_)) 329 args, &requested_permissions_, &bad_message_, &error_))
331 return false; 330 return false;
332 CHECK(requested_permissions_.get()); 331 CHECK(requested_permissions_.get());
333 332
334 extension_ = GetExtension();
335 ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); 333 ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance();
336 ExtensionPermissionsManager* perms_manager =
337 profile()->GetExtensionService()->permissions_manager();
338 ExtensionPrefs* prefs = profile()->GetExtensionService()->extension_prefs(); 334 ExtensionPrefs* prefs = profile()->GetExtensionService()->extension_prefs();
339 335
340 // Make sure they're only requesting permissions supported by this API. 336 // Make sure they're only requesting permissions supported by this API.
341 ExtensionAPIPermissionSet apis = requested_permissions_->apis(); 337 ExtensionAPIPermissionSet apis = requested_permissions_->apis();
342 for (ExtensionAPIPermissionSet::const_iterator i = apis.begin(); 338 for (ExtensionAPIPermissionSet::const_iterator i = apis.begin();
343 i != apis.end(); ++i) { 339 i != apis.end(); ++i) {
344 const ExtensionAPIPermission* api = info->GetByID(*i); 340 const ExtensionAPIPermission* api = info->GetByID(*i);
345 if (!api->supports_optional()) { 341 if (!api->supports_optional()) {
346 error_ = ExtensionErrorUtils::FormatErrorMessage( 342 error_ = ExtensionErrorUtils::FormatErrorMessage(
347 kNotWhitelistedError, api->name()); 343 kNotWhitelistedError, api->name());
348 return false; 344 return false;
349 } 345 }
350 } 346 }
351 347
352 // The requested permissions must be defined as optional in the manifest. 348 // The requested permissions must be defined as optional in the manifest.
353 if (!extension_->optional_permission_set()->Contains( 349 if (!GetExtension()->optional_permission_set()->Contains(
354 *requested_permissions_)) { 350 *requested_permissions_)) {
355 error_ = kNotInOptionalPermissionsError; 351 error_ = kNotInOptionalPermissionsError;
356 result_.reset(Value::CreateBooleanValue(false)); 352 result_.reset(Value::CreateBooleanValue(false));
357 return false; 353 return false;
358 } 354 }
359 355
360 // We don't need to prompt the user if the requested permissions are a subset 356 // We don't need to prompt the user if the requested permissions are a subset
361 // of the granted permissions set. 357 // of the granted permissions set.
362 const ExtensionPermissionSet* granted = 358 const ExtensionPermissionSet* granted =
363 prefs->GetGrantedPermissions(extension_->id()); 359 prefs->GetGrantedPermissions(GetExtension()->id());
364 if (granted && granted->Contains(*requested_permissions_)) { 360 if (granted && granted->Contains(*requested_permissions_)) {
365 perms_manager->AddPermissions(extension_, requested_permissions_.get()); 361 ExtensionPermissionsUpdater perms_updater(profile()->GetExtensionService());
362 perms_updater.AddPermissions(GetExtension(), requested_permissions_.get());
366 result_.reset(Value::CreateBooleanValue(true)); 363 result_.reset(Value::CreateBooleanValue(true));
367 SendResponse(true); 364 SendResponse(true);
368 return true; 365 return true;
369 } 366 }
370 367
371 // Filter out the granted permissions so we only prompt for new ones. 368 // Filter out the granted permissions so we only prompt for new ones.
372 requested_permissions_ = ExtensionPermissionSet::CreateDifference( 369 requested_permissions_ = ExtensionPermissionSet::CreateDifference(
373 requested_permissions_.get(), granted); 370 requested_permissions_.get(), granted);
374 371
375 // Balanced with Release() in InstallUIProceed() and InstallUIAbort(). 372 AddRef(); // Balanced in InstallUIProceed() / InstallUIAbort().
376 AddRef();
377 373
378 // We don't need to show the prompt if there are no new warnings, or if 374 // We don't need to show the prompt if there are no new warnings, or if
379 // we're skipping the confirmation UI. All extension types but INTERNAL 375 // we're skipping the confirmation UI. All extension types but INTERNAL
380 // are allowed to silently increase their permission level. 376 // are allowed to silently increase their permission level.
381 if (auto_confirm_for_tests == PROCEED || 377 if (auto_confirm_for_tests == PROCEED ||
382 requested_permissions_->GetWarningMessages().size() == 0) { 378 requested_permissions_->GetWarningMessages().size() == 0) {
383 InstallUIProceed(); 379 InstallUIProceed();
384 } else if (auto_confirm_for_tests == ABORT) { 380 } else if (auto_confirm_for_tests == ABORT) {
385 // Pretend the user clicked cancel. 381 // Pretend the user clicked cancel.
386 InstallUIAbort(true); 382 InstallUIAbort(true);
387 } else { 383 } else {
388 CHECK_EQ(DO_NOT_SKIP, auto_confirm_for_tests); 384 CHECK_EQ(DO_NOT_SKIP, auto_confirm_for_tests);
389 install_ui_.reset(new ExtensionInstallUI(profile())); 385 install_ui_.reset(new ExtensionInstallUI(profile()));
390 install_ui_->ConfirmPermissions( 386 install_ui_->ConfirmPermissions(
391 this, extension_, requested_permissions_.get()); 387 this, GetExtension(), requested_permissions_.get());
392 } 388 }
393 389
394 return true; 390 return true;
395 } 391 }
396 392
397 void RequestPermissionsFunction::InstallUIProceed() { 393 void RequestPermissionsFunction::InstallUIProceed() {
398 ExtensionPermissionsManager* perms_manager = 394 ExtensionPermissionsUpdater perms_updater(profile()->GetExtensionService());
399 profile()->GetExtensionService()->permissions_manager(); 395 perms_updater.AddPermissions(GetExtension(), requested_permissions_.get());
Aaron Boodman 2011/11/14 19:26:05 I can't remember - if an extension is unloaded, do
jstritar 2011/12/12 22:28:03 The ExtensionFunction has a scoped_refptr to the E
400 396
401 install_ui_.reset();
402 result_.reset(Value::CreateBooleanValue(true)); 397 result_.reset(Value::CreateBooleanValue(true));
403 perms_manager->AddPermissions(extension_, requested_permissions_.get());
404
405 SendResponse(true); 398 SendResponse(true);
406 399
407 Release(); 400 Release(); // Balanced in RunImpl().
408 } 401 }
409 402
410 void RequestPermissionsFunction::InstallUIAbort(bool user_initiated) { 403 void RequestPermissionsFunction::InstallUIAbort(bool user_initiated) {
411 install_ui_.reset();
412 result_.reset(Value::CreateBooleanValue(false)); 404 result_.reset(Value::CreateBooleanValue(false));
413 requested_permissions_ = NULL; 405 SendResponse(true);
414 406
415 SendResponse(true); 407 Release(); // Balanced in RunImpl().
416 Release();
417 } 408 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698