summaryrefslogtreecommitdiffstats
path: root/extensions
diff options
context:
space:
mode:
authorderat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-08 09:39:47 +0000
committerderat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-08 09:39:47 +0000
commit1ff3fac6be85e0382e9e0362df12464afb0fc2d3 (patch)
tree6a0cec570976bed89c557c62a3d0301dd6fdf181 /extensions
parent665d1d57eff29f1757e16e3891464d6cb5532e22 (diff)
downloadchromium_src-1ff3fac6be85e0382e9e0362df12464afb0fc2d3.zip
chromium_src-1ff3fac6be85e0382e9e0362df12464afb0fc2d3.tar.gz
chromium_src-1ff3fac6be85e0382e9e0362df12464afb0fc2d3.tar.bz2
Move extensions::admin_policy code to extensions/browser.
Also temporarily permit inclusion of grit/generated_resources.h from within extensions/browser. (Longer-term, we'll want to move resources needed by extensions/ into their own file.) BUG=313284 Review URL: https://codereview.chromium.org/64643003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@233847 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'extensions')
-rw-r--r--extensions/browser/DEPS1
-rw-r--r--extensions/browser/admin_policy.cc121
-rw-r--r--extensions/browser/admin_policy.h42
-rw-r--r--extensions/browser/admin_policy_unittest.cc196
-rw-r--r--extensions/extensions.gyp3
5 files changed, 363 insertions, 0 deletions
diff --git a/extensions/browser/DEPS b/extensions/browser/DEPS
index 737b8eb..0f912bf 100644
--- a/extensions/browser/DEPS
+++ b/extensions/browser/DEPS
@@ -16,6 +16,7 @@ include_rules = [
"+chrome/common/extensions/background_info.h",
"+chrome/common/extensions/extension.h",
"+chrome/common/extensions/extension_messages.h",
+ "+grit/generated_resources.h",
]
specific_include_rules = {
diff --git a/extensions/browser/admin_policy.cc b/extensions/browser/admin_policy.cc
new file mode 100644
index 0000000..2cc0b57
--- /dev/null
+++ b/extensions/browser/admin_policy.cc
@@ -0,0 +1,121 @@
+// Copyright 2013 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 "extensions/browser/admin_policy.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/common/extensions/extension.h"
+#include "extensions/common/manifest.h"
+#include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace {
+
+bool ManagementPolicyImpl(const extensions::Extension* extension,
+ string16* error,
+ bool modifiable_value) {
+ bool modifiable =
+ extension->location() != extensions::Manifest::COMPONENT &&
+ !extensions::Manifest::IsPolicyLocation(extension->location());
+ // Some callers equate "no restriction" to true, others to false.
+ if (modifiable)
+ return modifiable_value;
+
+ if (error) {
+ *error = l10n_util::GetStringFUTF16(
+ IDS_EXTENSION_CANT_MODIFY_POLICY_REQUIRED,
+ UTF8ToUTF16(extension->name()));
+ }
+ return !modifiable_value;
+}
+
+bool ReturnLoadError(const extensions::Extension* extension, string16* error) {
+ if (error) {
+ *error = l10n_util::GetStringFUTF16(
+ IDS_EXTENSION_CANT_INSTALL_POLICY_BLOCKED,
+ UTF8ToUTF16(extension->name()),
+ UTF8ToUTF16(extension->id()));
+ }
+ return false;
+}
+
+} // namespace
+
+namespace extensions {
+namespace admin_policy {
+
+bool BlacklistedByDefault(const base::ListValue* blacklist) {
+ base::StringValue wildcard("*");
+ return blacklist && blacklist->Find(wildcard) != blacklist->end();
+}
+
+bool UserMayLoad(const base::ListValue* blacklist,
+ const base::ListValue* whitelist,
+ const base::DictionaryValue* forcelist,
+ const base::ListValue* allowed_types,
+ const Extension* extension,
+ string16* error) {
+ // Component extensions are always allowed.
+ if (extension->location() == Manifest::COMPONENT)
+ return true;
+
+ // Forced installed extensions cannot be overwritten manually.
+ if (extension->location() != Manifest::EXTERNAL_POLICY &&
+ extension->location() != Manifest::EXTERNAL_POLICY_DOWNLOAD &&
+ forcelist && forcelist->HasKey(extension->id())) {
+ return ReturnLoadError(extension, error);
+ }
+
+ // Early exit for the common case of no policy restrictions.
+ if ((!blacklist || blacklist->empty()) && (!allowed_types))
+ 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
+ // kExtensionAllowedTypesMap in configuration_policy_handler_list.cc.
+ 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:
+ base::FundamentalValue type_value(extension->GetType());
+ if (allowed_types &&
+ allowed_types->Find(type_value) == allowed_types->end())
+ return ReturnLoadError(extension, error);
+ break;
+ }
+
+ // Check the whitelist/forcelist first.
+ base::StringValue id_value(extension->id());
+ if ((whitelist && whitelist->Find(id_value) != whitelist->end()) ||
+ (forcelist && forcelist->HasKey(extension->id())))
+ return true;
+
+ // Then check the admin blacklist.
+ if ((blacklist && blacklist->Find(id_value) != blacklist->end()) ||
+ BlacklistedByDefault(blacklist))
+ return ReturnLoadError(extension, error);
+
+ return true;
+}
+
+bool UserMayModifySettings(const Extension* extension, string16* error) {
+ return ManagementPolicyImpl(extension, error, true);
+}
+
+bool MustRemainEnabled(const Extension* extension, string16* error) {
+ return ManagementPolicyImpl(extension, error, false);
+}
+
+} // namespace admin_policy
+} // namespace extensions
diff --git a/extensions/browser/admin_policy.h b/extensions/browser/admin_policy.h
new file mode 100644
index 0000000..ea32ee7
--- /dev/null
+++ b/extensions/browser/admin_policy.h
@@ -0,0 +1,42 @@
+// Copyright 2013 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 EXTENSIONS_BROWSER_ADMIN_POLICY_H_
+#define EXTENSIONS_BROWSER_ADMIN_POLICY_H_
+
+#include "base/values.h"
+
+namespace extensions {
+
+class Extension;
+
+// Functions for providing information about the extension whitelist,
+// blacklist, and forcelist imposed by admin policy.
+namespace admin_policy {
+
+// Checks if extensions are blacklisted by default, by policy. When true, this
+// means that even extensions without an ID should be blacklisted (e.g.
+// from the command line, or when loaded as an unpacked extension).
+bool BlacklistedByDefault(const base::ListValue* blacklist);
+
+// Returns true if the extension is allowed by the admin policy.
+bool UserMayLoad(const base::ListValue* blacklist,
+ const base::ListValue* whitelist,
+ const base::DictionaryValue* forcelist,
+ const base::ListValue* allowed_types,
+ const Extension* extension,
+ string16* error);
+
+// Returns false if the extension is required to remain running. In practice
+// this enforces the admin policy forcelist.
+bool UserMayModifySettings(const Extension* extension, string16* error);
+
+// Returns false if the extension is required to remain running. In practice
+// this enforces the admin policy forcelist.
+bool MustRemainEnabled(const Extension* extension, string16* error);
+
+} // namespace
+} // namespace
+
+#endif // EXTENSIONS_BROWSER_ADMIN_POLICY_H_
diff --git a/extensions/browser/admin_policy_unittest.cc b/extensions/browser/admin_policy_unittest.cc
new file mode 100644
index 0000000..02d606d
--- /dev/null
+++ b/extensions/browser/admin_policy_unittest.cc
@@ -0,0 +1,196 @@
+// Copyright 2013 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 "extensions/browser/admin_policy.h"
+
+#include "base/values.h"
+#include "chrome/common/extensions/extension.h"
+#include "extensions/common/manifest.h"
+#include "extensions/common/manifest_constants.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using base::Value;
+using extensions::Extension;
+using extensions::Manifest;
+
+namespace ap = extensions::admin_policy;
+
+class ExtensionAdminPolicyTest : public testing::Test {
+ public:
+ void CreateExtension(Manifest::Location location) {
+ base::DictionaryValue values;
+ CreateExtensionFromValues(location, &values);
+ }
+
+ void CreateHostedApp(Manifest::Location location) {
+ base::DictionaryValue values;
+ values.Set(extensions::manifest_keys::kWebURLs, new base::ListValue());
+ values.SetString(extensions::manifest_keys::kLaunchWebURL,
+ "http://www.example.com");
+ CreateExtensionFromValues(location, &values);
+ }
+
+ void CreateExtensionFromValues(Manifest::Location location,
+ base::DictionaryValue* values) {
+ values->SetString(extensions::manifest_keys::kName, "test");
+ values->SetString(extensions::manifest_keys::kVersion, "0.1");
+ std::string error;
+ extension_ = Extension::Create(base::FilePath(), location, *values,
+ Extension::NO_FLAGS, &error);
+ ASSERT_TRUE(extension_.get());
+ }
+
+ protected:
+ scoped_refptr<Extension> extension_;
+};
+
+// Tests the flag value indicating that extensions are blacklisted by default.
+TEST_F(ExtensionAdminPolicyTest, BlacklistedByDefault) {
+ EXPECT_FALSE(ap::BlacklistedByDefault(NULL));
+
+ base::ListValue blacklist;
+ blacklist.Append(new base::StringValue("http://www.google.com"));
+ EXPECT_FALSE(ap::BlacklistedByDefault(&blacklist));
+ blacklist.Append(new base::StringValue("*"));
+ EXPECT_TRUE(ap::BlacklistedByDefault(&blacklist));
+
+ blacklist.Clear();
+ blacklist.Append(new base::StringValue("*"));
+ EXPECT_TRUE(ap::BlacklistedByDefault(&blacklist));
+}
+
+// Tests UserMayLoad for required extensions.
+TEST_F(ExtensionAdminPolicyTest, UserMayLoadRequired) {
+ CreateExtension(Manifest::COMPONENT);
+ EXPECT_TRUE(ap::UserMayLoad(NULL, NULL, NULL, NULL, extension_.get(), NULL));
+ string16 error;
+ EXPECT_TRUE(ap::UserMayLoad(NULL, NULL, NULL, NULL, extension_.get(),
+ &error));
+ EXPECT_TRUE(error.empty());
+
+ // Required extensions may load even if they're on the blacklist.
+ base::ListValue blacklist;
+ blacklist.Append(new base::StringValue(extension_->id()));
+ EXPECT_TRUE(ap::UserMayLoad(&blacklist, NULL, NULL, NULL, extension_.get(),
+ NULL));
+
+ blacklist.Append(new base::StringValue("*"));
+ EXPECT_TRUE(ap::UserMayLoad(&blacklist, NULL, NULL, NULL, extension_.get(),
+ NULL));
+}
+
+// Tests UserMayLoad when no blacklist exists, or it's empty.
+TEST_F(ExtensionAdminPolicyTest, UserMayLoadNoBlacklist) {
+ CreateExtension(Manifest::INTERNAL);
+ EXPECT_TRUE(ap::UserMayLoad(NULL, NULL, NULL, NULL, extension_.get(), NULL));
+ base::ListValue blacklist;
+ EXPECT_TRUE(ap::UserMayLoad(&blacklist, NULL, NULL, NULL, extension_.get(),
+ NULL));
+ string16 error;
+ EXPECT_TRUE(ap::UserMayLoad(&blacklist, NULL, NULL, NULL, extension_.get(),
+ &error));
+ EXPECT_TRUE(error.empty());
+}
+
+// Tests UserMayLoad for an extension on the whitelist.
+TEST_F(ExtensionAdminPolicyTest, UserMayLoadWhitelisted) {
+ CreateExtension(Manifest::INTERNAL);
+
+ base::ListValue whitelist;
+ whitelist.Append(new base::StringValue(extension_->id()));
+ EXPECT_TRUE(ap::UserMayLoad(NULL, &whitelist, NULL, NULL, extension_.get(),
+ NULL));
+
+ base::ListValue blacklist;
+ blacklist.Append(new base::StringValue(extension_->id()));
+ EXPECT_TRUE(ap::UserMayLoad(NULL, &whitelist, NULL, NULL, extension_.get(),
+ NULL));
+ string16 error;
+ EXPECT_TRUE(ap::UserMayLoad(NULL, &whitelist, NULL, NULL, extension_.get(),
+ &error));
+ EXPECT_TRUE(error.empty());
+}
+
+// Tests UserMayLoad for an extension on the blacklist.
+TEST_F(ExtensionAdminPolicyTest, UserMayLoadBlacklisted) {
+ CreateExtension(Manifest::INTERNAL);
+
+ // Blacklisted by default.
+ base::ListValue blacklist;
+ blacklist.Append(new base::StringValue("*"));
+ EXPECT_FALSE(ap::UserMayLoad(&blacklist, NULL, NULL, NULL, extension_.get(),
+ NULL));
+ string16 error;
+ EXPECT_FALSE(ap::UserMayLoad(&blacklist, NULL, NULL, NULL, extension_.get(),
+ &error));
+ EXPECT_FALSE(error.empty());
+
+ // Extension on the blacklist, with and without wildcard.
+ blacklist.Append(new base::StringValue(extension_->id()));
+ EXPECT_FALSE(ap::UserMayLoad(&blacklist, NULL, NULL, NULL, extension_.get(),
+ NULL));
+ blacklist.Clear();
+ blacklist.Append(new base::StringValue(extension_->id()));
+ EXPECT_FALSE(ap::UserMayLoad(&blacklist, NULL, NULL, NULL, extension_.get(),
+ NULL));
+
+ // With a whitelist. There's no such thing as a whitelist wildcard.
+ base::ListValue whitelist;
+ whitelist.Append(
+ new base::StringValue("behllobkkfkfnphdnhnkndlbkcpglgmj"));
+ EXPECT_FALSE(ap::UserMayLoad(&blacklist, &whitelist, NULL, NULL,
+ extension_.get(), NULL));
+ whitelist.Append(new base::StringValue("*"));
+ EXPECT_FALSE(ap::UserMayLoad(&blacklist, &whitelist, NULL, NULL,
+ extension_.get(), NULL));
+}
+
+TEST_F(ExtensionAdminPolicyTest, UserMayLoadAllowedTypes) {
+ CreateExtension(Manifest::INTERNAL);
+ EXPECT_TRUE(ap::UserMayLoad(NULL, NULL, NULL, NULL, extension_.get(), NULL));
+
+ base::ListValue allowed_types;
+ EXPECT_FALSE(ap::UserMayLoad(NULL, NULL, NULL, &allowed_types,
+ extension_.get(), NULL));
+
+ allowed_types.AppendInteger(Manifest::TYPE_EXTENSION);
+ EXPECT_TRUE(ap::UserMayLoad(NULL, NULL, NULL, &allowed_types,
+ extension_.get(), NULL));
+
+ CreateHostedApp(Manifest::INTERNAL);
+ EXPECT_FALSE(ap::UserMayLoad(NULL, NULL, NULL, &allowed_types,
+ extension_.get(), NULL));
+
+ CreateHostedApp(Manifest::EXTERNAL_POLICY_DOWNLOAD);
+ EXPECT_FALSE(ap::UserMayLoad(NULL, NULL, NULL, &allowed_types,
+ extension_.get(), NULL));
+}
+
+TEST_F(ExtensionAdminPolicyTest, UserMayModifySettings) {
+ CreateExtension(Manifest::INTERNAL);
+ EXPECT_TRUE(ap::UserMayModifySettings(extension_.get(), NULL));
+ string16 error;
+ EXPECT_TRUE(ap::UserMayModifySettings(extension_.get(), &error));
+ EXPECT_TRUE(error.empty());
+
+ CreateExtension(Manifest::EXTERNAL_POLICY_DOWNLOAD);
+ error.clear();
+ EXPECT_FALSE(ap::UserMayModifySettings(extension_.get(), NULL));
+ EXPECT_FALSE(ap::UserMayModifySettings(extension_.get(), &error));
+ EXPECT_FALSE(error.empty());
+}
+
+TEST_F(ExtensionAdminPolicyTest, MustRemainEnabled) {
+ CreateExtension(Manifest::EXTERNAL_POLICY_DOWNLOAD);
+ EXPECT_TRUE(ap::MustRemainEnabled(extension_.get(), NULL));
+ string16 error;
+ EXPECT_TRUE(ap::MustRemainEnabled(extension_.get(), &error));
+ EXPECT_FALSE(error.empty());
+
+ CreateExtension(Manifest::INTERNAL);
+ error.clear();
+ EXPECT_FALSE(ap::MustRemainEnabled(extension_.get(), NULL));
+ EXPECT_FALSE(ap::MustRemainEnabled(extension_.get(), &error));
+ EXPECT_TRUE(error.empty());
+}
diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp
index 98d502d..6cef0ee 100644
--- a/extensions/extensions.gyp
+++ b/extensions/extensions.gyp
@@ -130,8 +130,11 @@
'include_dirs': [
'..',
'<(INTERMEDIATE_DIR)',
+ '<(SHARED_INTERMEDIATE_DIR)/chrome',
],
'sources': [
+ 'browser/admin_policy.cc',
+ 'browser/admin_policy.h',
'browser/extension_prefs_scope.h',
'browser/extension_error.cc',
'browser/extension_error.h',