// 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_internal.h" #include "base/logging.h" #include "base/values.h" #include "base/version.h" #include "chrome/browser/extensions/extension_management_constants.h" #include "extensions/common/url_pattern_set.h" #include "url/gurl.h" namespace extensions { namespace internal { namespace { const char kMalformedPreferenceWarning[] = "Malformed extension management preference."; } // namespace IndividualSettings::IndividualSettings() { Reset(); } // Initializes from default settings. IndividualSettings::IndividualSettings( const IndividualSettings* default_settings) { installation_mode = default_settings->installation_mode; update_url = default_settings->installation_mode; blocked_permissions = default_settings->blocked_permissions; // We are not initializing |minimum_version_required| from |default_settings| // here since it's not applicable to default settings. } IndividualSettings::~IndividualSettings() { } bool IndividualSettings::Parse(const base::DictionaryValue* dict, ParsingScope scope) { std::string installation_mode_str; if (dict->GetStringWithoutPathExpansion(schema_constants::kInstallationMode, &installation_mode_str)) { if (installation_mode_str == schema_constants::kAllowed) { installation_mode = ExtensionManagement::INSTALLATION_ALLOWED; } else if (installation_mode_str == schema_constants::kBlocked) { installation_mode = ExtensionManagement::INSTALLATION_BLOCKED; } else if (installation_mode_str == schema_constants::kForceInstalled) { installation_mode = ExtensionManagement::INSTALLATION_FORCED; } else if (installation_mode_str == schema_constants::kNormalInstalled) { installation_mode = ExtensionManagement::INSTALLATION_RECOMMENDED; } else { // Invalid value for 'installation_mode'. LOG(WARNING) << kMalformedPreferenceWarning; return false; } // Only proceed to fetch update url if force or recommended install mode // is set. if (installation_mode == ExtensionManagement::INSTALLATION_FORCED || 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_str; if (dict->GetStringWithoutPathExpansion(schema_constants::kUpdateUrl, &update_url_str) && GURL(update_url_str).is_valid()) { update_url = update_url_str; } else { // No valid update URL for extension. LOG(WARNING) << kMalformedPreferenceWarning; return false; } } } // Parses the blocked permission settings. const base::ListValue* list_value = nullptr; base::string16 error; // If applicable, inherit from global block list and remove all explicitly // allowed permissions. if (scope != SCOPE_DEFAULT && dict->GetListWithoutPathExpansion(schema_constants::kAllowedPermissions, &list_value)) { // It is assumed that Parse() is already called for SCOPE_DEFAULT and // settings specified for |this| is initialized by copying from default // settings, including the |blocked_permissions| setting here. // That is, |blocked_permissions| should be the default block permissions // list settings here. APIPermissionSet globally_blocked_permissions = blocked_permissions; APIPermissionSet explicitly_allowed_permissions; // Reuses code for parsing API permissions from manifest. But note that we // only support list of strings type. if (!APIPermissionSet::ParseFromJSON( list_value, APIPermissionSet::kDisallowInternalPermissions, &explicitly_allowed_permissions, &error, nullptr)) { // There might be unknown permissions, warn and just ignore them; LOG(WARNING) << error; } APIPermissionSet::Difference(globally_blocked_permissions, explicitly_allowed_permissions, &blocked_permissions); } // Then add all newly blocked permissions to the list. if (dict->GetListWithoutPathExpansion(schema_constants::kBlockedPermissions, &list_value)) { // The |blocked_permissions| might be the result of the routines above, // or remains the same as default block permissions settings. APIPermissionSet permissions_to_merge_from = blocked_permissions; APIPermissionSet permissions_parsed; if (!APIPermissionSet::ParseFromJSON( list_value, APIPermissionSet::kDisallowInternalPermissions, &permissions_parsed, &error, nullptr)) { LOG(WARNING) << error; } APIPermissionSet::Union( permissions_to_merge_from, permissions_parsed, &blocked_permissions); } // Parses the minimum version settings. std::string minimum_version_required_str; if (scope == SCOPE_INDIVIDUAL && dict->GetStringWithoutPathExpansion( schema_constants::kMinimumVersionRequired, &minimum_version_required_str)) { scoped_ptr version( new Version(minimum_version_required_str)); // We accept a general version string here. Note that count of components in // version string of extensions is limited to 4. if (!version->IsValid()) LOG(WARNING) << kMalformedPreferenceWarning; else minimum_version_required = version.Pass(); } return true; } void IndividualSettings::Reset() { installation_mode = ExtensionManagement::INSTALLATION_ALLOWED; update_url.clear(); blocked_permissions.clear(); } GlobalSettings::GlobalSettings() { Reset(); } GlobalSettings::~GlobalSettings() { } void GlobalSettings::Reset() { has_restricted_install_sources = false; install_sources.ClearPatterns(); has_restricted_allowed_types = false; allowed_types.clear(); } } // namespace internal } // namespace extensions