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

Unified Diff: chrome/browser/extensions/extension_management.cc

Issue 559603002: Add new ExtensionManagement preference (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase; fixes Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/extension_management.cc
diff --git a/chrome/browser/extensions/extension_management.cc b/chrome/browser/extensions/extension_management.cc
index 186e4b49d08eb6a2dfcd601f83b6b9e1c898a1f7..be19b0936b82c1bf8bd9f0d8e2c3f39419311800 100644
--- a/chrome/browser/extensions/extension_management.cc
+++ b/chrome/browser/extensions/extension_management.cc
@@ -8,6 +8,7 @@
#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/external_policy_loader.h"
#include "chrome/browser/extensions/external_provider_impl.h"
#include "chrome/browser/extensions/standard_management_policy_provider.h"
@@ -21,6 +22,89 @@
namespace extensions {
+namespace schema_constants {
+
+const char kAllOtherExtension[] = "*";
Joao da Silva 2014/09/18 12:08:21 Rename this to kWildcard
binjin 2014/09/18 14:37:27 Done.
+
+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 AllowedTypesMapType 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 },
Joao da Silva 2014/09/18 12:08:21 Align the types in the same column
binjin 2014/09/18 14:37:27 Done.
+ // TODO(binjin): Add shared_module type here and update ExtensionAllowedTypes
+ // policy.
+ { NULL, Manifest::TYPE_UNKNOWN }
Joao da Silva 2014/09/18 12:08:21 Remove the NULL entry
binjin 2014/09/18 14:37:26 Done.
+};
Joao da Silva 2014/09/18 12:08:21 Add the size constant: const size_t kAllowedTypes
binjin 2014/09/18 14:37:27 Done.
+
+} // namespace schema_constants
+
+bool ExtensionManagement::IndividualSettings::Parse(
+ const base::DictionaryValue* dict,
+ Scope scope) {
+ Reset();
+
+ std::string installation_mode;
+ if (dict->GetStringWithoutPathExpansion(schema_constants::kInstallationMode,
+ &installation_mode)) {
+ if (installation_mode == schema_constants::kAllowed) {
+ this->installation_mode = INSTALLATION_ALLOWED;
+ } else if (installation_mode == schema_constants::kBlocked) {
+ this->installation_mode = INSTALLATION_BLOCKED;
+ } else if (installation_mode == schema_constants::kForceInstalled) {
+ this->installation_mode = INSTALLATION_FORCED;
+ } else if (installation_mode == schema_constants::kNormalInstalled) {
+ this->installation_mode = INSTALLATION_RECOMMENDED;
+ } else {
+ LOG(WARNING) << "Invalid value for 'installation_modes'.";
Joao da Silva 2014/09/18 12:08:21 installation_mode
binjin 2014/09/18 14:37:27 Done.
+ return false;
+ }
+ }
+
+ std::string update_url;
+ if (dict->GetStringWithoutPathExpansion(schema_constants::kUpdateUrl,
+ &update_url)) {
Joao da Silva 2014/09/18 12:08:21 The update_url only matters for FORCED and RECOMME
binjin 2014/09/18 14:37:26 Done with further simplification.
+ if (scope != SCOPE_INDIVIDUAL) {
+ LOG(WARNING)
+ << "Only individual extensions are allowed to have an update URL.";
+ return false;
+ }
+ if (!GURL(update_url).is_valid()) {
+ LOG(WARNING) << "No valid update URL for this extension.";
+ return false;
+ }
+ this->update_url = update_url;
+ }
+
+ if (this->installation_mode == INSTALLATION_FORCED ||
+ this->installation_mode == INSTALLATION_RECOMMENDED) {
+ if (scope != SCOPE_INDIVIDUAL) {
+ LOG(WARNING) << "Only individual extensions are allowed to be "
+ "automatically installed.";
+ return false;
+ }
+ if (this->update_url.empty()) {
+ LOG(WARNING) << "No valid update URL for this extension.";
+ return false;
+ }
+ }
+
+ return true;
+}
+
void ExtensionManagement::IndividualSettings::Reset() {
installation_mode = ExtensionManagement::INSTALLATION_ALLOWED;
update_url.clear();
@@ -54,6 +138,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 +231,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 +249,21 @@ void ExtensionManagement::Refresh() {
default_settings_.installation_mode = INSTALLATION_BLOCKED;
}
+ const base::DictionaryValue* subdict = NULL;
+ if (dict_pref &&
+ dict_pref->GetDictionary(schema_constants::kAllOtherExtension,
+ &subdict)) {
+ if (!default_settings_.Parse(subdict, IndividualSettings::SCOPE_DEFAULT))
+ LOG(WARNING) << "Default extension management settings parsing error.";
Joao da Silva 2014/09/18 12:08:21 Reset() default_settings_ in this case?
binjin 2014/09/18 14:37:26 Done.
+
+ // Settings from new preference have higher priority over legacy ones.
+ const base::ListValue* list_value;
Joao da Silva 2014/09/18 12:08:21 = NULL
binjin 2014/09/18 14:37:26 Done.
+ 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 +302,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 +323,52 @@ 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)) {
+ for (const schema_constants::AllowedTypesMapType* iter =
+ schema_constants::kAllowedTypesMap;
+ iter->name;
+ ++iter) {
+ if (iter->name == string_value) {
+ global_settings_.allowed_types.push_back(iter->manifest_type);
+ break;
Joao da Silva 2014/09/18 12:08:21 Make a helper for this: bool GetManifestType(cons
binjin 2014/09/18 14:37:27 Done. I tried to avoid passing pointer here, and r
+ }
+ }
}
}
}
- // 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::kAllOtherExtension)
+ continue;
+ if (!iter.value().GetAsDictionary(&subdict)) {
+ LOG(WARNING) << "Malformed extension management preference.";
+ continue;
+ }
+ if (!StartsWithASCII(
+ iter.key(), schema_constants::kUpdateUrlPrefix, true)) {
Joao da Silva 2014/09/18 12:08:21 if (StartsWithASCII(...)) continue;
binjin 2014/09/18 14:37:27 Done.
+ const std::string& extension_id = iter.key();
+ if (!crx_file::id_util::IdIsValid(extension_id)) {
+ LOG(WARNING) << "Malformed extension management preference.";
+ continue;
+ }
+ IndividualSettings by_id;
+ if (!by_id.Parse(subdict, IndividualSettings::SCOPE_INDIVIDUAL)) {
+ LOG(WARNING) << "Malformed extension management preference.";
+ continue;
+ } else {
+ *AccessById(extension_id) = by_id;
+ }
+ }
+ }
+ }
}
const base::Value* ExtensionManagement::LoadPreference(

Powered by Google App Engine
This is Rietveld 408576698