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

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: . 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 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 544 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
545 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 545 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
546 profile_(profile), 546 profile_(profile),
547 extension_prefs_(extension_prefs), 547 extension_prefs_(extension_prefs),
548 pending_extension_manager_(*ALLOW_THIS_IN_INITIALIZER_LIST(this)), 548 pending_extension_manager_(*ALLOW_THIS_IN_INITIALIZER_LIST(this)),
549 install_directory_(install_directory), 549 install_directory_(install_directory),
550 extensions_enabled_(extensions_enabled), 550 extensions_enabled_(extensions_enabled),
551 show_extensions_prompts_(true), 551 show_extensions_prompts_(true),
552 ready_(false), 552 ready_(false),
553 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 553 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
554 permissions_manager_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
554 apps_promo_(profile->GetPrefs()), 555 apps_promo_(profile->GetPrefs()),
555 event_routers_initialized_(false) { 556 event_routers_initialized_(false) {
556 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 557 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
557 558
558 // Figure out if extension installation should be enabled. 559 // Figure out if extension installation should be enabled.
559 if (command_line->HasSwitch(switches::kDisableExtensions)) { 560 if (command_line->HasSwitch(switches::kDisableExtensions)) {
560 extensions_enabled_ = false; 561 extensions_enabled_ = false;
561 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { 562 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) {
562 extensions_enabled_ = false; 563 extensions_enabled_ = false;
563 } 564 }
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::DISABLE); 977 NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::DISABLE);
977 } 978 }
978 979
979 void ExtensionService::GrantPermissions(const Extension* extension) { 980 void ExtensionService::GrantPermissions(const Extension* extension) {
980 CHECK(extension); 981 CHECK(extension);
981 982
982 // We only maintain the granted permissions prefs for INTERNAL extensions. 983 // We only maintain the granted permissions prefs for INTERNAL extensions.
983 CHECK_EQ(Extension::INTERNAL, extension->location()); 984 CHECK_EQ(Extension::INTERNAL, extension->location());
984 985
985 extension_prefs_->AddGrantedPermissions(extension->id(), 986 extension_prefs_->AddGrantedPermissions(extension->id(),
986 extension->permission_set()); 987 extension->GetActivePermissions());
987 } 988 }
988 989
989 void ExtensionService::GrantPermissionsAndEnableExtension( 990 void ExtensionService::GrantPermissionsAndEnableExtension(
990 const Extension* extension) { 991 const Extension* extension) {
991 CHECK(extension); 992 CHECK(extension);
992 RecordPermissionMessagesHistogram( 993 RecordPermissionMessagesHistogram(
993 extension, "Extensions.Permissions_ReEnable"); 994 extension, "Extensions.Permissions_ReEnable");
994 GrantPermissions(extension); 995 GrantPermissions(extension);
995 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); 996 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false);
996 EnableExtension(extension->id()); 997 EnableExtension(extension->id());
997 } 998 }
998 999
1000 void ExtensionService::UpdateActivePermissions(
1001 const Extension* extension,
1002 const ExtensionPermissionSet* permissions) {
1003 extension_prefs()->SetActivePermissions(extension->id(), permissions);
1004 extension->SetActivePermissions(permissions);
1005 }
1006
999 void ExtensionService::LoadExtension(const FilePath& extension_path) { 1007 void ExtensionService::LoadExtension(const FilePath& extension_path) {
1000 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 1008 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
1001 NewRunnableMethod(backend_.get(), 1009 NewRunnableMethod(backend_.get(),
1002 &ExtensionServiceBackend::LoadSingleExtension, 1010 &ExtensionServiceBackend::LoadSingleExtension,
1003 extension_path, true)); 1011 extension_path, true));
1004 } 1012 }
1005 1013
1006 void ExtensionService::LoadExtensionFromCommandLine( 1014 void ExtensionService::LoadExtensionFromCommandLine(
1007 const FilePath& extension_path) { 1015 const FilePath& extension_path) {
1008 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 1016 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1299 Source<Profile>(profile_), 1307 Source<Profile>(profile_),
1300 Details<const Extension>(extension)); 1308 Details<const Extension>(extension));
1301 1309
1302 // Tell renderers about the new extension. 1310 // Tell renderers about the new extension.
1303 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); 1311 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator());
1304 !i.IsAtEnd(); i.Advance()) { 1312 !i.IsAtEnd(); i.Advance()) {
1305 RenderProcessHost* host = i.GetCurrentValue(); 1313 RenderProcessHost* host = i.GetCurrentValue();
1306 if (host->profile()->GetOriginalProfile() == 1314 if (host->profile()->GetOriginalProfile() ==
1307 profile_->GetOriginalProfile()) { 1315 profile_->GetOriginalProfile()) {
1308 host->Send( 1316 host->Send(
1309 new ExtensionMsg_Loaded(ExtensionMsg_Loaded_Params(extension))); 1317 new ExtensionMsg_Loaded(ExtensionMsg_Loaded_Params(
1318 extension, extension->GetActivePermissions())));
1310 } 1319 }
1311 } 1320 }
1312 1321
1313 // Tell a random-ass collection of other subsystems about the new extension. 1322 // Tell a random-ass collection of other subsystems about the new extension.
1314 // TODO(aa): What should we do with all this goop? Can it move into the 1323 // TODO(aa): What should we do with all this goop? Can it move into the
1315 // relevant objects via EXTENSION_LOADED? 1324 // relevant objects via EXTENSION_LOADED?
1316 1325
1317 profile_->GetExtensionSpecialStoragePolicy()-> 1326 profile_->GetExtensionSpecialStoragePolicy()->
1318 GrantRightsForExtension(extension); 1327 GrantRightsForExtension(extension);
1319 1328
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
1907 1916
1908 // If a terminated extension is loaded, remove it from the terminated list. 1917 // If a terminated extension is loaded, remove it from the terminated list.
1909 UntrackTerminatedExtension(extension->id()); 1918 UntrackTerminatedExtension(extension->id());
1910 1919
1911 // If the extension was disabled for a reload, then enable it. 1920 // If the extension was disabled for a reload, then enable it.
1912 if (disabled_extension_paths_.erase(extension->id()) > 0) 1921 if (disabled_extension_paths_.erase(extension->id()) > 0)
1913 EnableExtension(extension->id()); 1922 EnableExtension(extension->id());
1914 1923
1915 // Check if the extension's privileges have changed and disable the 1924 // Check if the extension's privileges have changed and disable the
1916 // extension if necessary. 1925 // extension if necessary.
1917 DisableIfPrivilegeIncrease(extension); 1926 InitializePermissions(extension);
1918 1927
1919 bool disabled = Extension::UserMayDisable(extension->location()) && 1928 bool disabled = Extension::UserMayDisable(extension->location()) &&
1920 extension_prefs_->GetExtensionState(extension->id()) == 1929 extension_prefs_->GetExtensionState(extension->id()) ==
1921 Extension::DISABLED; 1930 Extension::DISABLED;
1922 if (disabled) { 1931 if (disabled) {
1923 disabled_extensions_.push_back(scoped_extension); 1932 disabled_extensions_.push_back(scoped_extension);
1924 // TODO(aa): This seems dodgy. It seems that AddExtension() could get called 1933 // TODO(aa): This seems dodgy. It seems that AddExtension() could get called
1925 // with a disabled extension for other reasons other than that an update was 1934 // with a disabled extension for other reasons other than that an update was
1926 // disabled. 1935 // disabled.
1927 NotificationService::current()->Notify( 1936 NotificationService::current()->Notify(
1928 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, 1937 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED,
1929 Source<Profile>(profile_), 1938 Source<Profile>(profile_),
1930 Details<const Extension>(extension)); 1939 Details<const Extension>(extension));
1931 return; 1940 return;
1932 } 1941 }
1933 1942
1934 extensions_.push_back(scoped_extension); 1943 extensions_.push_back(scoped_extension);
1935 NotifyExtensionLoaded(extension); 1944 NotifyExtensionLoaded(extension);
1936 } 1945 }
1937 1946
1938 void ExtensionService::DisableIfPrivilegeIncrease(const Extension* extension) { 1947 void ExtensionService::InitializePermissions(const Extension* extension) {
1948 // If the extension has used the optional permissions API, it will have a
1949 // custom set of active permissions defined in the extension prefs. Here,
1950 // we update the extension's active permissions based on the prefs.
1951 scoped_ptr<ExtensionPermissionSet> active_permissions(
1952 extension_prefs()->GetActivePermissions(extension->id()));
1953
1954 if (active_permissions.get()) {
1955 // We restrict the active permissions to be within the bounds defined in the
1956 // extension's manifest.
1957 // a) active permissions must be a subset of optional + default permissions
1958 // b) active permissions must contains all default permissions
1959 scoped_ptr<ExtensionPermissionSet> total_permissions(
1960 ExtensionPermissionSet::CreateUnion(
1961 extension->required_permission_set(),
1962 extension->optional_permission_set()));
1963
1964 // Make sure the active permissions contain no more than optional + default.
1965 scoped_ptr<ExtensionPermissionSet> adjusted_active(
1966 ExtensionPermissionSet::CreateIntersection(
1967 total_permissions.get(), active_permissions.get()));
1968
1969 // Make sure the active permissions contain the default permissions.
1970 adjusted_active.reset(
1971 ExtensionPermissionSet::CreateUnion(
1972 extension->required_permission_set(), adjusted_active.get()));
1973
1974 UpdateActivePermissions(extension, adjusted_active.release());
1975 }
1976
1939 // We keep track of all permissions the user has granted each extension. 1977 // We keep track of all permissions the user has granted each extension.
1940 // This allows extensions to gracefully support backwards compatibility 1978 // This allows extensions to gracefully support backwards compatibility
1941 // by including unknown permissions in their manifests. When the user 1979 // by including unknown permissions in their manifests. When the user
1942 // installs the extension, only the recognized permissions are recorded. 1980 // installs the extension, only the recognized permissions are recorded.
1943 // When the unknown permissions become recognized (e.g., through browser 1981 // When the unknown permissions become recognized (e.g., through browser
1944 // upgrade), we can prompt the user to accept these new permissions. 1982 // upgrade), we can prompt the user to accept these new permissions.
1945 // Extensions can also silently upgrade to less permissions, and then 1983 // Extensions can also silently upgrade to less permissions, and then
1946 // silently upgrade to a version that adds these permissions back. 1984 // silently upgrade to a version that adds these permissions back.
1947 // 1985 //
1948 // For example, pretend that Chrome 10 includes a permission "omnibox" 1986 // For example, pretend that Chrome 10 includes a permission "omnibox"
(...skipping 20 matching lines...) Expand all
1969 // hasn't been initialized yet. 2007 // hasn't been initialized yet.
1970 scoped_ptr<ExtensionPermissionSet> granted_permissions( 2008 scoped_ptr<ExtensionPermissionSet> granted_permissions(
1971 extension_prefs_->GetGrantedPermissions(extension->id())); 2009 extension_prefs_->GetGrantedPermissions(extension->id()));
1972 CHECK(granted_permissions.get()); 2010 CHECK(granted_permissions.get());
1973 2011
1974 // Here, we check if an extension's privileges have increased in a manner 2012 // Here, we check if an extension's privileges have increased in a manner
1975 // that requires the user's approval. This could occur because the browser 2013 // that requires the user's approval. This could occur because the browser
1976 // upgraded and recognized additional privileges, or an extension upgrades 2014 // upgraded and recognized additional privileges, or an extension upgrades
1977 // to a version that requires additional privileges. 2015 // to a version that requires additional privileges.
1978 is_privilege_increase = 2016 is_privilege_increase =
1979 granted_permissions->HasLessPrivilegesThan(extension->permission_set()); 2017 granted_permissions->HasLessPrivilegesThan(
2018 extension->GetActivePermissions());
1980 } 2019 }
1981 2020
1982 if (is_extension_upgrade) { 2021 if (is_extension_upgrade) {
1983 // Other than for unpacked extensions, CrxInstaller should have guaranteed 2022 // Other than for unpacked extensions, CrxInstaller should have guaranteed
1984 // that we aren't downgrading. 2023 // that we aren't downgrading.
1985 if (extension->location() != Extension::LOAD) 2024 if (extension->location() != Extension::LOAD)
1986 CHECK(extension->version()->CompareTo(*(old->version())) >= 0); 2025 CHECK(extension->version()->CompareTo(*(old->version())) >= 0);
1987 2026
1988 // Extensions get upgraded if the privileges are allowed to increase or 2027 // Extensions get upgraded if the privileges are allowed to increase or
1989 // the privileges haven't increased. 2028 // the privileges haven't increased.
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
2321 process->Send(new ExtensionMsg_SetFunctionNames(function_names)); 2360 process->Send(new ExtensionMsg_SetFunctionNames(function_names));
2322 2361
2323 // Scripting whitelist. This is modified by tests and must be communicated 2362 // Scripting whitelist. This is modified by tests and must be communicated
2324 // to renderers. 2363 // to renderers.
2325 process->Send(new ExtensionMsg_SetScriptingWhitelist( 2364 process->Send(new ExtensionMsg_SetScriptingWhitelist(
2326 *Extension::GetScriptingWhitelist())); 2365 *Extension::GetScriptingWhitelist()));
2327 2366
2328 // Loaded extensions. 2367 // Loaded extensions.
2329 for (size_t i = 0; i < extensions_.size(); ++i) { 2368 for (size_t i = 0; i < extensions_.size(); ++i) {
2330 process->Send(new ExtensionMsg_Loaded( 2369 process->Send(new ExtensionMsg_Loaded(
2331 ExtensionMsg_Loaded_Params(extensions_[i]))); 2370 ExtensionMsg_Loaded_Params(
2371 extensions_[i], extensions_[i]->GetActivePermissions())));
2332 } 2372 }
2333 break; 2373 break;
2334 } 2374 }
2335 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { 2375 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: {
2336 RenderProcessHost* process = Source<RenderProcessHost>(source).ptr(); 2376 RenderProcessHost* process = Source<RenderProcessHost>(source).ptr();
2337 installed_app_hosts_.erase(process->id()); 2377 installed_app_hosts_.erase(process->id());
2338 break; 2378 break;
2339 } 2379 }
2340 case chrome::NOTIFICATION_PREF_CHANGED: { 2380 case chrome::NOTIFICATION_PREF_CHANGED: {
2341 std::string* pref_name = Details<std::string>(details).ptr(); 2381 std::string* pref_name = Details<std::string>(details).ptr();
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
2469 2509
2470 ExtensionService::NaClModuleInfoList::iterator 2510 ExtensionService::NaClModuleInfoList::iterator
2471 ExtensionService::FindNaClModule(const GURL& url) { 2511 ExtensionService::FindNaClModule(const GURL& url) {
2472 for (NaClModuleInfoList::iterator iter = nacl_module_list_.begin(); 2512 for (NaClModuleInfoList::iterator iter = nacl_module_list_.begin();
2473 iter != nacl_module_list_.end(); ++iter) { 2513 iter != nacl_module_list_.end(); ++iter) {
2474 if (iter->url == url) 2514 if (iter->url == url)
2475 return iter; 2515 return iter;
2476 } 2516 }
2477 return nacl_module_list_.end(); 2517 return nacl_module_list_.end();
2478 } 2518 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698