summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/extension_management.cc139
-rw-r--r--chrome/browser/extensions/extension_management.h2
-rw-r--r--chrome/browser/extensions/extension_management_constants.cc48
-rw-r--r--chrome/browser/extensions/extension_management_constants.h47
-rw-r--r--chrome/browser/extensions/extension_management_test_util.cc140
-rw-r--r--chrome/browser/extensions/extension_management_test_util.h103
-rw-r--r--chrome/browser/extensions/extension_management_unittest.cc276
-rw-r--r--chrome/browser/extensions/extension_service_unittest.cc72
-rw-r--r--chrome/browser/policy/configuration_policy_handler_list_factory.cc29
-rw-r--r--chrome/chrome_browser_extensions.gypi2
-rw-r--r--chrome/chrome_tests_unit.gypi2
-rw-r--r--extensions/browser/pref_names.cc1
-rw-r--r--extensions/browser/pref_names.h5
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[];