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

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

Issue 7432006: Add an experimental permissions API for extensions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: missed a scoped_refptr Created 9 years, 5 months 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_service.h" 5 #include "chrome/browser/extensions/extension_service.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 545 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
546 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 546 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
547 profile_(profile), 547 profile_(profile),
548 extension_prefs_(extension_prefs), 548 extension_prefs_(extension_prefs),
549 pending_extension_manager_(*ALLOW_THIS_IN_INITIALIZER_LIST(this)), 549 pending_extension_manager_(*ALLOW_THIS_IN_INITIALIZER_LIST(this)),
550 install_directory_(install_directory), 550 install_directory_(install_directory),
551 extensions_enabled_(extensions_enabled), 551 extensions_enabled_(extensions_enabled),
552 show_extensions_prompts_(true), 552 show_extensions_prompts_(true),
553 ready_(false), 553 ready_(false),
554 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 554 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
555 permissions_manager_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
555 apps_promo_(profile->GetPrefs()), 556 apps_promo_(profile->GetPrefs()),
556 event_routers_initialized_(false) { 557 event_routers_initialized_(false) {
557 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 558 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
558 559
559 // Figure out if extension installation should be enabled. 560 // Figure out if extension installation should be enabled.
560 if (command_line->HasSwitch(switches::kDisableExtensions)) { 561 if (command_line->HasSwitch(switches::kDisableExtensions)) {
561 extensions_enabled_ = false; 562 extensions_enabled_ = false;
562 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { 563 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) {
563 extensions_enabled_ = false; 564 extensions_enabled_ = false;
564 } 565 }
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
967 extension); 968 extension);
968 terminated_extensions_.erase(iter); 969 terminated_extensions_.erase(iter);
969 } 970 }
970 971
971 NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::DISABLE); 972 NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::DISABLE);
972 } 973 }
973 974
974 void ExtensionService::GrantPermissions(const Extension* extension) { 975 void ExtensionService::GrantPermissions(const Extension* extension) {
975 CHECK(extension); 976 CHECK(extension);
976 977
977 // We only maintain the granted permissions prefs for INTERNAL extensions. 978 // We only maintain the granted permissions prefs for INTERNAL extensions
978 CHECK_EQ(Extension::INTERNAL, extension->location()); 979 // because the other types don't prompt the user at install & upgrade time.
980 if (extension->location() != Extension::INTERNAL)
Mihai Parparita -not on Chrome 2011/07/23 22:54:53 Not seeing the Extension::CanSilentlyIncreasePermi
jstritar 2011/07/25 19:15:24 Woops. Done.
981 return;
979 982
980 extension_prefs_->AddGrantedPermissions(extension->id(), 983 extension_prefs_->AddGrantedPermissions(extension->id(),
981 extension->permission_set()); 984 extension->GetActivePermissions());
982 } 985 }
983 986
984 void ExtensionService::GrantPermissionsAndEnableExtension( 987 void ExtensionService::GrantPermissionsAndEnableExtension(
985 const Extension* extension) { 988 const Extension* extension) {
986 CHECK(extension); 989 CHECK(extension);
987 RecordPermissionMessagesHistogram( 990 RecordPermissionMessagesHistogram(
988 extension, "Extensions.Permissions_ReEnable"); 991 extension, "Extensions.Permissions_ReEnable");
989 GrantPermissions(extension); 992 GrantPermissions(extension);
990 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); 993 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false);
991 EnableExtension(extension->id()); 994 EnableExtension(extension->id());
992 } 995 }
993 996
997 void ExtensionService::UpdateActivePermissions(
998 const Extension* extension,
999 const ExtensionPermissionSet* permissions) {
1000 extension_prefs()->SetActivePermissions(extension->id(), permissions);
1001 extension->SetActivePermissions(permissions);
1002 }
1003
994 void ExtensionService::LoadExtension(const FilePath& extension_path) { 1004 void ExtensionService::LoadExtension(const FilePath& extension_path) {
995 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 1005 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
996 NewRunnableMethod(backend_.get(), 1006 NewRunnableMethod(backend_.get(),
997 &ExtensionServiceBackend::LoadSingleExtension, 1007 &ExtensionServiceBackend::LoadSingleExtension,
998 extension_path, true)); 1008 extension_path, true));
999 } 1009 }
1000 1010
1001 void ExtensionService::LoadExtensionFromCommandLine( 1011 void ExtensionService::LoadExtensionFromCommandLine(
1002 const FilePath& path_in) { 1012 const FilePath& path_in) {
1003 1013
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
1327 Source<Profile>(profile_), 1337 Source<Profile>(profile_),
1328 Details<const Extension>(extension)); 1338 Details<const Extension>(extension));
1329 1339
1330 // Tell renderers about the new extension. 1340 // Tell renderers about the new extension.
1331 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); 1341 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator());
1332 !i.IsAtEnd(); i.Advance()) { 1342 !i.IsAtEnd(); i.Advance()) {
1333 RenderProcessHost* host = i.GetCurrentValue(); 1343 RenderProcessHost* host = i.GetCurrentValue();
1334 if (host->profile()->GetOriginalProfile() == 1344 if (host->profile()->GetOriginalProfile() ==
1335 profile_->GetOriginalProfile()) { 1345 profile_->GetOriginalProfile()) {
1336 host->Send( 1346 host->Send(
1337 new ExtensionMsg_Loaded(ExtensionMsg_Loaded_Params(extension))); 1347 new ExtensionMsg_Loaded(ExtensionMsg_Loaded_Params(
1348 extension, extension->GetActivePermissions())));
1338 } 1349 }
1339 } 1350 }
1340 1351
1341 // Tell a random-ass collection of other subsystems about the new extension. 1352 // Tell a random-ass collection of other subsystems about the new extension.
1342 // TODO(aa): What should we do with all this goop? Can it move into the 1353 // TODO(aa): What should we do with all this goop? Can it move into the
1343 // relevant objects via EXTENSION_LOADED? 1354 // relevant objects via EXTENSION_LOADED?
1344 1355
1345 profile_->GetExtensionSpecialStoragePolicy()-> 1356 profile_->GetExtensionSpecialStoragePolicy()->
1346 GrantRightsForExtension(extension); 1357 GrantRightsForExtension(extension);
1347 1358
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
1935 1946
1936 // If a terminated extension is loaded, remove it from the terminated list. 1947 // If a terminated extension is loaded, remove it from the terminated list.
1937 UntrackTerminatedExtension(extension->id()); 1948 UntrackTerminatedExtension(extension->id());
1938 1949
1939 // If the extension was disabled for a reload, then enable it. 1950 // If the extension was disabled for a reload, then enable it.
1940 if (disabled_extension_paths_.erase(extension->id()) > 0) 1951 if (disabled_extension_paths_.erase(extension->id()) > 0)
1941 EnableExtension(extension->id()); 1952 EnableExtension(extension->id());
1942 1953
1943 // Check if the extension's privileges have changed and disable the 1954 // Check if the extension's privileges have changed and disable the
1944 // extension if necessary. 1955 // extension if necessary.
1945 DisableIfPrivilegeIncrease(extension); 1956 InitializePermissions(extension);
1946 1957
1947 bool disabled = Extension::UserMayDisable(extension->location()) && 1958 bool disabled = Extension::UserMayDisable(extension->location()) &&
1948 extension_prefs_->GetExtensionState(extension->id()) == 1959 extension_prefs_->GetExtensionState(extension->id()) ==
1949 Extension::DISABLED; 1960 Extension::DISABLED;
1950 if (disabled) { 1961 if (disabled) {
1951 disabled_extensions_.push_back(scoped_extension); 1962 disabled_extensions_.push_back(scoped_extension);
1952 // TODO(aa): This seems dodgy. It seems that AddExtension() could get called 1963 // TODO(aa): This seems dodgy. It seems that AddExtension() could get called
1953 // with a disabled extension for other reasons other than that an update was 1964 // with a disabled extension for other reasons other than that an update was
1954 // disabled. 1965 // disabled.
1955 NotificationService::current()->Notify( 1966 NotificationService::current()->Notify(
1956 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, 1967 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED,
1957 Source<Profile>(profile_), 1968 Source<Profile>(profile_),
1958 Details<const Extension>(extension)); 1969 Details<const Extension>(extension));
1959 return; 1970 return;
1960 } 1971 }
1961 1972
1962 extensions_.push_back(scoped_extension); 1973 extensions_.push_back(scoped_extension);
1963 NotifyExtensionLoaded(extension); 1974 NotifyExtensionLoaded(extension);
1964 } 1975 }
1965 1976
1966 void ExtensionService::DisableIfPrivilegeIncrease(const Extension* extension) { 1977 void ExtensionService::InitializePermissions(const Extension* extension) {
1978 // If the extension has used the optional permissions API, it will have a
1979 // custom set of active permissions defined in the extension prefs. Here,
1980 // we update the extension's active permissions based on the prefs.
1981 scoped_ptr<ExtensionPermissionSet> active_permissions(
1982 extension_prefs()->GetActivePermissions(extension->id()));
1983
1984 if (active_permissions.get()) {
1985 // We restrict the active permissions to be within the bounds defined in the
1986 // extension's manifest.
1987 // a) active permissions must be a subset of optional + default permissions
1988 // b) active permissions must contains all default permissions
1989 scoped_ptr<ExtensionPermissionSet> total_permissions(
1990 ExtensionPermissionSet::CreateUnion(
1991 extension->required_permission_set(),
1992 extension->optional_permission_set()));
1993
1994 // Make sure the active permissions contain no more than optional + default.
1995 scoped_ptr<ExtensionPermissionSet> adjusted_active(
1996 ExtensionPermissionSet::CreateIntersection(
1997 total_permissions.get(), active_permissions.get()));
1998
1999 // Make sure the active permissions contain the default permissions.
2000 adjusted_active.reset(
2001 ExtensionPermissionSet::CreateUnion(
2002 extension->required_permission_set(), adjusted_active.get()));
2003
2004 UpdateActivePermissions(extension, adjusted_active.release());
2005 }
2006
1967 // We keep track of all permissions the user has granted each extension. 2007 // We keep track of all permissions the user has granted each extension.
1968 // This allows extensions to gracefully support backwards compatibility 2008 // This allows extensions to gracefully support backwards compatibility
1969 // by including unknown permissions in their manifests. When the user 2009 // by including unknown permissions in their manifests. When the user
1970 // installs the extension, only the recognized permissions are recorded. 2010 // installs the extension, only the recognized permissions are recorded.
1971 // When the unknown permissions become recognized (e.g., through browser 2011 // When the unknown permissions become recognized (e.g., through browser
1972 // upgrade), we can prompt the user to accept these new permissions. 2012 // upgrade), we can prompt the user to accept these new permissions.
1973 // Extensions can also silently upgrade to less permissions, and then 2013 // Extensions can also silently upgrade to less permissions, and then
1974 // silently upgrade to a version that adds these permissions back. 2014 // silently upgrade to a version that adds these permissions back.
1975 // 2015 //
1976 // For example, pretend that Chrome 10 includes a permission "omnibox" 2016 // For example, pretend that Chrome 10 includes a permission "omnibox"
(...skipping 20 matching lines...) Expand all
1997 // hasn't been initialized yet. 2037 // hasn't been initialized yet.
1998 scoped_ptr<ExtensionPermissionSet> granted_permissions( 2038 scoped_ptr<ExtensionPermissionSet> granted_permissions(
1999 extension_prefs_->GetGrantedPermissions(extension->id())); 2039 extension_prefs_->GetGrantedPermissions(extension->id()));
2000 CHECK(granted_permissions.get()); 2040 CHECK(granted_permissions.get());
2001 2041
2002 // Here, we check if an extension's privileges have increased in a manner 2042 // Here, we check if an extension's privileges have increased in a manner
2003 // that requires the user's approval. This could occur because the browser 2043 // that requires the user's approval. This could occur because the browser
2004 // upgraded and recognized additional privileges, or an extension upgrades 2044 // upgraded and recognized additional privileges, or an extension upgrades
2005 // to a version that requires additional privileges. 2045 // to a version that requires additional privileges.
2006 is_privilege_increase = 2046 is_privilege_increase =
2007 granted_permissions->HasLessPrivilegesThan(extension->permission_set()); 2047 granted_permissions->HasLessPrivilegesThan(
2048 extension->GetActivePermissions());
2008 } 2049 }
2009 2050
2010 if (is_extension_upgrade) { 2051 if (is_extension_upgrade) {
2011 // Other than for unpacked extensions, CrxInstaller should have guaranteed 2052 // Other than for unpacked extensions, CrxInstaller should have guaranteed
2012 // that we aren't downgrading. 2053 // that we aren't downgrading.
2013 if (extension->location() != Extension::LOAD) 2054 if (extension->location() != Extension::LOAD)
2014 CHECK(extension->version()->CompareTo(*(old->version())) >= 0); 2055 CHECK(extension->version()->CompareTo(*(old->version())) >= 0);
2015 2056
2016 // Extensions get upgraded if the privileges are allowed to increase or 2057 // Extensions get upgraded if the privileges are allowed to increase or
2017 // the privileges haven't increased. 2058 // the privileges haven't increased.
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
2349 process->Send(new ExtensionMsg_SetFunctionNames(function_names)); 2390 process->Send(new ExtensionMsg_SetFunctionNames(function_names));
2350 2391
2351 // Scripting whitelist. This is modified by tests and must be communicated 2392 // Scripting whitelist. This is modified by tests and must be communicated
2352 // to renderers. 2393 // to renderers.
2353 process->Send(new ExtensionMsg_SetScriptingWhitelist( 2394 process->Send(new ExtensionMsg_SetScriptingWhitelist(
2354 *Extension::GetScriptingWhitelist())); 2395 *Extension::GetScriptingWhitelist()));
2355 2396
2356 // Loaded extensions. 2397 // Loaded extensions.
2357 for (size_t i = 0; i < extensions_.size(); ++i) { 2398 for (size_t i = 0; i < extensions_.size(); ++i) {
2358 process->Send(new ExtensionMsg_Loaded( 2399 process->Send(new ExtensionMsg_Loaded(
2359 ExtensionMsg_Loaded_Params(extensions_[i]))); 2400 ExtensionMsg_Loaded_Params(
2401 extensions_[i], extensions_[i]->GetActivePermissions())));
2360 } 2402 }
2361 break; 2403 break;
2362 } 2404 }
2363 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { 2405 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: {
2364 RenderProcessHost* process = Source<RenderProcessHost>(source).ptr(); 2406 RenderProcessHost* process = Source<RenderProcessHost>(source).ptr();
2365 installed_app_hosts_.erase(process->id()); 2407 installed_app_hosts_.erase(process->id());
2366 break; 2408 break;
2367 } 2409 }
2368 case chrome::NOTIFICATION_PREF_CHANGED: { 2410 case chrome::NOTIFICATION_PREF_CHANGED: {
2369 std::string* pref_name = Details<std::string>(details).ptr(); 2411 std::string* pref_name = Details<std::string>(details).ptr();
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
2497 2539
2498 ExtensionService::NaClModuleInfoList::iterator 2540 ExtensionService::NaClModuleInfoList::iterator
2499 ExtensionService::FindNaClModule(const GURL& url) { 2541 ExtensionService::FindNaClModule(const GURL& url) {
2500 for (NaClModuleInfoList::iterator iter = nacl_module_list_.begin(); 2542 for (NaClModuleInfoList::iterator iter = nacl_module_list_.begin();
2501 iter != nacl_module_list_.end(); ++iter) { 2543 iter != nacl_module_list_.end(); ++iter) {
2502 if (iter->url == url) 2544 if (iter->url == url)
2503 return iter; 2545 return iter;
2504 } 2546 }
2505 return nacl_module_list_.end(); 2547 return nacl_module_list_.end();
2506 } 2548 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698