blob: a4e370858fb5b60e0ea8d6d72e3c4f369fb1b88d [file] [log] [blame]
// Copyright 2012 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/standard_management_policy_provider.h"
#include <string>
#include "base/logging.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/extension_management.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest.h"
#include "extensions/strings/grit/extensions_strings.h"
#include "ui/base/l10n/l10n_util.h"
namespace extensions {
namespace {
// Returns whether the extension can be modified under admin policy or not, and
// fills |error| with corresponding error message if necessary.
bool AdminPolicyIsModifiable(const Extension* source_extension,
const Extension* extension,
base::string16* error) {
// Component and force installed extensions can enable/disable all other
// extensions including force installed ones (but component are off limits).
const bool component_or_force_installed =
source_extension &&
(Manifest::IsComponentLocation(source_extension->location()) ||
Manifest::IsPolicyLocation(source_extension->location()));
bool is_modifiable = true;
if (Manifest::IsComponentLocation(extension->location()))
is_modifiable = false;
if (!component_or_force_installed &&
Manifest::IsPolicyLocation(extension->location())) {
is_modifiable = false;
}
if (is_modifiable)
return true;
if (error) {
*error = l10n_util::GetStringFUTF16(
IDS_EXTENSION_CANT_MODIFY_POLICY_REQUIRED,
base::UTF8ToUTF16(extension->name()));
}
return false;
}
} // namespace
StandardManagementPolicyProvider::StandardManagementPolicyProvider(
const ExtensionManagement* settings)
: settings_(settings) {
}
StandardManagementPolicyProvider::~StandardManagementPolicyProvider() {
}
std::string
StandardManagementPolicyProvider::GetDebugPolicyProviderName() const {
#if DCHECK_IS_ON()
return "extension management policy controlled settings";
#else
IMMEDIATE_CRASH();
#endif
}
bool StandardManagementPolicyProvider::UserMayLoad(
const Extension* extension,
base::string16* error) const {
// Component extensions are always allowed.
if (Manifest::IsComponentLocation(extension->location()))
return true;
// Shared modules are always allowed too: they only contain resources that
// are used by other extensions. The extension that depends on the shared
// module may be filtered by policy.
if (extension->is_shared_module())
return true;
// Always allow bookmark apps. The fact that bookmark apps are an extension is
// an internal implementation detail and hence they should not be controlled
// by extension management policies. See crbug.com/786061.
// TODO(calamity): This special case should be removed by removing bookmark
// apps from external sources. See crbug.com/788245.
if (extension->from_bookmark())
return true;
// Check whether the extension type is allowed.
//
// If you get a compile error here saying that the type you added is not
// handled by the switch statement below, please consider whether enterprise
// policy should be able to disallow extensions of the new type. If so, add
// a branch to the second block and add a line to the definition of
// kAllowedTypesMap in extension_management_constants.h.
switch (extension->GetType()) {
case Manifest::TYPE_UNKNOWN:
break;
case Manifest::TYPE_EXTENSION:
case Manifest::TYPE_THEME:
case Manifest::TYPE_USER_SCRIPT:
case Manifest::TYPE_HOSTED_APP:
case Manifest::TYPE_LEGACY_PACKAGED_APP:
case Manifest::TYPE_PLATFORM_APP:
case Manifest::TYPE_SHARED_MODULE: {
if (!settings_->IsAllowedManifestType(extension->GetType(),
extension->id()))
return ReturnLoadError(extension, error);
break;
}
case Manifest::NUM_LOAD_TYPES:
NOTREACHED();
}
ExtensionManagement::InstallationMode installation_mode =
settings_->GetInstallationMode(extension);
if (installation_mode == ExtensionManagement::INSTALLATION_BLOCKED)
return ReturnLoadError(extension, error);
return true;
}
bool StandardManagementPolicyProvider::UserMayInstall(
const Extension* extension,
base::string16* error) const {
ExtensionManagement::InstallationMode installation_mode =
settings_->GetInstallationMode(extension);
// Force-installed extensions cannot be overwritten manually.
if (!Manifest::IsPolicyLocation(extension->location()) &&
installation_mode == ExtensionManagement::INSTALLATION_FORCED) {
return ReturnLoadError(extension, error);
}
return UserMayLoad(extension, error);
}
bool StandardManagementPolicyProvider::UserMayModifySettings(
const Extension* extension,
base::string16* error) const {
return AdminPolicyIsModifiable(nullptr, extension, error);
}
bool StandardManagementPolicyProvider::ExtensionMayModifySettings(
const Extension* source_extension,
const Extension* extension,
base::string16* error) const {
return AdminPolicyIsModifiable(source_extension, extension, error);
}
bool StandardManagementPolicyProvider::MustRemainEnabled(
const Extension* extension,
base::string16* error) const {
return !AdminPolicyIsModifiable(nullptr, extension, error);
}
bool StandardManagementPolicyProvider::MustRemainDisabled(
const Extension* extension,
disable_reason::DisableReason* reason,
base::string16* error) const {
std::string required_version;
if (!settings_->CheckMinimumVersion(extension, &required_version)) {
if (reason)
*reason = disable_reason::DISABLE_UPDATE_REQUIRED_BY_POLICY;
if (error) {
*error = l10n_util::GetStringFUTF16(
IDS_EXTENSION_DISABLED_UPDATE_REQUIRED_BY_POLICY,
base::UTF8ToUTF16(extension->name()),
base::ASCIIToUTF16(required_version));
}
return true;
}
return false;
}
bool StandardManagementPolicyProvider::MustRemainInstalled(
const Extension* extension,
base::string16* error) const {
ExtensionManagement::InstallationMode mode =
settings_->GetInstallationMode(extension);
// Disallow removing of recommended extension, to avoid re-install it
// again while policy is reload. But disabling of recommended extension is
// allowed.
if (mode == ExtensionManagement::INSTALLATION_FORCED ||
mode == ExtensionManagement::INSTALLATION_RECOMMENDED) {
if (error) {
*error = l10n_util::GetStringFUTF16(
IDS_EXTENSION_CANT_UNINSTALL_POLICY_REQUIRED,
base::UTF8ToUTF16(extension->name()));
}
return true;
}
return false;
}
bool StandardManagementPolicyProvider::ReturnLoadError(
const extensions::Extension* extension,
base::string16* error) const {
if (error) {
*error = l10n_util::GetStringFUTF16(
IDS_EXTENSION_CANT_INSTALL_POLICY_BLOCKED,
base::UTF8ToUTF16(extension->name()),
base::UTF8ToUTF16(extension->id()),
base::UTF8ToUTF16(settings_->BlockedInstallMessage(extension->id())));
}
return false;
}
} // namespace extensions