diff options
author | jstritar@chromium.org <jstritar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-29 00:45:34 +0000 |
---|---|---|
committer | jstritar@chromium.org <jstritar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-29 00:45:34 +0000 |
commit | c09e2d208da071a7fdb7d53c7f0bdea4e0aa2fd8 (patch) | |
tree | 4c24a67380cbaf52b4dfa90e17189ccec01dbc66 /chrome/browser | |
parent | fdf6801902413c5662d071fba731e013e04f5181 (diff) | |
download | chromium_src-c09e2d208da071a7fdb7d53c7f0bdea4e0aa2fd8.zip chromium_src-c09e2d208da071a7fdb7d53c7f0bdea4e0aa2fd8.tar.gz chromium_src-c09e2d208da071a7fdb7d53c7f0bdea4e0aa2fd8.tar.bz2 |
Revert 67500 - Adds a section to the extension preferences to store the recognized permissions that the user has granted the extension.
Ignores unknown permissions when installing extensions.
Disables extension and prompts user to re-enable when unknown permissions become recognized (e.g., through browser upgrade).
Allows extensions to remove a permission in one version, then add them back in the next without prompting the user.
BUG=42742
TEST=ExtensionsServiceTest, ExtensionPrefsGrantedPermissions, ExtensionTest
Review URL: http://codereview.chromium.org/4687005
TBR=jstritar@chromium.org
Review URL: http://codereview.chromium.org/5286009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67501 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/automation/automation_provider.cc | 2 | ||||
-rw-r--r-- | chrome/browser/download/download_util.cc | 1 | ||||
-rw-r--r-- | chrome/browser/extensions/crx_installer.cc | 3 | ||||
-rw-r--r-- | chrome/browser/extensions/crx_installer.h | 13 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_disabled_infobar_delegate.cc | 4 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_prefs.cc | 152 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_prefs.h | 41 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_prefs_unittest.cc | 122 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.cc | 195 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.h | 19 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service_unittest.cc | 314 |
11 files changed, 117 insertions, 749 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index 231e875..bbfb3c5c 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -799,6 +799,7 @@ void AutomationProvider::InstallExtension(const FilePath& crx_path, scoped_refptr<CrxInstaller> installer( new CrxInstaller(service, NULL)); // silent install, no UI + installer->set_allow_privilege_increase(true); installer->InstallCrx(crx_path); } else { AutomationMsg_InstallExtension::WriteReplyParams( @@ -867,6 +868,7 @@ void AutomationProvider::InstallExtensionAndGetHandle( ExtensionInstallUI* client = (with_ui ? new ExtensionInstallUI(profile_) : NULL); scoped_refptr<CrxInstaller> installer(new CrxInstaller(service, client)); + installer->set_allow_privilege_increase(true); installer->InstallCrx(crx_path); } else { AutomationMsg_InstallExtensionAndGetHandle::WriteReplyParams( diff --git a/chrome/browser/download/download_util.cc b/chrome/browser/download/download_util.cc index 082845c..dd4a34c 100644 --- a/chrome/browser/download/download_util.cc +++ b/chrome/browser/download/download_util.cc @@ -252,6 +252,7 @@ void OpenChromeExtension(Profile* profile, download_item.url(), download_item.referrer_url()); installer->set_original_mime_type(download_item.original_mime_type()); installer->set_apps_require_extension_mime_type(true); + installer->set_allow_privilege_increase(true); installer->set_original_url(download_item.url()); installer->set_is_gallery_install(is_gallery_download); installer->InstallCrx(download_item.full_path()); diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index efe3ad1..3a9a3df 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc @@ -83,6 +83,7 @@ CrxInstaller::CrxInstaller(ExtensionsService* frontend, install_source_(Extension::INTERNAL), extensions_enabled_(frontend->extensions_enabled()), delete_source_(false), + allow_privilege_increase_(false), is_gallery_install_(false), create_app_shortcut_(false), frontend_(frontend), @@ -432,7 +433,7 @@ void CrxInstaller::ReportSuccessFromUIThread() { // Tell the frontend about the installation and hand off ownership of // extension_ to it. - frontend_->OnExtensionInstalled(extension_); + frontend_->OnExtensionInstalled(extension_, allow_privilege_increase_); extension_ = NULL; // We're done. We don't post any more tasks to ourselves so we are deleted diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h index c22a4a9..26bbbd8 100644 --- a/chrome/browser/extensions/crx_installer.h +++ b/chrome/browser/extensions/crx_installer.h @@ -96,6 +96,11 @@ class CrxInstaller bool delete_source() const { return delete_source_; } void set_delete_source(bool val) { delete_source_ = val; } + bool allow_privilege_increase() const { return allow_privilege_increase_; } + void set_allow_privilege_increase(bool val) { + allow_privilege_increase_ = val; + } + bool allow_silent_install() const { return allow_silent_install_; } void set_allow_silent_install(bool val) { allow_silent_install_ = val; } @@ -173,6 +178,14 @@ class CrxInstaller // to false. bool delete_source_; + // Whether privileges should be allowed to silently increaes from any + // previously installed version of the extension. This is used for things + // like external extensions, where extensions come with third-party software + // or are distributed by the network administrator. There is no UI shown + // for these extensions, so there shouldn't be UI for privilege increase, + // either. Defaults to false. + bool allow_privilege_increase_; + // Whether the install originated from the gallery. bool is_gallery_install_; diff --git a/chrome/browser/extensions/extension_disabled_infobar_delegate.cc b/chrome/browser/extensions/extension_disabled_infobar_delegate.cc index 354fea9..d66a448 100644 --- a/chrome/browser/extensions/extension_disabled_infobar_delegate.cc +++ b/chrome/browser/extensions/extension_disabled_infobar_delegate.cc @@ -36,7 +36,9 @@ class ExtensionDisabledDialogDelegate // Overridden from ExtensionInstallUI::Delegate: virtual void InstallUIProceed() { - service_->GrantPermissionsAndEnableExtension(extension_); + ExtensionPrefs* prefs = service_->extension_prefs(); + prefs->SetDidExtensionEscalatePermissions(extension_, false); + service_->EnableExtension(extension_->id()); Release(); } virtual void InstallUIAbort() { diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc index ec6ada0..09b7dd6 100644 --- a/chrome/browser/extensions/extension_prefs.cc +++ b/chrome/browser/extensions/extension_prefs.cc @@ -8,7 +8,6 @@ #include "base/string_number_conversions.h" #include "base/utf_string_conversions.h" #include "chrome/common/extensions/extension.h" -#include "chrome/common/extensions/url_pattern.h" #include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" @@ -83,14 +82,6 @@ const char kUpdateUrlData[] = "update_url_data"; // Whether the browser action is visible in the toolbar. const char kBrowserActionVisible[] = "browser_action_visible"; -// Preferences that hold which permissions the user has granted the extension. -// We explicitly keep track of these so that extensions can contain unknown -// permissions, for backwards compatibility reasons, and we can still prompt -// the user to accept them once recognized. -const char kPrefGrantedPermissionsAPI[] = "granted_permissions.api"; -const char kPrefGrantedPermissionsHost[] = "granted_permissions.host"; -const char kPrefGrantedPermissionsAll[] = "granted_permissions.full"; - } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -122,15 +113,6 @@ static void CleanupBadExtensionKeys(PrefService* prefs) { prefs->ScheduleSavePersistentPrefs(); } -static void ExtentToStringSet(const ExtensionExtent& host_extent, - std::set<std::string>* result) { - ExtensionExtent::PatternList patterns = host_extent.patterns(); - ExtensionExtent::PatternList::const_iterator i; - - for (i = patterns.begin(); i != patterns.end(); ++i) - result->insert(i->GetAsString()); -} - } // namespace ExtensionPrefs::ExtensionPrefs(PrefService* prefs, const FilePath& root_dir) @@ -236,17 +218,24 @@ DictionaryValue* ExtensionPrefs::CopyCurrentExtensions() { bool ExtensionPrefs::ReadBooleanFromPref( DictionaryValue* ext, const std::string& pref_key) { + if (!ext->HasKey(pref_key)) return false; bool bool_value = false; - if (!ext->GetBoolean(pref_key, &bool_value)) + if (!ext->GetBoolean(pref_key, &bool_value)) { + NOTREACHED() << "Failed to fetch " << pref_key << " flag."; + // In case we could not fetch the flag, we treat it as false. return false; - + } return bool_value; } bool ExtensionPrefs::ReadExtensionPrefBoolean( const std::string& extension_id, const std::string& pref_key) { - DictionaryValue* ext = GetExtensionPref(extension_id); - if (!ext) { + const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); + if (!extensions) + return false; + + DictionaryValue* ext = NULL; + if (!extensions->GetDictionary(extension_id, &ext)) { // No such extension yet. return false; } @@ -255,74 +244,29 @@ bool ExtensionPrefs::ReadExtensionPrefBoolean( bool ExtensionPrefs::ReadIntegerFromPref( DictionaryValue* ext, const std::string& pref_key, int* out_value) { - if (!ext->GetInteger(pref_key, out_value)) + if (!ext->HasKey(pref_key)) return false; + if (!ext->GetInteger(pref_key, out_value)) { + NOTREACHED() << "Failed to fetch " << pref_key << " flag."; + // In case we could not fetch the flag, we treat it as false. return false; - + } return out_value != NULL; } bool ExtensionPrefs::ReadExtensionPrefInteger( const std::string& extension_id, const std::string& pref_key, int* out_value) { - DictionaryValue* ext = GetExtensionPref(extension_id); - if (!ext) { + const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); + if (!extensions) + return false; + DictionaryValue* ext = NULL; + if (!extensions->GetDictionary(extension_id, &ext)) { // No such extension yet. return false; } return ReadIntegerFromPref(ext, pref_key, out_value); } -bool ExtensionPrefs::ReadExtensionPrefList( - const std::string& extension_id, const std::string& pref_key, - ListValue** out_value) { - DictionaryValue* ext = GetExtensionPref(extension_id); - if (!ext || !ext->GetList(pref_key, out_value)) - return false; - - return out_value != NULL; -} - -bool ExtensionPrefs::ReadExtensionPrefStringSet( - const std::string& extension_id, - const std::string& pref_key, - std::set<std::string>* result) { - ListValue* value = NULL; - if (!ReadExtensionPrefList(extension_id, pref_key, &value)) - return false; - - result->clear(); - - for (size_t i = 0; i < value->GetSize(); ++i) { - std::string item; - if (!value->GetString(i, &item)) - return false; - result->insert(item); - } - - return true; -} - -void ExtensionPrefs::AddToExtensionPrefStringSet( - const std::string& extension_id, - const std::string& pref_key, - const std::set<std::string>& added_value) { - std::set<std::string> old_value; - std::set<std::string> new_value; - ReadExtensionPrefStringSet(extension_id, pref_key, &old_value); - - std::set_union(old_value.begin(), old_value.end(), - added_value.begin(), added_value.end(), - std::inserter(new_value, new_value.end())); - - ListValue* value = new ListValue(); - for (std::set<std::string>::const_iterator iter = new_value.begin(); - iter != new_value.end(); ++iter) - value->Append(Value::CreateStringValue(*iter)); - - UpdateExtensionPref(extension_id, pref_key, value); - prefs_->ScheduleSavePersistentPrefs(); -} - void ExtensionPrefs::SavePrefsAndNotify() { prefs_->ScheduleSavePersistentPrefs(); prefs_->pref_notifier()->OnUserPreferenceSet(kExtensionsPref); @@ -467,60 +411,6 @@ void ExtensionPrefs::SetLastPingDayImpl(const Time& time, SavePrefsAndNotify(); } - -bool ExtensionPrefs::GetGrantedPermissions( - const std::string& extension_id, - bool* full_access, - std::set<std::string>* api_permissions, - ExtensionExtent* host_extent) { - CHECK(Extension::IdIsValid(extension_id)); - - DictionaryValue* ext = GetExtensionPref(extension_id); - if (!ext || !ext->GetBoolean(kPrefGrantedPermissionsAll, full_access)) - return false; - - ReadExtensionPrefStringSet( - extension_id, kPrefGrantedPermissionsAPI, api_permissions); - - std::set<std::string> host_permissions; - ReadExtensionPrefStringSet( - extension_id, kPrefGrantedPermissionsHost, &host_permissions); - - for (std::set<std::string>::iterator i = host_permissions.begin(); - i != host_permissions.end(); ++i) - host_extent->AddPattern(URLPattern( - Extension::kValidWebExtentSchemes | UserScript::kValidUserScriptSchemes, - *i)); - - return true; -} - -void ExtensionPrefs::AddGrantedPermissions( - const std::string& extension_id, - const bool full_access, - const std::set<std::string>& api_permissions, - const ExtensionExtent& host_extent) { - CHECK(Extension::IdIsValid(extension_id)); - - UpdateExtensionPref(extension_id, kPrefGrantedPermissionsAll, - Value::CreateBooleanValue(full_access)); - - if (!api_permissions.empty()) { - AddToExtensionPrefStringSet( - extension_id, kPrefGrantedPermissionsAPI, api_permissions); - } - - if (!host_extent.is_empty()) { - std::set<std::string> host_permissions; - ExtentToStringSet(host_extent, &host_permissions); - - AddToExtensionPrefStringSet( - extension_id, kPrefGrantedPermissionsHost, host_permissions); - } - - SavePrefsAndNotify(); -} - Time ExtensionPrefs::LastPingDay(const std::string& extension_id) const { DCHECK(Extension::IdIsValid(extension_id)); return LastPingDayImpl(GetExtensionPref(extension_id)); diff --git a/chrome/browser/extensions/extension_prefs.h b/chrome/browser/extensions/extension_prefs.h index 26e4327..0bcd9f9 100644 --- a/chrome/browser/extensions/extension_prefs.h +++ b/chrome/browser/extensions/extension_prefs.h @@ -123,27 +123,6 @@ class ExtensionPrefs { // the client's. void SetLastPingDay(const std::string& extension_id, const base::Time& time); - // Gets the permissions (|api_permissions|, |host_extent| and |full_access|) - // granted to the extension with |extension_id|. |full_access| will be true - // if the extension has all effective permissions (like from an NPAPI plugin). - // Returns false if the granted permissions haven't been initialized yet. - // TODO(jstritar): Refractor the permissions into a class that encapsulates - // all granted permissions, can be initialized from preferences or - // a manifest file, and can be compared to each other. - bool GetGrantedPermissions(const std::string& extension_id, - bool* full_access, - std::set<std::string>* api_permissions, - ExtensionExtent* host_extent); - - // Adds the specified |api_permissions|, |host_extent| and |full_access| - // to the granted permissions for extension with |extension_id|. - // |full_access| should be set to true if the extension effectively has all - // permissions (such as by having an NPAPI plugin). - void AddGrantedPermissions(const std::string& extension_id, - const bool full_access, - const std::set<std::string>& api_permissions, - const ExtensionExtent& host_extent); - // Similar to the 2 above, but for the extensions blacklist. base::Time BlacklistLastPingDay() const; void SetBlacklistLastPingDay(const base::Time& time); @@ -243,7 +222,7 @@ class ExtensionPrefs { void DeleteExtensionPrefs(const std::string& id); // Reads a boolean pref from |ext| with key |pref_key|. - // Return false if the value is false or |pref_key| does not exist. + // Return false if the value is false or kPrefBlacklist does not exist. bool ReadBooleanFromPref(DictionaryValue* ext, const std::string& pref_key); // Reads a boolean pref |pref_key| from extension with id |extension_id|. @@ -260,24 +239,6 @@ class ExtensionPrefs { const std::string& pref_key, int* out_value); - // Reads a list pref |pref_key| from extension with id | extension_id|. - bool ReadExtensionPrefList(const std::string& extension_id, - const std::string& pref_key, - ListValue** out_value); - - // Reads a list pref |pref_key| as a string set from the extension with - // id |extension_id|. - bool ReadExtensionPrefStringSet(const std::string& extension_id, - const std::string& pref_key, - std::set<std::string>* result); - - // Adds the |added_values| to the value of |pref_key| for the extension - // with id |extension_id| (the new value will be the union of the existing - // value and |added_values|). - void AddToExtensionPrefStringSet(const std::string& extension_id, - const std::string& pref_key, - const std::set<std::string>& added_values); - // Ensures and returns a mutable dictionary for extension |id|'s prefs. DictionaryValue* GetOrCreateExtensionPref(const std::string& id); diff --git a/chrome/browser/extensions/extension_prefs_unittest.cc b/chrome/browser/extensions/extension_prefs_unittest.cc index ec3a33d..4218790 100644 --- a/chrome/browser/extensions/extension_prefs_unittest.cc +++ b/chrome/browser/extensions/extension_prefs_unittest.cc @@ -19,28 +19,6 @@ using base::Time; using base::TimeDelta; -static void AddPattern(ExtensionExtent* extent, const std::string& pattern) { - int schemes = URLPattern::SCHEME_ALL; - extent->AddPattern(URLPattern(schemes, pattern)); -} - -static void AssertEqualExtents(ExtensionExtent* extent1, - ExtensionExtent* extent2) { - std::vector<URLPattern> patterns1 = extent1->patterns(); - std::vector<URLPattern> patterns2 = extent2->patterns(); - std::set<std::string> strings1; - EXPECT_EQ(patterns1.size(), patterns2.size()); - - for (size_t i = 0; i < patterns1.size(); ++i) - strings1.insert(patterns1.at(i).GetAsString()); - - std::set<std::string> strings2; - for (size_t i = 0; i < patterns2.size(); ++i) - strings2.insert(patterns2.at(i).GetAsString()); - - EXPECT_EQ(strings1, strings2); -} - // Base class for tests. class ExtensionPrefsTest : public testing::Test { public: @@ -167,106 +145,6 @@ class ExtensionPrefsEscalatePermissions : public ExtensionPrefsTest { }; TEST_F(ExtensionPrefsEscalatePermissions, EscalatePermissions) {} -// Tests the AddGrantedPermissions / GetGrantedPermissions functions. -class ExtensionPrefsGrantedPermissions : public ExtensionPrefsTest { - public: - virtual void Initialize() { - extension_id_ = prefs_.AddExtensionAndReturnId("test"); - - api_perm_set1_.insert("tabs"); - api_perm_set1_.insert("bookmarks"); - api_perm_set1_.insert("something_random"); - - api_perm_set2_.insert("history"); - api_perm_set2_.insert("unknown2"); - - AddPattern(&host_perm_set1_, "http://*.google.com/*"); - AddPattern(&host_perm_set1_, "http://example.com/*"); - - AddPattern(&host_perm_set2_, "https://*.google.com/*"); - // with duplicate: - AddPattern(&host_perm_set2_, "http://*.google.com/*"); - - std::set_union(api_perm_set1_.begin(), api_perm_set1_.end(), - api_perm_set2_.begin(), api_perm_set2_.end(), - std::inserter(api_permissions_, api_permissions_.end())); - - AddPattern(&host_permissions_, "http://*.google.com/*"); - AddPattern(&host_permissions_, "http://example.com/*"); - AddPattern(&host_permissions_, "https://*.google.com/*"); - - std::set<std::string> empty_set; - std::set<std::string> api_perms; - bool full_access = false; - ExtensionExtent host_perms; - ExtensionExtent empty_extent; - - // Make sure both granted api and host permissions start empty. - EXPECT_FALSE(prefs()->GetGrantedPermissions( - extension_id_, &full_access, &api_perms, &host_perms)); - - EXPECT_TRUE(api_perms.empty()); - EXPECT_TRUE(host_perms.is_empty()); - - // Add part of the api permissions. - prefs()->AddGrantedPermissions( - extension_id_, false, api_perm_set1_, empty_extent); - EXPECT_TRUE(prefs()->GetGrantedPermissions( - extension_id_, &full_access, &api_perms, &host_perms)); - EXPECT_EQ(api_perm_set1_, api_perms); - EXPECT_TRUE(host_perms.is_empty()); - EXPECT_FALSE(full_access); - host_perms.ClearPaths(); - api_perms.clear(); - - // Add part of the host permissions. - prefs()->AddGrantedPermissions( - extension_id_, false, empty_set, host_perm_set1_); - EXPECT_TRUE(prefs()->GetGrantedPermissions( - extension_id_, &full_access, &api_perms, &host_perms)); - EXPECT_FALSE(full_access); - EXPECT_EQ(api_perm_set1_, api_perms); - AssertEqualExtents(&host_perm_set1_, &host_perms); - host_perms.ClearPaths(); - api_perms.clear(); - - // Add the rest of both the api and host permissions. - prefs()->AddGrantedPermissions(extension_id_, - true, - api_perm_set2_, - host_perm_set2_); - - EXPECT_TRUE(prefs()->GetGrantedPermissions( - extension_id_, &full_access, &api_perms, &host_perms)); - EXPECT_TRUE(full_access); - EXPECT_EQ(api_permissions_, api_perms); - AssertEqualExtents(&host_permissions_, &host_perms); - } - - virtual void Verify() { - std::set<std::string> api_perms; - ExtensionExtent host_perms; - bool full_access; - - EXPECT_TRUE(prefs()->GetGrantedPermissions( - extension_id_, &full_access, &api_perms, &host_perms)); - EXPECT_EQ(api_permissions_, api_perms); - EXPECT_TRUE(full_access); - AssertEqualExtents(&host_permissions_, &host_perms); - } - - private: - std::string extension_id_; - std::set<std::string> api_perm_set1_; - std::set<std::string> api_perm_set2_; - ExtensionExtent host_perm_set1_; - ExtensionExtent host_perm_set2_; - - - std::set<std::string> api_permissions_; - ExtensionExtent host_permissions_; -}; -TEST_F(ExtensionPrefsGrantedPermissions, GrantedPermissions) {} // Tests the GetVersionString function. class ExtensionPrefsVersionString : public ExtensionPrefsTest { diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc index 8284def..a675f5b 100644 --- a/chrome/browser/extensions/extensions_service.cc +++ b/chrome/browser/extensions/extensions_service.cc @@ -347,9 +347,8 @@ void ExtensionsServiceBackend::LoadSingleExtension( // prefs. BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - NewRunnableMethod(frontend_, - &ExtensionsService::OnExtensionInstalled, - extension)); + NewRunnableMethod(frontend_, &ExtensionsService::OnExtensionInstalled, + extension, true)); } void ExtensionsServiceBackend::ReportExtensionLoadError( @@ -645,6 +644,7 @@ void ExtensionsService::InstallExtension(const FilePath& extension_path) { scoped_refptr<CrxInstaller> installer( new CrxInstaller(this, // frontend NULL)); // no client (silent install) + installer->set_allow_privilege_increase(true); installer->InstallCrx(extension_path); } @@ -943,27 +943,6 @@ void ExtensionsService::DisableExtension(const std::string& extension_id) { UpdateActiveExtensionsInCrashReporter(); } -void ExtensionsService::GrantPermissions(const Extension* extension) { - CHECK(extension); - - // We only maintain the granted permissions prefs for INTERNAL extensions. - CHECK(extension->location() == Extension::INTERNAL); - - ExtensionExtent effective_hosts = extension->GetEffectiveHostPermissions(); - extension_prefs_->AddGrantedPermissions(extension->id(), - extension->HasFullPermissions(), - extension->api_permissions(), - effective_hosts); -} - -void ExtensionsService::GrantPermissionsAndEnableExtension( - const Extension* extension) { - CHECK(extension); - GrantPermissions(extension); - extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); - EnableExtension(extension->id()); -} - void ExtensionsService::LoadExtension(const FilePath& extension_path) { BrowserThread::PostTask( BrowserThread::FILE, FROM_HERE, @@ -996,7 +975,7 @@ void ExtensionsService::LoadComponentExtensions() { return; } - OnExtensionLoaded(extension); + OnExtensionLoaded(extension, false); // Don't allow privilege increase. } } @@ -1141,6 +1120,7 @@ void ExtensionsService::LoadAllExtensions() { browser_action_count); } + void ExtensionsService::LoadInstalledExtension(const ExtensionInfo& info, bool write_to_prefs) { std::string error; @@ -1167,7 +1147,7 @@ void ExtensionsService::LoadInstalledExtension(const ExtensionInfo& info, if (write_to_prefs) extension_prefs_->UpdateManifest(extension); - OnExtensionLoaded(extension); + OnExtensionLoaded(extension, true); if (Extension::IsExternalLocation(info.extension_location)) { BrowserThread::PostTask( @@ -1543,7 +1523,8 @@ void ExtensionsService::OnLoadedInstalledExtensions() { NotificationService::NoDetails()); } -void ExtensionsService::OnExtensionLoaded(const Extension* extension) { +void ExtensionsService::OnExtensionLoaded(const Extension* extension, + bool allow_privilege_increase) { // Ensure extension is deleted unless we transfer ownership. scoped_refptr<const Extension> scoped_extension(extension); @@ -1554,29 +1535,63 @@ void ExtensionsService::OnExtensionLoaded(const Extension* extension) { if (disabled_extension_paths_.erase(extension->id()) > 0) EnableExtension(extension->id()); - // Check if the extension's privileges have changed and disable the extension - // if necessary. - DisableIfPrivilegeIncrease(extension); + // TODO(aa): Need to re-evaluate this branch. Does this still make sense now + // that extensions are enabled by default? + if (extensions_enabled() || + extension->is_theme() || + extension->location() == Extension::LOAD || + extension->location() == Extension::COMPONENT || + Extension::IsExternalLocation(extension->location())) { + const Extension* old = GetExtensionByIdInternal(extension->id(), + true, true); + if (old) { + // CrxInstaller should have guaranteed that we aren't downgrading. + CHECK(extension->version()->CompareTo(*(old->version())) >= 0); + + bool allow_silent_upgrade = + allow_privilege_increase || !Extension::IsPrivilegeIncrease( + old, extension); + + // Extensions get upgraded if silent upgrades are allowed, otherwise + // they get disabled. + if (allow_silent_upgrade) { + SetBeingUpgraded(old, true); + SetBeingUpgraded(extension, true); + } + + // To upgrade an extension in place, unload the old one and + // then load the new one. + UnloadExtension(old->id()); + old = NULL; - switch (extension_prefs_->GetExtensionState(extension->id())) { - case Extension::ENABLED: - extensions_.push_back(scoped_extension); + if (!allow_silent_upgrade) { + // Extension has changed permissions significantly. Disable it. We + // send a notification below. + extension_prefs_->SetExtensionState(extension, Extension::DISABLED); + extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); + } + } - NotifyExtensionLoaded(extension); + switch (extension_prefs_->GetExtensionState(extension->id())) { + case Extension::ENABLED: + extensions_.push_back(scoped_extension); - ExtensionDOMUI::RegisterChromeURLOverrides( - profile_, extension->GetChromeURLOverrides()); - break; - case Extension::DISABLED: - disabled_extensions_.push_back(scoped_extension); - NotificationService::current()->Notify( - NotificationType::EXTENSION_UPDATE_DISABLED, - Source<Profile>(profile_), - Details<const Extension>(extension)); - break; - default: - NOTREACHED(); - break; + NotifyExtensionLoaded(extension); + + ExtensionDOMUI::RegisterChromeURLOverrides(profile_, + extension->GetChromeURLOverrides()); + break; + case Extension::DISABLED: + disabled_extensions_.push_back(scoped_extension); + NotificationService::current()->Notify( + NotificationType::EXTENSION_UPDATE_DISABLED, + Source<Profile>(profile_), + Details<const Extension>(extension)); + break; + default: + NOTREACHED(); + break; + } } SetBeingUpgraded(extension, false); @@ -1594,86 +1609,6 @@ void ExtensionsService::OnExtensionLoaded(const Extension* extension) { } } -void ExtensionsService::DisableIfPrivilegeIncrease(const Extension* extension) { - // We keep track of all permissions the user has granted each extension. - // This allows extensions to gracefully support backwards compatibility - // by including unknown permissions in their manifests. When the user - // installs the extension, only the recognized permissions are recorded. - // When the unknown permissions become recognized (e.g., through browser - // upgrade), we can prompt the user to accept these new permissions. - // Extensions can also silently upgrade to less permissions, and then - // silently upgrade to a version that adds these permissions back. - // - // For example, pretend that Chrome 10 includes a permission "omnibox" - // for an API that adds suggestions to the omnibox. An extension can - // maintain backwards compatibility while still having "omnibox" in the - // manifest. If a user installs the extension on Chrome 9, the browser - // will record the permissions it recognized, not including "omnibox." - // When upgrading to Chrome 10, "omnibox" will be recognized and Chrome - // will disable the extension and prompt the user to approve the increase - // in privileges. The extension could then release a new version that - // removes the "omnibox" permission. When the user upgrades, Chrome will - // still remember that "omnibox" had been granted, so that if the - // extension once again includes "omnibox" in an upgrade, the extension - // can upgrade without requiring this user's approval. - const Extension* old = GetExtensionByIdInternal(extension->id(), - true, true); - bool granted_full_access; - std::set<std::string> granted_apis; - ExtensionExtent granted_extent; - - bool is_extension_upgrade = old != NULL; - bool is_privilege_increase = false; - - // We only record the granted permissions for INTERNAL extensions, since - // they can't silently increase privileges. - if (extension->location() == Extension::INTERNAL) { - // Add all the recognized permissions if the granted permissions list - // hasn't been initialized yet. - if (!extension_prefs_->GetGrantedPermissions(extension->id(), - &granted_full_access, - &granted_apis, - &granted_extent)) { - GrantPermissions(extension); - CHECK(extension_prefs_->GetGrantedPermissions(extension->id(), - &granted_full_access, - &granted_apis, - &granted_extent)); - } - - // Here, we check if an extension's privileges have increased in a manner - // that requires the user's approval. This could occur because the browser - // upgraded and recognized additional privileges, or an extension upgrades - // to a version that requires additional privileges. - is_privilege_increase = Extension::IsPrivilegeIncrease( - granted_full_access, granted_apis, granted_extent, extension); - } - - if (is_extension_upgrade) { - // CrxInstaller should have guaranteed that we aren't downgrading. - CHECK(extension->version()->CompareTo(*(old->version())) >= 0); - - // Extensions get upgraded if the privileges are allowed to increase or - // the privileges haven't increased. - if (!is_privilege_increase) { - SetBeingUpgraded(old, true); - SetBeingUpgraded(extension, true); - } - - // To upgrade an extension in place, unload the old one and - // then load the new one. - UnloadExtension(old->id()); - old = NULL; - } - - // Extension has changed permissions significantly. Disable it. A - // notification should be sent by the caller. - if (is_privilege_increase) { - extension_prefs_->SetExtensionState(extension, Extension::DISABLED); - extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); - } -} - void ExtensionsService::UpdateActiveExtensionsInCrashReporter() { std::set<std::string> extension_ids; for (size_t i = 0; i < extensions_.size(); ++i) { @@ -1685,7 +1620,8 @@ void ExtensionsService::UpdateActiveExtensionsInCrashReporter() { child_process_logging::SetActiveExtensions(extension_ids); } -void ExtensionsService::OnExtensionInstalled(const Extension* extension) { +void ExtensionsService::OnExtensionInstalled(const Extension* extension, + bool allow_privilege_increase) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); // Ensure extension is deleted unless we transfer ownership. @@ -1827,7 +1763,7 @@ void ExtensionsService::OnExtensionInstalled(const Extension* extension) { } // Transfer ownership of |extension| to OnExtensionLoaded. - OnExtensionLoaded(scoped_extension); + OnExtensionLoaded(scoped_extension, allow_privilege_increase); } const Extension* ExtensionsService::GetExtensionByIdInternal( @@ -1945,6 +1881,7 @@ void ExtensionsService::OnExternalExtensionFileFound( NULL)); // no client (silent install) installer->set_install_source(location); installer->set_expected_id(id); + installer->set_allow_privilege_increase(true); installer->InstallCrx(path); } diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h index c831039..f19bb22 100644 --- a/chrome/browser/extensions/extensions_service.h +++ b/chrome/browser/extensions/extensions_service.h @@ -277,15 +277,6 @@ class ExtensionsService void EnableExtension(const std::string& extension_id); void DisableExtension(const std::string& extension_id); - // Updates the |extension|'s granted permissions lists to include all - // permissions in the |extension|'s manifest. - void GrantPermissions(const Extension* extension); - - // Updates the |extension|'s granted permissions lists to include all - // permissions in the |extension|'s manifest and re-enables the - // extension. - void GrantPermissionsAndEnableExtension(const Extension* extension); - // Load the extension from the directory |extension_path|. void LoadExtension(const FilePath& extension_path); @@ -360,10 +351,12 @@ class ExtensionsService virtual void OnLoadedInstalledExtensions(); // Called when an extension has been loaded. - void OnExtensionLoaded(const Extension* extension); + void OnExtensionLoaded(const Extension* extension, + bool allow_privilege_increase); // Called by the backend when an extension has been installed. - void OnExtensionInstalled(const Extension* extension); + void OnExtensionInstalled(const Extension* extension, + bool allow_privilege_increase); // Called by the backend when an external extension is found. void OnExternalExtensionFileFound(const std::string& id, @@ -371,10 +364,6 @@ class ExtensionsService const FilePath& path, Extension::Location location); - // Checks if the privileges requested by |extension| have increased, and if - // so, disables the extension and prompts the user to approve the change. - void DisableIfPrivilegeIncrease(const Extension* extension); - // Go through each extensions in pref, unload blacklisted extensions // and update the blacklist state in pref. virtual void UpdateExtensionBlacklist( diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc index 271309c..e222c27 100644 --- a/chrome/browser/extensions/extensions_service_unittest.cc +++ b/chrome/browser/extensions/extensions_service_unittest.cc @@ -72,7 +72,6 @@ const char* const good_crx = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; const char* const page_action = "obcimlgaoabeegjmmpldobjndiealpln"; const char* const theme_crx = "iamefpfkojoapidjnbafmgkgncegbkad"; const char* const theme2_crx = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf"; -const char* const permissions_crx = "eagpmdpfmaekmmcejjbmjoecnejeiiin"; struct ExtensionsOrder { bool operator()(const Extension* a, const Extension* b) { @@ -99,28 +98,6 @@ static std::vector<std::string> GetErrors() { return ret_val; } -static void AddPattern(ExtensionExtent* extent, const std::string& pattern) { - int schemes = URLPattern::SCHEME_ALL; - extent->AddPattern(URLPattern(schemes, pattern)); -} - -static void AssertEqualExtents(ExtensionExtent* extent1, - ExtensionExtent* extent2) { - std::vector<URLPattern> patterns1 = extent1->patterns(); - std::vector<URLPattern> patterns2 = extent2->patterns(); - std::set<std::string> strings1; - EXPECT_EQ(patterns1.size(), patterns2.size()); - - for (size_t i = 0; i < patterns1.size(); ++i) - strings1.insert(patterns1.at(i).GetAsString()); - - std::set<std::string> strings2; - for (size_t i = 0; i < patterns2.size(); ++i) - strings2.insert(patterns2.at(i).GetAsString()); - - EXPECT_EQ(strings1, strings2); -} - } // namespace class MockExtensionProvider : public ExternalExtensionProvider { @@ -481,39 +458,21 @@ class ExtensionsServiceTest Extension::Location location); void PackAndInstallExtension(const FilePath& dir_path, - const FilePath& pem_path, bool should_succeed) { FilePath crx_path; ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &crx_path)); crx_path = crx_path.AppendASCII("temp.crx"); - - // Use the existing pem key, if provided. - FilePath pem_output_path; - if (pem_path.value().empty()) { - pem_output_path = crx_path.DirName().AppendASCII("temp.pem"); - ASSERT_TRUE(file_util::Delete(pem_output_path, false)); - } else { - ASSERT_TRUE(file_util::PathExists(pem_path)); - } + FilePath pem_path = crx_path.DirName().AppendASCII("temp.pem"); ASSERT_TRUE(file_util::Delete(crx_path, false)); - + ASSERT_TRUE(file_util::Delete(pem_path, false)); scoped_ptr<ExtensionCreator> creator(new ExtensionCreator()); - ASSERT_TRUE(creator->Run(dir_path, - crx_path, - pem_path, - pem_output_path)); - + ASSERT_TRUE(creator->Run(dir_path, crx_path, FilePath(), pem_path)); ASSERT_TRUE(file_util::PathExists(crx_path)); InstallExtension(crx_path, should_succeed); } - void PackAndInstallExtension(const FilePath& dir_path, - bool should_succeed) { - PackAndInstallExtension(dir_path, FilePath(), should_succeed); - } - void InstallExtension(const FilePath& path, bool should_succeed) { ASSERT_TRUE(file_util::PathExists(path)); @@ -695,19 +654,6 @@ class ExtensionsServiceTest EXPECT_EQ(expected_val, val) << msg; } - void SetPref(const std::string& extension_id, - const std::string& pref_path, - Value* value, - const std::string& msg) { - const DictionaryValue* dict = - profile_->GetPrefs()->GetMutableDictionary("extensions.settings"); - ASSERT_TRUE(dict != NULL) << msg; - DictionaryValue* pref = NULL; - ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg; - EXPECT_TRUE(pref != NULL) << msg; - pref->Set(pref_path, value); - } - void SetPrefInteg(const std::string& extension_id, const std::string& pref_path, int value) { @@ -718,46 +664,13 @@ class ExtensionsServiceTest msg += " = "; msg += base::IntToString(value); - SetPref(extension_id, pref_path, Value::CreateIntegerValue(value), msg); - } - - void SetPrefBool(const std::string& extension_id, - const std::string& pref_path, - bool value) { - std::string msg = " while setting: "; - msg += extension_id + " " + pref_path; - msg += " = "; - msg += (value ? "true" : "false"); - - SetPref(extension_id, pref_path, Value::CreateBooleanValue(value), msg); - } - - void ClearPref(const std::string& extension_id, - const std::string& pref_path) { - std::string msg = " while clearing: "; - msg += extension_id + " " + pref_path; - const DictionaryValue* dict = profile_->GetPrefs()->GetMutableDictionary("extensions.settings"); ASSERT_TRUE(dict != NULL) << msg; DictionaryValue* pref = NULL; ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg; EXPECT_TRUE(pref != NULL) << msg; - pref->Remove(pref_path, NULL); - } - - void SetPrefStringSet(const std::string& extension_id, - const std::string& pref_path, - const std::set<std::string>& value) { - std::string msg = " while setting: "; - msg += extension_id + " " + pref_path; - - ListValue* list_value = new ListValue(); - for (std::set<std::string>::const_iterator iter = value.begin(); - iter != value.end(); ++iter) - list_value->Append(Value::CreateStringValue(*iter)); - - SetPref(extension_id, pref_path, list_value, msg); + pref->SetInteger(pref_path, value); } protected: @@ -1094,225 +1007,6 @@ TEST_F(ExtensionsServiceTest, InstallUserScript) { ExtensionErrorReporter::GetInstance()->ClearErrors(); } -// This tests that the granted permissions preferences are correctly set when -// installing an extension. -TEST_F(ExtensionsServiceTest, GrantedPermissions) { - InitializeEmptyExtensionsService(); - FilePath path; - FilePath pem_path; - ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path)); - path = path.AppendASCII("extensions") - .AppendASCII("permissions"); - - pem_path = path.AppendASCII("unknown.pem"); - path = path.AppendASCII("unknown"); - - ASSERT_TRUE(file_util::PathExists(pem_path)); - ASSERT_TRUE(file_util::PathExists(path)); - - ExtensionPrefs* prefs = service_->extension_prefs(); - - std::set<std::string> expected_api_perms; - std::set<std::string> known_api_perms; - bool full_access; - ExtensionExtent expected_host_perms; - ExtensionExtent known_host_perms; - - // Make sure there aren't any granted permissions before the - // extension is installed. - EXPECT_FALSE(prefs->GetGrantedPermissions( - permissions_crx, &full_access, &known_api_perms, &known_host_perms)); - EXPECT_TRUE(known_api_perms.empty()); - EXPECT_TRUE(known_host_perms.is_empty()); - - PackAndInstallExtension(path, pem_path, true); - - EXPECT_EQ(0u, GetErrors().size()); - ASSERT_EQ(1u, service_->extensions()->size()); - std::string extension_id = service_->extensions()->at(0)->id(); - EXPECT_EQ(permissions_crx, extension_id); - - - // Verify that the valid API permissions have been recognized. - expected_api_perms.insert("tabs"); - - AddPattern(&expected_host_perms, "http://*.google.com/*"); - AddPattern(&expected_host_perms, "https://*.google.com/*"); - AddPattern(&expected_host_perms, "http://www.example.com/*"); - - EXPECT_TRUE(prefs->GetGrantedPermissions(extension_id, - &full_access, - &known_api_perms, - &known_host_perms)); - - EXPECT_EQ(expected_api_perms, known_api_perms); - EXPECT_FALSE(full_access); - AssertEqualExtents(&expected_host_perms, &known_host_perms); -} - - -// Tests that the granted permissions full_access bit gets set correctly when -// an extension contains an NPAPI plugin. -TEST_F(ExtensionsServiceTest, GrantedFullAccessPermissions) { - InitializeEmptyExtensionsService(); - - FilePath path; - ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path)); - path = path.AppendASCII("extensions") - .AppendASCII("good") - .AppendASCII("Extensions") - .AppendASCII("hpiknbiabeeppbpihjehijgoemciehgk") - .AppendASCII("2"); - - ASSERT_TRUE(file_util::PathExists(path)); - - PackAndInstallExtension(path, true); - - EXPECT_EQ(0u, GetErrors().size()); - EXPECT_EQ(1u, service_->extensions()->size()); - const Extension* extension = service_->extensions()->at(0); - std::string extension_id = extension->id(); - ExtensionPrefs* prefs = service_->extension_prefs(); - - bool full_access; - std::set<std::string> api_permissions; - ExtensionExtent host_permissions; - EXPECT_TRUE(prefs->GetGrantedPermissions( - extension_id, &full_access, &api_permissions, &host_permissions)); - - EXPECT_TRUE(full_access); - EXPECT_TRUE(api_permissions.empty()); - EXPECT_TRUE(host_permissions.is_empty()); -} - -// Tests that the extension is disabled when permissions are missing from -// the extension's granted permissions preferences. (This simulates updating -// the browser to a version which recognizes more permissions). -TEST_F(ExtensionsServiceTest, GrantedAPIAndHostPermissions) { - InitializeEmptyExtensionsService(); - - FilePath path; - ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path)); - path = path.AppendASCII("extensions") - .AppendASCII("permissions") - .AppendASCII("unknown"); - - ASSERT_TRUE(file_util::PathExists(path)); - - PackAndInstallExtension(path, true); - - EXPECT_EQ(0u, GetErrors().size()); - EXPECT_EQ(1u, service_->extensions()->size()); - const Extension* extension = service_->extensions()->at(0); - std::string extension_id = extension->id(); - - ExtensionPrefs* prefs = service_->extension_prefs(); - - std::set<std::string> expected_api_permissions; - ExtensionExtent expected_host_permissions; - - expected_api_permissions.insert("tabs"); - AddPattern(&expected_host_permissions, "http://*.google.com/*"); - AddPattern(&expected_host_permissions, "https://*.google.com/*"); - AddPattern(&expected_host_permissions, "http://www.example.com/*"); - - std::set<std::string> api_permissions; - std::set<std::string> host_permissions; - - // Test that the extension is disabled when an API permission is missing from - // the extension's granted api permissions preference. (This simulates - // updating the browser to a version which recognizes a new API permission). - host_permissions.insert("http://*.google.com/*"); - host_permissions.insert("https://*.google.com/*"); - host_permissions.insert("http://www.example.com/*"); - - SetPrefBool(extension_id, "granted_permissions.initialized", true); - SetPrefStringSet(extension_id, "granted_permissions.api", api_permissions); - SetPrefStringSet(extension_id, "granted_permissions.host", host_permissions); - - service_->ReloadExtensions(); - - ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::DISABLED); - ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id)); - - // Now grant and re-enable the extension, making sure the prefs are updated. - service_->GrantPermissionsAndEnableExtension(extension); - - ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::ENABLED); - ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id)); - - std::set<std::string> current_api_permissions; - ExtensionExtent current_host_permissions; - bool current_full_access; - - ASSERT_TRUE(prefs->GetGrantedPermissions(extension_id, - ¤t_full_access, - ¤t_api_permissions, - ¤t_host_permissions)); - - ASSERT_FALSE(current_full_access); - ASSERT_EQ(expected_api_permissions, current_api_permissions); - AssertEqualExtents(&expected_host_permissions, ¤t_host_permissions); - - // Tests that the extension is disabled when a host permission is missing from - // the extension's granted host permissions preference. (This simulates - // updating the browser to a version which recognizes additional host - // permissions). - api_permissions.clear(); - host_permissions.clear(); - current_api_permissions.clear(); - current_host_permissions.ClearPaths(); - - api_permissions.insert("tabs"); - host_permissions.insert("http://*.google.com/*"); - host_permissions.insert("https://*.google.com/*"); - - SetPrefBool(extension_id, "granted_permissions.initialized", true); - SetPrefStringSet(extension_id, "granted_permissions.api", api_permissions); - SetPrefStringSet(extension_id, "granted_permissions.host", host_permissions); - - service_->ReloadExtensions(); - - ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::DISABLED); - ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id)); - - // Now grant and re-enable the extension, making sure the prefs are updated. - service_->GrantPermissionsAndEnableExtension(extension); - - ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::ENABLED); - ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id)); - - ASSERT_TRUE(prefs->GetGrantedPermissions(extension_id, - ¤t_full_access, - ¤t_api_permissions, - ¤t_host_permissions)); - - ASSERT_FALSE(current_full_access); - ASSERT_EQ(expected_api_permissions, current_api_permissions); - AssertEqualExtents(&expected_host_permissions, ¤t_host_permissions); - - // Tests that the granted permissions preferences are initialized when - // migrating from the old pref schema. - current_api_permissions.clear(); - current_host_permissions.ClearPaths(); - - ClearPref(extension_id, "granted_permissions"); - - service_->ReloadExtensions(); - - ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::ENABLED); - ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id)); - - ASSERT_TRUE(prefs->GetGrantedPermissions(extension_id, - ¤t_full_access, - ¤t_api_permissions, - ¤t_host_permissions)); - - ASSERT_FALSE(current_full_access); - ASSERT_EQ(expected_api_permissions, current_api_permissions); - AssertEqualExtents(&expected_host_permissions, ¤t_host_permissions); -} - // Test Packaging and installing an extension. TEST_F(ExtensionsServiceTest, PackExtension) { InitializeEmptyExtensionsService(); |