diff options
-rw-r--r-- | chrome/browser/extensions/extension_management.cc | 139 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_management.h | 2 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_management_constants.cc | 48 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_management_constants.h | 47 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_management_test_util.cc | 140 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_management_test_util.h | 103 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_management_unittest.cc | 276 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_service_unittest.cc | 72 | ||||
-rw-r--r-- | chrome/browser/policy/configuration_policy_handler_list_factory.cc | 29 | ||||
-rw-r--r-- | chrome/chrome_browser_extensions.gypi | 2 | ||||
-rw-r--r-- | chrome/chrome_tests_unit.gypi | 2 | ||||
-rw-r--r-- | extensions/browser/pref_names.cc | 1 | ||||
-rw-r--r-- | extensions/browser/pref_names.h | 5 |
13 files changed, 789 insertions, 77 deletions
diff --git a/chrome/browser/extensions/extension_management.cc b/chrome/browser/extensions/extension_management.cc index 186e4b4..1c07ebb 100644 --- a/chrome/browser/extensions/extension_management.cc +++ b/chrome/browser/extensions/extension_management.cc @@ -8,6 +8,8 @@ #include "base/bind_helpers.h" #include "base/logging.h" #include "base/prefs/pref_service.h" +#include "base/strings/string_util.h" +#include "chrome/browser/extensions/extension_management_constants.h" #include "chrome/browser/extensions/external_policy_loader.h" #include "chrome/browser/extensions/external_provider_impl.h" #include "chrome/browser/extensions/standard_management_policy_provider.h" @@ -15,12 +17,80 @@ #include "chrome/browser/profiles/profile.h" #include "components/crx_file/id_util.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/pref_registry/pref_registry_syncable.h" #include "extensions/browser/pref_names.h" #include "extensions/common/url_pattern.h" #include "url/gurl.h" namespace extensions { +namespace { + +const char kMalformedPreferenceWarning[] = + "Malformed extension management preference."; + +enum Scope { + // Parses the default settings. + SCOPE_DEFAULT = 0, + // Parses the settings for an extension with specified extension ID. + SCOPE_INDIVIDUAL, +}; + +// Parse the individual settings for |settings|. |dict| is the a +// sub-dictionary in extension management preference and |scope| represents +// the applicable range of the settings, a single extension, a group of +// extensions or default settings. +// Note that in case of parsing errors, |settings| will NOT be left untouched. +bool ParseIndividualSettings( + const base::DictionaryValue* dict, + Scope scope, + ExtensionManagement::IndividualSettings* settings) { + settings->Reset(); + + std::string installation_mode; + if (dict->GetStringWithoutPathExpansion(schema_constants::kInstallationMode, + &installation_mode)) { + if (installation_mode == schema_constants::kAllowed) { + settings->installation_mode = ExtensionManagement::INSTALLATION_ALLOWED; + } else if (installation_mode == schema_constants::kBlocked) { + settings->installation_mode = ExtensionManagement::INSTALLATION_BLOCKED; + } else if (installation_mode == schema_constants::kForceInstalled) { + settings->installation_mode = ExtensionManagement::INSTALLATION_FORCED; + } else if (installation_mode == schema_constants::kNormalInstalled) { + settings->installation_mode = + ExtensionManagement::INSTALLATION_RECOMMENDED; + } else { + // Invalid value for 'installation_mode'. + LOG(WARNING) << kMalformedPreferenceWarning; + return false; + } + } + + if (settings->installation_mode == ExtensionManagement::INSTALLATION_FORCED || + settings->installation_mode == + ExtensionManagement::INSTALLATION_RECOMMENDED) { + if (scope != SCOPE_INDIVIDUAL) { + // Only individual extensions are allowed to be automatically installed. + LOG(WARNING) << kMalformedPreferenceWarning; + return false; + } + std::string update_url; + if (dict->GetStringWithoutPathExpansion(schema_constants::kUpdateUrl, + &update_url) && + GURL(update_url).is_valid()) { + settings->update_url = update_url; + } else { + // No valid update URL for extension. + LOG(WARNING) << kMalformedPreferenceWarning; + return false; + } + } + + return true; +} + +} // namespace + void ExtensionManagement::IndividualSettings::Reset() { installation_mode = ExtensionManagement::INSTALLATION_ALLOWED; update_url.clear(); @@ -54,6 +124,8 @@ ExtensionManagement::ExtensionManagement(PrefService* pref_service) pref_change_registrar_.Add(pref_names::kAllowedInstallSites, pref_change_callback); pref_change_registrar_.Add(pref_names::kAllowedTypes, pref_change_callback); + pref_change_registrar_.Add(pref_names::kExtensionManagement, + pref_change_callback); Refresh(); provider_.reset(new StandardManagementPolicyProvider(this)); } @@ -145,6 +217,11 @@ void ExtensionManagement::Refresh() { const base::ListValue* allowed_types_pref = static_cast<const base::ListValue*>(LoadPreference( pref_names::kAllowedTypes, true, base::Value::TYPE_LIST)); + const base::DictionaryValue* dict_pref = + static_cast<const base::DictionaryValue*>( + LoadPreference(pref_names::kExtensionManagement, + true, + base::Value::TYPE_DICTIONARY)); // Reset all settings. global_settings_.Reset(); @@ -158,6 +235,22 @@ void ExtensionManagement::Refresh() { default_settings_.installation_mode = INSTALLATION_BLOCKED; } + const base::DictionaryValue* subdict = NULL; + if (dict_pref && + dict_pref->GetDictionary(schema_constants::kWildcard, &subdict)) { + if (!ParseIndividualSettings(subdict, SCOPE_DEFAULT, &default_settings_)) { + LOG(WARNING) << "Default extension management settings parsing error."; + default_settings_.Reset(); + } + + // Settings from new preference have higher priority over legacy ones. + const base::ListValue* list_value = NULL; + if (subdict->GetList(schema_constants::kInstallSources, &list_value)) + install_sources_pref = list_value; + if (subdict->GetList(schema_constants::kAllowedTypes, &list_value)) + allowed_types_pref = list_value; + } + // Parse legacy preferences. ExtensionId id; @@ -196,11 +289,11 @@ void ExtensionManagement::Refresh() { if (install_sources_pref) { global_settings_.has_restricted_install_sources = true; - std::string url_pattern; for (base::ListValue::const_iterator it = install_sources_pref->begin(); it != install_sources_pref->end(); ++it) { - URLPattern entry(URLPattern::SCHEME_ALL); + std::string url_pattern; if ((*it)->GetAsString(&url_pattern)) { + URLPattern entry(URLPattern::SCHEME_ALL); if (entry.Parse(url_pattern) == URLPattern::PARSE_SUCCESS) { global_settings_.install_sources.AddPattern(entry); } else { @@ -217,16 +310,47 @@ void ExtensionManagement::Refresh() { for (base::ListValue::const_iterator it = allowed_types_pref->begin(); it != allowed_types_pref->end(); ++it) { int int_value; + std::string string_value; if ((*it)->GetAsInteger(&int_value) && int_value >= 0 && int_value < Manifest::Type::NUM_LOAD_TYPES) { global_settings_.allowed_types.push_back( static_cast<Manifest::Type>(int_value)); + } else if ((*it)->GetAsString(&string_value)) { + Manifest::Type manifest_type = + schema_constants::GetManifestType(string_value); + if (manifest_type != Manifest::TYPE_UNKNOWN) + global_settings_.allowed_types.push_back(manifest_type); } } } - // TODO(binjin): Add parsing of new ExtensionManagement preference after the - // new ExtensionManagement policy is added. + if (dict_pref) { + // Parse new extension management preference. + for (base::DictionaryValue::Iterator iter(*dict_pref); !iter.IsAtEnd(); + iter.Advance()) { + if (iter.key() == schema_constants::kWildcard) + continue; + if (!iter.value().GetAsDictionary(&subdict)) { + LOG(WARNING) << kMalformedPreferenceWarning; + continue; + } + if (StartsWithASCII( + iter.key(), schema_constants::kUpdateUrlPrefix, true)) + continue; + const std::string& extension_id = iter.key(); + if (!crx_file::id_util::IdIsValid(extension_id)) { + LOG(WARNING) << kMalformedPreferenceWarning; + continue; + } + IndividualSettings by_id; + if (ParseIndividualSettings(subdict, SCOPE_INDIVIDUAL, &by_id)) { + *AccessById(extension_id) = by_id; + } else { + LOG(WARNING) << "Malformed Extension Management settings for " + << iter.key() << "."; + } + } + } } const base::Value* ExtensionManagement::LoadPreference( @@ -293,4 +417,11 @@ content::BrowserContext* ExtensionManagementFactory::GetBrowserContextToUse( return chrome::GetBrowserContextRedirectedInIncognito(context); } +void ExtensionManagementFactory::RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* user_prefs) { + user_prefs->RegisterDictionaryPref( + pref_names::kExtensionManagement, + user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); +} + } // namespace extensions diff --git a/chrome/browser/extensions/extension_management.h b/chrome/browser/extensions/extension_management.h index 1bfe39b..5c44354 100644 --- a/chrome/browser/extensions/extension_management.h +++ b/chrome/browser/extensions/extension_management.h @@ -193,6 +193,8 @@ class ExtensionManagementFactory : public BrowserContextKeyedServiceFactory { content::BrowserContext* context) const OVERRIDE; virtual content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const OVERRIDE; + virtual void RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* registry) OVERRIDE; DISALLOW_COPY_AND_ASSIGN(ExtensionManagementFactory); }; diff --git a/chrome/browser/extensions/extension_management_constants.cc b/chrome/browser/extensions/extension_management_constants.cc new file mode 100644 index 0000000..399bb7c --- /dev/null +++ b/chrome/browser/extensions/extension_management_constants.cc @@ -0,0 +1,48 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/extension_management_constants.h" + +#include "base/macros.h" + +namespace extensions { +namespace schema_constants { + +const char kWildcard[] = "*"; + +const char kInstallationMode[] = "installation_mode"; +const char kAllowed[] = "allowed"; +const char kBlocked[] = "blocked"; +const char kForceInstalled[] = "force_installed"; +const char kNormalInstalled[] = "normal_installed"; + +const char kUpdateUrl[] = "update_url"; +const char kInstallSources[] = "install_sources"; +const char kAllowedTypes[] = "allowed_types"; + +const char kUpdateUrlPrefix[] = "update_url:"; + +const AllowedTypesMapEntry kAllowedTypesMap[] = { + { "extension", Manifest::TYPE_EXTENSION }, + { "theme", Manifest::TYPE_THEME }, + { "user_script", Manifest::TYPE_USER_SCRIPT }, + { "hosted_app", Manifest::TYPE_HOSTED_APP }, + { "legacy_packaged_app", Manifest::TYPE_LEGACY_PACKAGED_APP }, + { "platform_app", Manifest::TYPE_PLATFORM_APP }, + // TODO(binjin): Add shared_module type here and update ExtensionAllowedTypes + // policy. +}; + +const size_t kAllowedTypesMapSize = arraysize(kAllowedTypesMap); + +Manifest::Type GetManifestType(const std::string& name) { + for (size_t index = 0; index < kAllowedTypesMapSize; ++index) { + if (kAllowedTypesMap[index].name == name) + return kAllowedTypesMap[index].manifest_type; + } + return Manifest::TYPE_UNKNOWN; +} + +} // namespace schema_constants +} // namespace extensions diff --git a/chrome/browser/extensions/extension_management_constants.h b/chrome/browser/extensions/extension_management_constants.h new file mode 100644 index 0000000..63a50aa --- /dev/null +++ b/chrome/browser/extensions/extension_management_constants.h @@ -0,0 +1,47 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_MANAGEMENT_CONSTANTS_H_ +#define CHROME_BROWSER_EXTENSIONS_EXTENSION_MANAGEMENT_CONSTANTS_H_ + +#include <string> + +#include "extensions/common/manifest.h" + +namespace extensions { +namespace schema_constants { + +extern const char kWildcard[]; + +extern const char kInstallationMode[]; +extern const char kAllowed[]; +extern const char kBlocked[]; +extern const char kForceInstalled[]; +extern const char kNormalInstalled[]; + +extern const char kUpdateUrl[]; +extern const char kInstallSources[]; +extern const char kAllowedTypes[]; + +extern const char kUpdateUrlPrefix[]; + +struct AllowedTypesMapEntry { + // Name of allowed types of extensions used in schema of extension + // management preference. + const char* name; + // The corresponding Manifest::Type. + Manifest::Type manifest_type; +}; + +extern const size_t kAllowedTypesMapSize; +extern const AllowedTypesMapEntry kAllowedTypesMap[]; + +// Helper fuction over |kAllowedTypesMap|, returns Manifest::TYPE_UNKNOWN if +// not found. +Manifest::Type GetManifestType(const std::string& name); + +} // namespace schema_constants +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_MANAGEMENT_CONSTANTS_H_ diff --git a/chrome/browser/extensions/extension_management_test_util.cc b/chrome/browser/extensions/extension_management_test_util.cc new file mode 100644 index 0000000..86b15cf --- /dev/null +++ b/chrome/browser/extensions/extension_management_test_util.cc @@ -0,0 +1,140 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/extension_management_test_util.h" + +#include "components/crx_file/id_util.h" + +namespace extensions { + +namespace schema = schema_constants; + +namespace { + +std::string make_path(std::string a, std::string b) { + return a + "." + b; +} + +const char kInstallSourcesPath[] = "*.install_sources"; +const char kAllowedTypesPath[] = "*.allowed_types"; + +} // namespace + +ExtensionManagementPrefUpdaterBase::ExtensionManagementPrefUpdaterBase() { +} + +ExtensionManagementPrefUpdaterBase::~ExtensionManagementPrefUpdaterBase() { +} + +void ExtensionManagementPrefUpdaterBase::SetBlacklistedByDefault(bool value) { + pref_->SetString(make_path(schema::kWildcard, schema::kInstallationMode), + value ? schema::kBlocked : schema::kAllowed); +} + +void ExtensionManagementPrefUpdaterBase:: + ClearInstallationModesForIndividualExtensions() { + for (base::DictionaryValue::Iterator it(*pref_.get()); !it.IsAtEnd(); + it.Advance()) { + DCHECK(it.value().IsType(base::Value::TYPE_DICTIONARY)); + if (it.key() != schema::kWildcard) { + DCHECK(crx_file::id_util::IdIsValid(it.key())); + pref_->Remove(make_path(it.key(), schema::kInstallationMode), NULL); + pref_->Remove(make_path(it.key(), schema::kUpdateUrl), NULL); + } + } +} + +void +ExtensionManagementPrefUpdaterBase::SetIndividualExtensionInstallationAllowed( + const ExtensionId& id, + bool allowed) { + DCHECK(crx_file::id_util::IdIsValid(id)); + pref_->SetString(make_path(id, schema::kInstallationMode), + allowed ? schema::kAllowed : schema::kBlocked); + pref_->Remove(make_path(id, schema::kUpdateUrl), NULL); +} + +void ExtensionManagementPrefUpdaterBase::SetIndividualExtensionAutoInstalled( + const ExtensionId& id, + const std::string& update_url, + bool forced) { + DCHECK(crx_file::id_util::IdIsValid(id)); + pref_->SetString(make_path(id, schema::kInstallationMode), + forced ? schema::kForceInstalled : schema::kNormalInstalled); + pref_->SetString(make_path(id, schema::kUpdateUrl), update_url); +} + +void ExtensionManagementPrefUpdaterBase::UnsetInstallSources() { + pref_->Remove(kInstallSourcesPath, NULL); +} + +void ExtensionManagementPrefUpdaterBase::ClearInstallSources() { + ClearList(kInstallSourcesPath); +} + +void ExtensionManagementPrefUpdaterBase::AddInstallSource( + const std::string& install_source) { + AddStringToList(kInstallSourcesPath, install_source); +} + +void ExtensionManagementPrefUpdaterBase::RemoveInstallSource( + const std::string& install_source) { + RemoveStringFromList(kInstallSourcesPath, install_source); +} + +void ExtensionManagementPrefUpdaterBase::UnsetAllowedTypes() { + pref_->Remove(kAllowedTypesPath, NULL); +} + +void ExtensionManagementPrefUpdaterBase::ClearAllowedTypes() { + ClearList(kAllowedTypesPath); +} + +void ExtensionManagementPrefUpdaterBase::AddAllowedType( + const std::string& allowed_type) { + AddStringToList(kAllowedTypesPath, allowed_type); +} + +const base::DictionaryValue* ExtensionManagementPrefUpdaterBase::GetPref() { + return pref_.get(); +} + +void ExtensionManagementPrefUpdaterBase::SetPref(base::DictionaryValue* pref) { + pref_.reset(pref); +} + +scoped_ptr<base::DictionaryValue> +ExtensionManagementPrefUpdaterBase::TakePref() { + return pref_.Pass(); +} + +void ExtensionManagementPrefUpdaterBase::RemoveAllowedType( + const std::string& allowd_type) { + RemoveStringFromList(kAllowedTypesPath, allowd_type); +} + +void ExtensionManagementPrefUpdaterBase::ClearList(const std::string& path) { + pref_->Set(path, new base::ListValue()); +} + +void ExtensionManagementPrefUpdaterBase::AddStringToList( + const std::string& path, + const std::string& str) { + base::ListValue* list_value = NULL; + if (!pref_->GetList(path, &list_value)) { + list_value = new base::ListValue(); + pref_->Set(path, list_value); + } + CHECK(list_value->AppendIfNotPresent(new base::StringValue(str))); +} + +void ExtensionManagementPrefUpdaterBase::RemoveStringFromList( + const std::string& path, + const std::string& str) { + base::ListValue* list_value = NULL; + if (pref_->GetList(path, &list_value)) + CHECK(list_value->Remove(base::StringValue(str), NULL)); +} + +} // namespace extensions diff --git a/chrome/browser/extensions/extension_management_test_util.h b/chrome/browser/extensions/extension_management_test_util.h new file mode 100644 index 0000000..889266a --- /dev/null +++ b/chrome/browser/extensions/extension_management_test_util.h @@ -0,0 +1,103 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_MANAGEMENT_TEST_UTIL_H_ +#define CHROME_BROWSER_EXTENSIONS_EXTENSION_MANAGEMENT_TEST_UTIL_H_ + +#include <string> + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/values.h" +#include "chrome/browser/extensions/extension_management_constants.h" +#include "extensions/browser/pref_names.h" +#include "extensions/common/extension.h" + +namespace extensions { + +// Base class for essential routines on preference manipulation. +class ExtensionManagementPrefUpdaterBase { + public: + ExtensionManagementPrefUpdaterBase(); + virtual ~ExtensionManagementPrefUpdaterBase(); + + // Helper functions for 'installation_mode' manipulation. + void SetBlacklistedByDefault(bool value); + void ClearInstallationModesForIndividualExtensions(); + void SetIndividualExtensionInstallationAllowed(const ExtensionId& id, + bool allowed); + void SetIndividualExtensionAutoInstalled(const ExtensionId& id, + const std::string& update_url, + bool forced); + + // Helper functions for 'install_sources' manipulation. + void UnsetInstallSources(); + void ClearInstallSources(); + void AddInstallSource(const std::string& install_source); + void RemoveInstallSource(const std::string& install_source); + + // Helper functions for 'allowed_types' manipulation. + void UnsetAllowedTypes(); + void ClearAllowedTypes(); + void AddAllowedType(const std::string& allowed_type); + void RemoveAllowedType(const std::string& allowd_type); + + // Expose a read-only preference to user. + const base::DictionaryValue* GetPref(); + + protected: + // Set the preference with |pref|, pass the ownership of it as well. + // This function must be called before accessing publicly exposed functions, + // for example in constructor of subclass. + void SetPref(base::DictionaryValue* pref); + + // Take the preference. Caller takes ownership of it as well. + // This function must be called after accessing publicly exposed functions, + // for example in destructor of subclass. + scoped_ptr<base::DictionaryValue> TakePref(); + + private: + // Helper functions for manipulating sub properties like list of strings. + void ClearList(const std::string& path); + void AddStringToList(const std::string& path, const std::string& str); + void RemoveStringFromList(const std::string& path, const std::string& str); + + scoped_ptr<base::DictionaryValue> pref_; + + DISALLOW_COPY_AND_ASSIGN(ExtensionManagementPrefUpdaterBase); +}; + +// A helper class to manipulate the extension management preference in unit +// tests. +template <class TestingPrefService> +class ExtensionManagementPrefUpdater + : public ExtensionManagementPrefUpdaterBase { + public: + explicit ExtensionManagementPrefUpdater(TestingPrefService* service) + : service_(service) { + const base::Value* pref_value = + service_->GetManagedPref(pref_names::kExtensionManagement); + if (pref_value) { + const base::DictionaryValue* dict_value = NULL; + pref_value->GetAsDictionary(&dict_value); + SetPref(dict_value->DeepCopy()); + } else { + SetPref(new base::DictionaryValue); + } + } + + virtual ~ExtensionManagementPrefUpdater() { + service_->SetManagedPref(pref_names::kExtensionManagement, + TakePref().release()); + } + + private: + TestingPrefService* service_; + + DISALLOW_COPY_AND_ASSIGN(ExtensionManagementPrefUpdater); +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_MANAGEMENT_TEST_UTIL_H_ diff --git a/chrome/browser/extensions/extension_management_unittest.cc b/chrome/browser/extensions/extension_management_unittest.cc index 377d708..e040d53 100644 --- a/chrome/browser/extensions/extension_management_unittest.cc +++ b/chrome/browser/extensions/extension_management_unittest.cc @@ -3,30 +3,61 @@ // found in the LICENSE file. #include <algorithm> +#include <vector> +#include "base/json/json_parser.h" #include "base/memory/scoped_ptr.h" #include "base/prefs/pref_registry_simple.h" #include "base/prefs/testing_pref_service.h" #include "base/values.h" #include "chrome/browser/extensions/extension_management.h" +#include "chrome/browser/extensions/extension_management_test_util.h" #include "chrome/browser/extensions/external_policy_loader.h" #include "extensions/browser/pref_names.h" +#include "extensions/common/manifest.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/url_pattern.h" #include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" namespace extensions { namespace { + const char kTargetExtension[] = "abcdefghijklmnopabcdefghijklmnop"; +const char kTargetExtension2[] = "bcdefghijklmnopabcdefghijklmnopa"; +const char kTargetExtension3[] = "cdefghijklmnopabcdefghijklmnopab"; const char kOtherExtension[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; const char kExampleUpdateUrl[] = "http://example.com/update_url"; + +const char kExampleDictPreference[] = + "{" + " \"abcdefghijklmnopabcdefghijklmnop\": {" // kTargetExtension + " \"installation_mode\": \"allowed\"," + " }," + " \"bcdefghijklmnopabcdefghijklmnopa\": {" // kTargetExtension2 + " \"installation_mode\": \"force_installed\"," + " \"update_url\": \"http://example.com/update_url\"," + " }," + " \"cdefghijklmnopabcdefghijklmnopab\": {" // kTargetExtension3 + " \"installation_mode\": \"normal_installed\"," + " \"update_url\": \"http://example.com/update_url\"," + " }," + " \"*\": {" + " \"installation_mode\": \"blocked\"," + " \"install_sources\": [\"*://foo.com/*\"]," + " \"allowed_types\": [\"theme\", \"user_script\"]," + " }," + "}"; + } // namespace -class ExtensionManagementTest : public testing::Test { +class ExtensionManagementServiceTest : public testing::Test { public: - ExtensionManagementTest() {} - virtual ~ExtensionManagementTest() {} + typedef ExtensionManagementPrefUpdater<TestingPrefServiceSimple> PrefUpdater; + + ExtensionManagementServiceTest() {} + virtual ~ExtensionManagementServiceTest() {} // testing::Test: virtual void SetUp() OVERRIDE { @@ -43,6 +74,8 @@ class ExtensionManagementTest : public testing::Test { pref_service_->registry()->RegisterListPref(pref_names::kInstallAllowList); pref_service_->registry()->RegisterDictionaryPref( pref_names::kInstallForceList); + pref_service_->registry()->RegisterDictionaryPref( + pref_names::kExtensionManagement); extension_management_.reset(new ExtensionManagement(pref_service_.get())); } @@ -60,12 +93,24 @@ class ExtensionManagementTest : public testing::Test { pref_service_->RemoveUserPref(path); } + void SetExampleDictPref() { + std::string error_msg; + scoped_ptr<base::Value> parsed(base::JSONReader::ReadAndReturnError( + kExampleDictPreference, + base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS, + NULL, + &error_msg)); + ASSERT_TRUE(parsed && parsed->IsType(base::Value::TYPE_DICTIONARY)) + << error_msg; + SetPref(true, pref_names::kExtensionManagement, parsed.release()); + } + protected: scoped_ptr<TestingPrefServiceSimple> pref_service_; scoped_ptr<ExtensionManagement> extension_management_; }; -class ExtensionAdminPolicyTest : public ExtensionManagementTest { +class ExtensionAdminPolicyTest : public ExtensionManagementServiceTest { public: ExtensionAdminPolicyTest() {} virtual ~ExtensionAdminPolicyTest() {} @@ -151,7 +196,7 @@ bool ExtensionAdminPolicyTest::MustRemainEnabled(const Extension* extension, // Verify that preference controlled by legacy ExtensionInstallSources policy is // handled well. -TEST_F(ExtensionManagementTest, LegacyInstallSources) { +TEST_F(ExtensionManagementServiceTest, LegacyInstallSources) { base::ListValue allowed_sites_pref; allowed_sites_pref.AppendString("https://www.example.com/foo"); allowed_sites_pref.AppendString("https://corp.mycompany.com/*"); @@ -172,7 +217,7 @@ TEST_F(ExtensionManagementTest, LegacyInstallSources) { // Verify that preference controlled by legacy ExtensionAllowedTypes policy is // handled well. -TEST_F(ExtensionManagementTest, LegacyAllowedTypes) { +TEST_F(ExtensionManagementServiceTest, LegacyAllowedTypes) { base::ListValue allowed_types_pref; allowed_types_pref.AppendInteger(Manifest::TYPE_THEME); allowed_types_pref.AppendInteger(Manifest::TYPE_USER_SCRIPT); @@ -196,7 +241,7 @@ TEST_F(ExtensionManagementTest, LegacyAllowedTypes) { // Verify that preference controlled by legacy ExtensionInstallBlacklist policy // is handled well. -TEST_F(ExtensionManagementTest, LegacyInstallBlacklist) { +TEST_F(ExtensionManagementServiceTest, LegacyInstallBlacklist) { base::ListValue denied_list_pref; denied_list_pref.AppendString(kTargetExtension); @@ -209,7 +254,7 @@ TEST_F(ExtensionManagementTest, LegacyInstallBlacklist) { // Verify that preference controlled by legacy ExtensionInstallWhitelist policy // is handled well. -TEST_F(ExtensionManagementTest, LegacyInstallWhitelist) { +TEST_F(ExtensionManagementServiceTest, LegacyInstallWhitelist) { base::ListValue denied_list_pref; denied_list_pref.AppendString("*"); base::ListValue allowed_list_pref; @@ -231,7 +276,7 @@ TEST_F(ExtensionManagementTest, LegacyInstallWhitelist) { // Verify that preference controlled by legacy ExtensionInstallForcelist policy // is handled well. -TEST_F(ExtensionManagementTest, LegacyInstallForcelist) { +TEST_F(ExtensionManagementServiceTest, LegacyInstallForcelist) { base::DictionaryValue forced_list_pref; ExternalPolicyLoader::AddExtension( &forced_list_pref, kTargetExtension, kExampleUpdateUrl); @@ -251,6 +296,219 @@ TEST_F(ExtensionManagementTest, LegacyInstallForcelist) { ExtensionManagement::INSTALLATION_ALLOWED); } +// Tests parsing of new dictionary preference. +TEST_F(ExtensionManagementServiceTest, PreferenceParsing) { + SetExampleDictPref(); + + // Verifies the installation mode settings. + EXPECT_TRUE(extension_management_->BlacklistedByDefault()); + EXPECT_EQ(extension_management_->ReadById(kTargetExtension).installation_mode, + ExtensionManagement::INSTALLATION_ALLOWED); + EXPECT_EQ( + extension_management_->ReadById(kTargetExtension2).installation_mode, + ExtensionManagement::INSTALLATION_FORCED); + EXPECT_EQ(extension_management_->ReadById(kTargetExtension2).update_url, + kExampleUpdateUrl); + EXPECT_EQ( + extension_management_->ReadById(kTargetExtension3).installation_mode, + ExtensionManagement::INSTALLATION_RECOMMENDED); + EXPECT_EQ(extension_management_->ReadById(kTargetExtension3).update_url, + kExampleUpdateUrl); + EXPECT_EQ(extension_management_->ReadById(kOtherExtension).installation_mode, + ExtensionManagement::INSTALLATION_BLOCKED); + + // Verifies global settings. + EXPECT_TRUE(extension_management_->ReadGlobalSettings() + .has_restricted_install_sources); + const URLPatternSet& allowed_sites = + extension_management_->ReadGlobalSettings().install_sources; + EXPECT_EQ(allowed_sites.size(), 1u); + EXPECT_TRUE(allowed_sites.MatchesURL(GURL("http://foo.com/entry"))); + EXPECT_FALSE(allowed_sites.MatchesURL(GURL("http://bar.com/entry"))); + + EXPECT_TRUE( + extension_management_->ReadGlobalSettings().has_restricted_allowed_types); + const std::vector<Manifest::Type>& allowed_types = + extension_management_->ReadGlobalSettings().allowed_types; + EXPECT_EQ(allowed_types.size(), 2u); + EXPECT_TRUE(std::find(allowed_types.begin(), + allowed_types.end(), + Manifest::TYPE_THEME) != allowed_types.end()); + EXPECT_TRUE(std::find(allowed_types.begin(), + allowed_types.end(), + Manifest::TYPE_USER_SCRIPT) != allowed_types.end()); +} + +// Tests functionality of new preference as to deprecate legacy +// ExtensionInstallSources policy. +TEST_F(ExtensionManagementServiceTest, NewInstallSources) { + // Set the legacy preference, and verifies that it works. + base::ListValue allowed_sites_pref; + allowed_sites_pref.AppendString("https://www.example.com/foo"); + SetPref( + true, pref_names::kAllowedInstallSites, allowed_sites_pref.DeepCopy()); + EXPECT_TRUE(extension_management_->ReadGlobalSettings() + .has_restricted_install_sources); + EXPECT_TRUE( + extension_management_->ReadGlobalSettings() + .install_sources.MatchesURL(GURL("https://www.example.com/foo"))); + + // Set the new dictionary preference. + { + PrefUpdater updater(pref_service_.get()); + updater.ClearInstallSources(); + } + // Verifies that the new one overrides the legacy ones. + EXPECT_TRUE(extension_management_->ReadGlobalSettings() + .has_restricted_install_sources); + EXPECT_FALSE( + extension_management_->ReadGlobalSettings() + .install_sources.MatchesURL(GURL("https://www.example.com/foo"))); + + // Updates the new dictionary preference. + { + PrefUpdater updater(pref_service_.get()); + updater.AddInstallSource("https://corp.mycompany.com/*"); + } + EXPECT_TRUE(extension_management_->ReadGlobalSettings() + .has_restricted_install_sources); + EXPECT_TRUE(extension_management_->ReadGlobalSettings() + .install_sources.MatchesURL( + GURL("https://corp.mycompany.com/entry"))); +} + +// Tests functionality of new preference as to deprecate legacy +// ExtensionAllowedTypes policy. +TEST_F(ExtensionManagementServiceTest, NewAllowedTypes) { + // Set the legacy preference, and verifies that it works. + base::ListValue allowed_types_pref; + allowed_types_pref.AppendInteger(Manifest::TYPE_USER_SCRIPT); + SetPref(true, pref_names::kAllowedTypes, allowed_types_pref.DeepCopy()); + EXPECT_TRUE( + extension_management_->ReadGlobalSettings().has_restricted_allowed_types); + EXPECT_EQ(extension_management_->ReadGlobalSettings().allowed_types.size(), + 1u); + EXPECT_EQ(extension_management_->ReadGlobalSettings().allowed_types[0], + Manifest::TYPE_USER_SCRIPT); + + // Set the new dictionary preference. + { + PrefUpdater updater(pref_service_.get()); + updater.ClearAllowedTypes(); + } + // Verifies that the new one overrides the legacy ones. + EXPECT_TRUE( + extension_management_->ReadGlobalSettings().has_restricted_allowed_types); + EXPECT_EQ(extension_management_->ReadGlobalSettings().allowed_types.size(), + 0u); + + // Updates the new dictionary preference. + { + PrefUpdater updater(pref_service_.get()); + updater.AddAllowedType("theme"); + } + EXPECT_TRUE( + extension_management_->ReadGlobalSettings().has_restricted_allowed_types); + EXPECT_EQ(extension_management_->ReadGlobalSettings().allowed_types.size(), + 1u); + EXPECT_EQ(extension_management_->ReadGlobalSettings().allowed_types[0], + Manifest::TYPE_THEME); +} + +// Tests functionality of new preference as to deprecate legacy +// ExtensionInstallBlacklist policy. +TEST_F(ExtensionManagementServiceTest, NewInstallBlacklist) { + // Set the new dictionary preference. + { + PrefUpdater updater(pref_service_.get()); + updater.SetBlacklistedByDefault(false); // Allowed by default. + updater.SetIndividualExtensionInstallationAllowed(kTargetExtension, false); + } + EXPECT_FALSE(extension_management_->BlacklistedByDefault()); + EXPECT_EQ(extension_management_->ReadById(kTargetExtension).installation_mode, + ExtensionManagement::INSTALLATION_BLOCKED); + EXPECT_EQ(extension_management_->ReadById(kOtherExtension).installation_mode, + ExtensionManagement::INSTALLATION_ALLOWED); + + // Set legacy preference. + base::ListValue denied_list_pref; + denied_list_pref.AppendString("*"); + denied_list_pref.AppendString(kTargetExtension2); + SetPref(true, pref_names::kInstallDenyList, denied_list_pref.DeepCopy()); + + base::ListValue allowed_list_pref; + allowed_list_pref.AppendString(kTargetExtension); + SetPref(true, pref_names::kInstallAllowList, allowed_list_pref.DeepCopy()); + + // Verifies that the new one have higher priority over the legacy ones. + EXPECT_FALSE(extension_management_->BlacklistedByDefault()); + EXPECT_EQ(extension_management_->ReadById(kTargetExtension).installation_mode, + ExtensionManagement::INSTALLATION_BLOCKED); + EXPECT_EQ( + extension_management_->ReadById(kTargetExtension2).installation_mode, + ExtensionManagement::INSTALLATION_BLOCKED); + EXPECT_EQ(extension_management_->ReadById(kOtherExtension).installation_mode, + ExtensionManagement::INSTALLATION_ALLOWED); +} + +// Tests functionality of new preference as to deprecate legacy +// ExtensionInstallWhitelist policy. +TEST_F(ExtensionManagementServiceTest, NewInstallWhitelist) { + // Set the new dictionary preference. + { + PrefUpdater updater(pref_service_.get()); + updater.SetBlacklistedByDefault(true); // Disallowed by default. + updater.SetIndividualExtensionInstallationAllowed(kTargetExtension, true); + } + EXPECT_TRUE(extension_management_->BlacklistedByDefault()); + EXPECT_EQ(extension_management_->ReadById(kTargetExtension).installation_mode, + ExtensionManagement::INSTALLATION_ALLOWED); + EXPECT_EQ(extension_management_->ReadById(kOtherExtension).installation_mode, + ExtensionManagement::INSTALLATION_BLOCKED); + + // Set legacy preference. + base::ListValue denied_list_pref; + denied_list_pref.AppendString(kTargetExtension); + SetPref(true, pref_names::kInstallDenyList, denied_list_pref.DeepCopy()); + + base::ListValue allowed_list_pref; + allowed_list_pref.AppendString(kTargetExtension2); + SetPref(true, pref_names::kInstallAllowList, allowed_list_pref.DeepCopy()); + + // Verifies that the new one have higher priority over the legacy ones. + EXPECT_TRUE(extension_management_->BlacklistedByDefault()); + EXPECT_EQ(extension_management_->ReadById(kTargetExtension).installation_mode, + ExtensionManagement::INSTALLATION_ALLOWED); + EXPECT_EQ( + extension_management_->ReadById(kTargetExtension2).installation_mode, + ExtensionManagement::INSTALLATION_ALLOWED); + EXPECT_EQ(extension_management_->ReadById(kOtherExtension).installation_mode, + ExtensionManagement::INSTALLATION_BLOCKED); +} + +// Tests functionality of new preference as to deprecate legacy +// ExtensionInstallForcelist policy. +TEST_F(ExtensionManagementServiceTest, NewInstallForcelist) { + // Set some legacy preferences, to verify that the new one overrides the + // legacy ones. + base::ListValue denied_list_pref; + denied_list_pref.AppendString(kTargetExtension); + SetPref(true, pref_names::kInstallDenyList, denied_list_pref.DeepCopy()); + + // Set the new dictionary preference. + { + PrefUpdater updater(pref_service_.get()); + updater.SetIndividualExtensionAutoInstalled( + kTargetExtension, kExampleUpdateUrl, true); + } + EXPECT_EQ(extension_management_->ReadById(kTargetExtension).installation_mode, + ExtensionManagement::INSTALLATION_FORCED); + EXPECT_EQ(extension_management_->ReadById(kTargetExtension).update_url, + kExampleUpdateUrl); + EXPECT_EQ(extension_management_->ReadById(kOtherExtension).installation_mode, + ExtensionManagement::INSTALLATION_ALLOWED); +} + // Tests the flag value indicating that extensions are blacklisted by default. TEST_F(ExtensionAdminPolicyTest, BlacklistedByDefault) { EXPECT_FALSE(BlacklistedByDefault(NULL)); diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc index 383b238..3743654 100644 --- a/chrome/browser/extensions/extension_service_unittest.cc +++ b/chrome/browser/extensions/extension_service_unittest.cc @@ -37,6 +37,7 @@ #include "chrome/browser/extensions/extension_creator.h" #include "chrome/browser/extensions/extension_error_reporter.h" #include "chrome/browser/extensions/extension_error_ui.h" +#include "chrome/browser/extensions/extension_management_test_util.h" #include "chrome/browser/extensions/extension_notification_observer.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service_test_base.h" @@ -91,7 +92,6 @@ #include "extensions/browser/external_provider_interface.h" #include "extensions/browser/install_flag.h" #include "extensions/browser/management_policy.h" -#include "extensions/browser/pref_names.h" #include "extensions/browser/test_management_policy.h" #include "extensions/browser/uninstall_reason.h" #include "extensions/common/constants.h" @@ -1104,6 +1104,8 @@ class ExtensionServiceTest : public extensions::ExtensionServiceTestBase, } protected: + typedef extensions::ExtensionManagementPrefUpdater<TestingPrefServiceSyncable> + ManagementPrefUpdater; scoped_ptr<ExtensionSyncService> extension_sync_service_; extensions::ExtensionList loaded_; std::string unloaded_id_; @@ -3292,10 +3294,10 @@ TEST_F(ExtensionServiceTest, UnloadBlacklistedExtensionPolicy) { UpdateExtension(good_crx, path, FAILED_SILENTLY); EXPECT_EQ(1u, registry()->enabled_extensions().size()); - base::ListValue whitelist; - whitelist.Append(new base::StringValue(good_crx)); - profile_->GetTestingPrefService()->SetManagedPref( - extensions::pref_names::kInstallAllowList, whitelist.DeepCopy()); + { + ManagementPrefUpdater pref(profile_->GetTestingPrefService()); + pref.SetIndividualExtensionInstallationAllowed(good_crx, true); + } test_blacklist.SetBlacklistState( good_crx, extensions::BLACKLISTED_MALWARE, true); @@ -3587,10 +3589,8 @@ TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) { // Blacklist everything. { - ListPrefUpdate update(profile()->GetPrefs(), - extensions::pref_names::kInstallDenyList); - base::ListValue* blacklist = update.Get(); - blacklist->Append(new base::StringValue("*")); + ManagementPrefUpdater pref(profile_->GetTestingPrefService()); + pref.SetBlacklistedByDefault(true); } // Blacklist prevents us from installing good_crx. @@ -3600,10 +3600,8 @@ TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) { // Now whitelist this particular extension. { - base::ListValue whitelist; - whitelist.Append(new base::StringValue(good_crx)); - profile_->GetTestingPrefService()->SetManagedPref( - extensions::pref_names::kInstallAllowList, whitelist.DeepCopy()); + ManagementPrefUpdater pref(profile_->GetTestingPrefService()); + pref.SetIndividualExtensionInstallationAllowed(good_crx, true); } // Ensure we can now install good_crx. @@ -3613,21 +3611,17 @@ TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) { // Extension blacklisted by policy get unloaded after installing. TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) { - InitializeEmptyExtensionService(); + InitializeEmptyExtensionServiceWithTestingPrefs(); // Install good_crx. base::FilePath path = data_dir().AppendASCII("good.crx"); InstallCRX(path, INSTALL_NEW); EXPECT_EQ(1u, registry()->enabled_extensions().size()); - { // Scope for pref update notification. - PrefService* prefs = profile()->GetPrefs(); - ListPrefUpdate update(prefs, extensions::pref_names::kInstallDenyList); - base::ListValue* blacklist = update.Get(); - ASSERT_TRUE(blacklist != NULL); - + { + ManagementPrefUpdater pref(profile_->GetTestingPrefService()); // Blacklist this extension. - blacklist->Append(new base::StringValue(good_crx)); + pref.SetIndividualExtensionInstallationAllowed(good_crx, false); } // Extension should not be running now. @@ -3637,14 +3631,12 @@ TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) { // Tests that component extensions are not blacklisted by policy. TEST_F(ExtensionServiceTest, ComponentExtensionWhitelisted) { - InitializeEmptyExtensionService(); + InitializeEmptyExtensionServiceWithTestingPrefs(); // Blacklist everything. { - ListPrefUpdate update(profile()->GetPrefs(), - extensions::pref_names::kInstallDenyList); - base::ListValue* blacklist = update.Get(); - blacklist->Append(new base::StringValue("*")); + ManagementPrefUpdater pref(profile_->GetTestingPrefService()); + pref.SetBlacklistedByDefault(true); } // Install a component extension. @@ -3670,10 +3662,8 @@ TEST_F(ExtensionServiceTest, ComponentExtensionWhitelisted) { // Extension should not be uninstalled on blacklist changes. { - ListPrefUpdate update(profile()->GetPrefs(), - extensions::pref_names::kInstallDenyList); - base::ListValue* blacklist = update.Get(); - blacklist->Append(new base::StringValue(good0)); + ManagementPrefUpdater pref(profile_->GetTestingPrefService()); + pref.SetIndividualExtensionInstallationAllowed(good0, false); } base::RunLoop().RunUntilIdle(); ASSERT_EQ(1u, registry()->enabled_extensions().size()); @@ -3685,20 +3675,12 @@ TEST_F(ExtensionServiceTest, PolicyInstalledExtensionsWhitelisted) { InitializeEmptyExtensionServiceWithTestingPrefs(); { + ManagementPrefUpdater pref(profile_->GetTestingPrefService()); // Blacklist everything. - ListPrefUpdate blacklist_update(profile()->GetPrefs(), - extensions::pref_names::kInstallDenyList); - base::ListValue* blacklist = blacklist_update.Get(); - blacklist->AppendString("*"); - } - - { + pref.SetBlacklistedByDefault(true); // Mark good.crx for force-installation. - base::DictionaryValue forcelist; - extensions::ExternalPolicyLoader::AddExtension( - &forcelist, good_crx, "http://example.com/update_url"); - profile_->GetTestingPrefService()->SetManagedPref( - extensions::pref_names::kInstallForceList, forcelist.DeepCopy()); + pref.SetIndividualExtensionAutoInstalled( + good_crx, "http://example.com/update_url", true); } // Have policy force-install an extension. @@ -3722,10 +3704,8 @@ TEST_F(ExtensionServiceTest, PolicyInstalledExtensionsWhitelisted) { // Blacklist update should not uninstall the extension. { - ListPrefUpdate update(profile()->GetPrefs(), - extensions::pref_names::kInstallDenyList); - base::ListValue* blacklist = update.Get(); - blacklist->Append(new base::StringValue(good0)); + ManagementPrefUpdater pref(profile_->GetTestingPrefService()); + pref.SetIndividualExtensionInstallationAllowed(good0, false); } base::RunLoop().RunUntilIdle(); ASSERT_EQ(1u, registry()->enabled_extensions().size()); diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 0df28c3..bc1cff3 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc @@ -50,6 +50,7 @@ #if defined(ENABLE_EXTENSIONS) #include "chrome/browser/extensions/api/messaging/native_messaging_policy_handler.h" +#include "chrome/browser/extensions/extension_management_constants.h" #include "chrome/browser/extensions/policy_handlers.h" #include "extensions/browser/pref_names.h" #include "extensions/common/manifest.h" @@ -496,24 +497,16 @@ const PolicyToPreferenceMapEntry kSimplePolicyMap[] = { void GetExtensionAllowedTypesMap( ScopedVector<StringMappingListPolicyHandler::MappingEntry>* result) { // Mapping from extension type names to Manifest::Type. - result->push_back(new StringMappingListPolicyHandler::MappingEntry( - "extension", scoped_ptr<base::Value>(new base::FundamentalValue( - extensions::Manifest::TYPE_EXTENSION)))); - result->push_back(new StringMappingListPolicyHandler::MappingEntry( - "theme", scoped_ptr<base::Value>(new base::FundamentalValue( - extensions::Manifest::TYPE_THEME)))); - result->push_back(new StringMappingListPolicyHandler::MappingEntry( - "user_script", scoped_ptr<base::Value>(new base::FundamentalValue( - extensions::Manifest::TYPE_USER_SCRIPT)))); - result->push_back(new StringMappingListPolicyHandler::MappingEntry( - "hosted_app", scoped_ptr<base::Value>(new base::FundamentalValue( - extensions::Manifest::TYPE_HOSTED_APP)))); - result->push_back(new StringMappingListPolicyHandler::MappingEntry( - "legacy_packaged_app", scoped_ptr<base::Value>(new base::FundamentalValue( - extensions::Manifest::TYPE_LEGACY_PACKAGED_APP)))); - result->push_back(new StringMappingListPolicyHandler::MappingEntry( - "platform_app", scoped_ptr<base::Value>(new base::FundamentalValue( - extensions::Manifest::TYPE_PLATFORM_APP)))); + for (size_t index = 0; + index < extensions::schema_constants::kAllowedTypesMapSize; + ++index) { + const extensions::schema_constants::AllowedTypesMapEntry& entry = + extensions::schema_constants::kAllowedTypesMap[index]; + result->push_back(new StringMappingListPolicyHandler::MappingEntry( + entry.name, + scoped_ptr<base::Value>( + new base::FundamentalValue(entry.manifest_type)))); + } } #endif diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi index ab0c7c6..66bd51c 100644 --- a/chrome/chrome_browser_extensions.gypi +++ b/chrome/chrome_browser_extensions.gypi @@ -627,6 +627,8 @@ 'browser/extensions/extension_keybinding_registry.h', 'browser/extensions/extension_management.cc', 'browser/extensions/extension_management.h', + 'browser/extensions/extension_management_constants.cc', + 'browser/extensions/extension_management_constants.h', 'browser/extensions/extension_message_bubble_controller.cc', 'browser/extensions/extension_message_bubble_controller.h', 'browser/extensions/extension_renderer_state.cc', diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 0d75eda..5e3d770 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -396,6 +396,8 @@ 'browser/extensions/extension_icon_manager_unittest.cc', 'browser/extensions/extension_install_checker_unittest.cc', 'browser/extensions/extension_install_prompt_unittest.cc', + 'browser/extensions/extension_management_test_util.cc', + 'browser/extensions/extension_management_test_util.h', 'browser/extensions/extension_management_unittest.cc', 'browser/extensions/extension_message_bubble_controller_unittest.cc', 'browser/extensions/extension_path_util_unittest.cc', diff --git a/extensions/browser/pref_names.cc b/extensions/browser/pref_names.cc index 94b386c..29c3945 100644 --- a/extensions/browser/pref_names.cc +++ b/extensions/browser/pref_names.cc @@ -34,6 +34,7 @@ const char kAppFullscreenAllowed[] = "apps.fullscreen.allowed"; const char kBookmarkAppCreationLaunchType[] = "extensions.bookmark_app_creation_launch_type"; const char kExtensions[] = "extensions.settings"; +const char kExtensionManagement[] = "extensions.management"; const char kInstallAllowList[] = "extensions.install.allowlist"; const char kInstallDenyList[] = "extensions.install.denylist"; const char kInstallForceList[] = "extensions.install.forcelist"; diff --git a/extensions/browser/pref_names.h b/extensions/browser/pref_names.h index e552455..e221c35 100644 --- a/extensions/browser/pref_names.h +++ b/extensions/browser/pref_names.h @@ -47,6 +47,11 @@ extern const char kBookmarkAppCreationLaunchType[]; // extension ids. extern const char kExtensions[]; +// Dictionary pref that manages extensions, controlled by policy. +// Values are expected to conform to the schema of the ExtensionManagement +// policy. +extern const char kExtensionManagement[]; + // A whitelist of extension ids the user can install: exceptions from the // following blacklist. extern const char kInstallAllowList[]; |