summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjoaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-25 13:19:08 +0000
committerjoaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-25 13:19:08 +0000
commitbad38cb105657bee72df7f78bb44e9e75f9ec18c (patch)
treef631962771627a5e696a888280d03d05c22a36ad
parent42887efa99e289a175fb019ae96bffada8118cdd (diff)
downloadchromium_src-bad38cb105657bee72df7f78bb44e9e75f9ec18c.zip
chromium_src-bad38cb105657bee72df7f78bb44e9e75f9ec18c.tar.gz
chromium_src-bad38cb105657bee72df7f78bb44e9e75f9ec18c.tar.bz2
Refactored users of PolicySchema to use the new policy::Schema class.
PolicySchema was used to contain the JSON schema describing the valid values for each known policy. This is now done by the policy::Schema class, which supports loading the Chrome policy schema at startup without having to parse a JSON blob. BUG=270667 R=bartfab@chromium.org, dubroy@chromium.org, joi@chromium.org, kalman@chromium.org Review URL: https://codereview.chromium.org/24367003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@225181 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/api/storage/managed_value_store_cache.cc8
-rw-r--r--chrome/browser/policy/cloud/component_cloud_policy_service_unittest.cc7
-rw-r--r--chrome/browser/policy/policy_domain_descriptor.cc27
-rw-r--r--chrome/browser/policy/policy_domain_descriptor.h12
-rw-r--r--chrome/browser/policy/policy_domain_descriptor_unittest.cc74
-rw-r--r--chrome/browser/policy/policy_loader_mac.cc28
-rw-r--r--chrome/browser/policy/policy_loader_mac.h4
-rw-r--r--chrome/browser/policy/policy_service_impl_unittest.cc5
-rw-r--r--chrome/browser/ui/webui/policy_ui.cc12
-rw-r--r--chrome/common/extensions/api/storage/storage_schema_manifest_handler.cc14
-rw-r--r--chrome/common/extensions/api/storage/storage_schema_manifest_handler.h6
-rw-r--r--components/components_tests.gypi1
-rw-r--r--components/policy.gypi2
-rw-r--r--components/policy/core/common/policy_schema.cc244
-rw-r--r--components/policy/core/common/policy_schema.h70
-rw-r--r--components/policy/core/common/policy_schema_unittest.cc193
-rw-r--r--components/policy/core/common/schema.cc4
-rw-r--r--components/policy/core/common/schema.h7
18 files changed, 140 insertions, 578 deletions
diff --git a/chrome/browser/extensions/api/storage/managed_value_store_cache.cc b/chrome/browser/extensions/api/storage/managed_value_store_cache.cc
index 13a5fde..9301bda 100644
--- a/chrome/browser/extensions/api/storage/managed_value_store_cache.cc
+++ b/chrome/browser/extensions/api/storage/managed_value_store_cache.cc
@@ -27,7 +27,7 @@
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_set.h"
#include "chrome/common/extensions/permissions/api_permission.h"
-#include "components/policy/core/common/policy_schema.h"
+#include "components/policy/core/common/schema.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
@@ -137,10 +137,10 @@ void ManagedValueStoreCache::ExtensionTracker::LoadSchemas(
std::string schema_file;
if (!(*it)->manifest()->GetString(
manifest_keys::kStorageManagedSchema, &schema_file)) {
- // TODO(joaodasilva): Remove this for M30. http://crbug.com/240704
+ // TODO(joaodasilva): Remove this for M32. http://crbug.com/240704
if ((*it)->HasAPIPermission(APIPermission::kStorage)) {
descriptor->RegisterComponent((*it)->id(),
- scoped_ptr<policy::PolicySchema>());
+ scoped_ptr<policy::SchemaOwner>());
} else {
NOTREACHED();
}
@@ -149,7 +149,7 @@ void ManagedValueStoreCache::ExtensionTracker::LoadSchemas(
// The extension should have been validated, so assume the schema exists
// and is valid.
std::string error;
- scoped_ptr<policy::PolicySchema> schema =
+ scoped_ptr<policy::SchemaOwner> schema =
StorageSchemaManifestHandler::GetSchema(it->get(), &error);
CHECK(schema) << error;
descriptor->RegisterComponent((*it)->id(), schema.Pass());
diff --git a/chrome/browser/policy/cloud/component_cloud_policy_service_unittest.cc b/chrome/browser/policy/cloud/component_cloud_policy_service_unittest.cc
index d01b453..b29d8b6 100644
--- a/chrome/browser/policy/cloud/component_cloud_policy_service_unittest.cc
+++ b/chrome/browser/policy/cloud/component_cloud_policy_service_unittest.cc
@@ -24,7 +24,7 @@
#include "chrome/browser/policy/policy_types.h"
#include "chrome/browser/policy/proto/cloud/chrome_extension_policy.pb.h"
#include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
-#include "components/policy/core/common/policy_schema.h"
+#include "components/policy/core/common/schema.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread.h"
#include "net/url_request/test_url_fetcher_factory.h"
@@ -61,7 +61,6 @@ const char kTestPolicy[] =
const char kTestSchema[] =
"{"
- " \"$schema\": \"http://json-schema.org/draft-03/schema#\","
" \"type\": \"object\","
" \"properties\": {"
" \"Name\": { \"type\": \"string\" },"
@@ -194,9 +193,9 @@ class ComponentCloudPolicyServiceTest : public testing::Test {
return builder_.GetBlob();
}
- scoped_ptr<PolicySchema> CreateTestSchema() {
+ scoped_ptr<SchemaOwner> CreateTestSchema() {
std::string error;
- scoped_ptr<PolicySchema> schema = PolicySchema::Parse(kTestSchema, &error);
+ scoped_ptr<SchemaOwner> schema = SchemaOwner::Parse(kTestSchema, &error);
EXPECT_TRUE(schema) << error;
return schema.Pass();
}
diff --git a/chrome/browser/policy/policy_domain_descriptor.cc b/chrome/browser/policy/policy_domain_descriptor.cc
index c841a55..f054710 100644
--- a/chrome/browser/policy/policy_domain_descriptor.cc
+++ b/chrome/browser/policy/policy_domain_descriptor.cc
@@ -9,19 +9,18 @@
#include "base/values.h"
#include "chrome/browser/policy/policy_bundle.h"
#include "chrome/browser/policy/policy_map.h"
-#include "components/policy/core/common/policy_schema.h"
namespace policy {
namespace {
-bool Matches(const PolicySchema* schema, const base::Value& value) {
- if (!schema) {
+bool Matches(Schema schema, const base::Value& value) {
+ if (!schema.valid()) {
// Schema not found, invalid entry.
return false;
}
- if (!value.IsType(schema->type()))
+ if (!value.IsType(schema.type()))
return false;
const base::DictionaryValue* dict = NULL;
@@ -29,13 +28,13 @@ bool Matches(const PolicySchema* schema, const base::Value& value) {
if (value.GetAsDictionary(&dict)) {
for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
it.Advance()) {
- if (!Matches(schema->GetSchemaForProperty(it.key()), it.value()))
+ if (!Matches(schema.GetProperty(it.key()), it.value()))
return false;
}
} else if (value.GetAsList(&list)) {
for (base::ListValue::const_iterator it = list->begin();
it != list->end(); ++it) {
- if (!*it || !Matches(schema->GetSchemaForItems(), **it))
+ if (!*it || !Matches(schema.GetItems(), **it))
return false;
}
}
@@ -50,10 +49,11 @@ PolicyDomainDescriptor::PolicyDomainDescriptor(PolicyDomain domain)
void PolicyDomainDescriptor::RegisterComponent(
const std::string& component_id,
- scoped_ptr<PolicySchema> schema) {
- const PolicySchema*& entry = schema_map_[component_id];
+ scoped_ptr<SchemaOwner> schema) {
+ SchemaOwner*& entry = schema_owner_map_[component_id];
delete entry;
entry = schema.release();
+ schema_map_[component_id] = entry ? entry->schema() : Schema();
}
void PolicyDomainDescriptor::FilterBundle(PolicyBundle* bundle) const {
@@ -76,18 +76,17 @@ void PolicyDomainDescriptor::FilterBundle(PolicyBundle* bundle) const {
// TODO(joaodasilva): if a component is registered but doesn't have a schema
// then its policies aren't filtered. This behavior is enabled for M29 to
// allow a graceful update of the Legacy Browser Support extension; it'll
- // be removed for M30. http://crbug.com/240704
- if (!it_schema->second)
+ // be removed for M32. http://crbug.com/240704
+ Schema schema = it_schema->second;
+ if (!schema.valid())
continue;
- const PolicySchema* component_schema = it_schema->second;
PolicyMap* map = it_bundle->second;
for (PolicyMap::const_iterator it_map = map->begin();
it_map != map->end();) {
const std::string& policy_name = it_map->first;
const base::Value* policy_value = it_map->second.value;
- const PolicySchema* policy_schema =
- component_schema->GetSchemaForProperty(policy_name);
+ Schema policy_schema = schema.GetProperty(policy_name);
++it_map;
if (!policy_value || !Matches(policy_schema, *policy_value))
map->Erase(policy_name);
@@ -96,7 +95,7 @@ void PolicyDomainDescriptor::FilterBundle(PolicyBundle* bundle) const {
}
PolicyDomainDescriptor::~PolicyDomainDescriptor() {
- STLDeleteValues(&schema_map_);
+ STLDeleteValues(&schema_owner_map_);
}
} // namespace policy
diff --git a/chrome/browser/policy/policy_domain_descriptor.h b/chrome/browser/policy/policy_domain_descriptor.h
index daa3d56..2106633 100644
--- a/chrome/browser/policy/policy_domain_descriptor.h
+++ b/chrome/browser/policy/policy_domain_descriptor.h
@@ -12,18 +12,18 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/policy/policy_service.h"
+#include "components/policy/core/common/schema.h"
namespace policy {
class PolicyBundle;
-class PolicySchema;
// For each policy domain, this class keeps the complete list of valid
-// components for that domain, and the PolicySchema for each component.
+// components for that domain, and the Schema for each component.
class PolicyDomainDescriptor
: public base::RefCountedThreadSafe<PolicyDomainDescriptor> {
public:
- typedef std::map<std::string, const PolicySchema*> SchemaMap;
+ typedef std::map<std::string, Schema> SchemaMap;
explicit PolicyDomainDescriptor(PolicyDomain domain);
@@ -34,17 +34,21 @@ class PolicyDomainDescriptor
// |schema|. This registration overrides any previously set schema for this
// component.
void RegisterComponent(const std::string& component_id,
- scoped_ptr<PolicySchema> schema);
+ scoped_ptr<SchemaOwner> schema);
// Removes all the policies in |bundle| that don't match this descriptor.
// Policies of domains other than |domain_| are ignored.
void FilterBundle(PolicyBundle* bundle) const;
private:
+ typedef std::map<std::string, SchemaOwner*> SchemaOwnerMap;
+
friend class base::RefCountedThreadSafe<PolicyDomainDescriptor>;
+
~PolicyDomainDescriptor();
PolicyDomain domain_;
+ SchemaOwnerMap schema_owner_map_;
SchemaMap schema_map_;
DISALLOW_COPY_AND_ASSIGN(PolicyDomainDescriptor);
diff --git a/chrome/browser/policy/policy_domain_descriptor_unittest.cc b/chrome/browser/policy/policy_domain_descriptor_unittest.cc
index 9a03f8e..4ef89fc 100644
--- a/chrome/browser/policy/policy_domain_descriptor_unittest.cc
+++ b/chrome/browser/policy/policy_domain_descriptor_unittest.cc
@@ -13,7 +13,6 @@
#include "chrome/browser/policy/external_data_manager.h"
#include "chrome/browser/policy/policy_bundle.h"
#include "chrome/browser/policy/policy_map.h"
-#include "components/policy/core/common/policy_schema.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace policy {
@@ -37,9 +36,8 @@ TEST_F(PolicyDomainDescriptorTest, FilterBundle) {
EXPECT_TRUE(descriptor->components().empty());
std::string error;
- scoped_ptr<PolicySchema> schema = PolicySchema::Parse(
+ scoped_ptr<SchemaOwner> schema = SchemaOwner::Parse(
"{"
- " \"$schema\":\"http://json-schema.org/draft-03/schema#\","
" \"type\":\"object\","
" \"properties\": {"
" \"Array\": {"
@@ -147,4 +145,74 @@ TEST_F(PolicyDomainDescriptorTest, FilterBundle) {
EXPECT_TRUE(bundle.Equals(empty_bundle));
}
+TEST_F(PolicyDomainDescriptorTest, LegacyComponents) {
+ scoped_refptr<PolicyDomainDescriptor> descriptor =
+ new PolicyDomainDescriptor(POLICY_DOMAIN_EXTENSIONS);
+ EXPECT_EQ(POLICY_DOMAIN_EXTENSIONS, descriptor->domain());
+ EXPECT_TRUE(descriptor->components().empty());
+
+ std::string error;
+ scoped_ptr<SchemaOwner> schema = SchemaOwner::Parse(
+ "{"
+ " \"type\":\"object\","
+ " \"properties\": {"
+ " \"String\": { \"type\": \"string\" }"
+ " }"
+ "}", &error);
+ ASSERT_TRUE(schema) << error;
+
+ descriptor->RegisterComponent("with-schema", schema.Pass());
+ descriptor->RegisterComponent("without-schema", scoped_ptr<SchemaOwner>());
+
+ EXPECT_EQ(2u, descriptor->components().size());
+
+ // |bundle| contains policies loaded by a policy provider.
+ PolicyBundle bundle;
+
+ // Known components with schemas are filtered.
+ PolicyNamespace extension_ns(POLICY_DOMAIN_EXTENSIONS, "with-schema");
+ bundle.Get(extension_ns).Set("String",
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER,
+ base::Value::CreateStringValue("value 1"),
+ NULL);
+
+ // Known components without a schema are not filtered.
+ PolicyNamespace without_schema_ns(POLICY_DOMAIN_EXTENSIONS, "without-schema");
+ bundle.Get(without_schema_ns).Set("Schemaless",
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER,
+ base::Value::CreateStringValue("value 2"),
+ NULL);
+
+ // Other namespaces aren't filtered.
+ PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, "");
+ bundle.Get(chrome_ns).Set("ChromePolicy",
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER,
+ base::Value::CreateStringValue("value 3"),
+ NULL);
+
+ PolicyBundle expected_bundle;
+ expected_bundle.MergeFrom(bundle);
+
+ // Unknown policies of known components with a schema are removed.
+ bundle.Get(extension_ns).Set("Surprise",
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER,
+ base::Value::CreateStringValue("value 4"),
+ NULL);
+
+ // Unknown components are removed.
+ PolicyNamespace unknown_ns(POLICY_DOMAIN_EXTENSIONS, "unknown");
+ bundle.Get(unknown_ns).Set("Surprise",
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER,
+ base::Value::CreateStringValue("value 5"),
+ NULL);
+
+ descriptor->FilterBundle(&bundle);
+ EXPECT_TRUE(bundle.Equals(expected_bundle));
+}
+
} // namespace policy
diff --git a/chrome/browser/policy/policy_loader_mac.cc b/chrome/browser/policy/policy_loader_mac.cc
index 29774f0..2d8e220 100644
--- a/chrome/browser/policy/policy_loader_mac.cc
+++ b/chrome/browser/policy/policy_loader_mac.cc
@@ -21,7 +21,7 @@
#include "chrome/browser/policy/policy_load_status.h"
#include "chrome/browser/policy/policy_map.h"
#include "chrome/browser/policy/preferences_mac.h"
-#include "components/policy/core/common/policy_schema.h"
+#include "components/policy/core/common/schema.h"
#include "policy/policy_constants.h"
using base::mac::CFCast;
@@ -210,29 +210,22 @@ void PolicyLoaderMac::LoadPolicyForDomain(
void PolicyLoaderMac::LoadPolicyForComponent(
const std::string& bundle_id_string,
- const PolicySchema* schema,
+ Schema schema,
PolicyMap* policy) {
// TODO(joaodasilva): extensions may be registered in a PolicyDomainDescriptor
- // without a PolicySchema, to allow a graceful update of the Legacy Browser
- // Support extension on Windows. Remove this temporary check once that support
- // is removed.
- if (!schema)
+ // without a schema, to allow a graceful update of the Legacy Browser Support
+ // extension on Windows. Remove this check once that support is removed.
+ if (!schema.valid())
return;
base::ScopedCFTypeRef<CFStringRef> bundle_id(
base::SysUTF8ToCFStringRef(bundle_id_string));
preferences_->AppSynchronize(bundle_id);
- const PolicySchemaMap* map = schema->GetProperties();
- if (!map) {
- NOTREACHED();
- return;
- }
-
- for (PolicySchemaMap::const_iterator it = map->begin();
- it != map->end(); ++it) {
+ for (Schema::Iterator it = schema.GetPropertiesIterator();
+ !it.IsAtEnd(); it.Advance()) {
base::ScopedCFTypeRef<CFStringRef> pref_name(
- base::SysUTF8ToCFStringRef(it->first));
+ base::SysUTF8ToCFStringRef(it.key()));
base::ScopedCFTypeRef<CFPropertyListRef> value(
preferences_->CopyAppValue(pref_name, bundle_id));
if (!value.get())
@@ -242,9 +235,10 @@ void PolicyLoaderMac::LoadPolicyForComponent(
PolicyLevel level = forced ? POLICY_LEVEL_MANDATORY :
POLICY_LEVEL_RECOMMENDED;
scoped_ptr<base::Value> policy_value(CreateValueFromProperty(value));
- if (policy_value)
- policy->Set(it->first, level, POLICY_SCOPE_USER,
+ if (policy_value) {
+ policy->Set(it.key(), level, POLICY_SCOPE_USER,
policy_value.release(), NULL);
+ }
}
}
diff --git a/chrome/browser/policy/policy_loader_mac.h b/chrome/browser/policy/policy_loader_mac.h
index 104ec90..68da9e4 100644
--- a/chrome/browser/policy/policy_loader_mac.h
+++ b/chrome/browser/policy/policy_loader_mac.h
@@ -25,7 +25,7 @@ namespace policy {
class PolicyDomainDescriptor;
class PolicyMap;
-class PolicySchema;
+class Schema;
struct PolicyDefinitionList;
// A policy loader that loads policies from the Mac preferences system, and
@@ -63,7 +63,7 @@ class PolicyLoaderMac : public AsyncPolicyLoader {
// Loads the policies described in |schema| from the bundle identified by
// |bundle_id_string|, and stores them in |policy|.
void LoadPolicyForComponent(const std::string& bundle_id_string,
- const PolicySchema* schema,
+ Schema schema,
PolicyMap* policy);
// List of recognized policies.
diff --git a/chrome/browser/policy/policy_service_impl_unittest.cc b/chrome/browser/policy/policy_service_impl_unittest.cc
index c34cb2b..c7854d5 100644
--- a/chrome/browser/policy/policy_service_impl_unittest.cc
+++ b/chrome/browser/policy/policy_service_impl_unittest.cc
@@ -15,7 +15,7 @@
#include "chrome/browser/policy/mock_configuration_policy_provider.h"
#include "chrome/browser/policy/mock_policy_service.h"
#include "chrome/browser/policy/policy_domain_descriptor.h"
-#include "components/policy/core/common/policy_schema.h"
+#include "components/policy/core/common/schema.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -627,9 +627,8 @@ TEST_F(PolicyServiceTest, RegisterPolicyDomain) {
// Register another namespace.
std::string error;
- scoped_ptr<PolicySchema> schema = PolicySchema::Parse(
+ scoped_ptr<SchemaOwner> schema = SchemaOwner::Parse(
"{"
- " \"$schema\":\"http://json-schema.org/draft-03/schema#\","
" \"type\":\"object\","
" \"properties\": {"
" \"Boolean\": { \"type\": \"boolean\" },"
diff --git a/chrome/browser/ui/webui/policy_ui.cc b/chrome/browser/ui/webui/policy_ui.cc
index fa9ed74..7e00861 100644
--- a/chrome/browser/ui/webui/policy_ui.cc
+++ b/chrome/browser/ui/webui/policy_ui.cc
@@ -64,7 +64,7 @@
#include "chrome/browser/policy/policy_domain_descriptor.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_set.h"
-#include "components/policy/core/common/policy_schema.h"
+#include "components/policy/core/common/schema.h"
#include "extensions/common/manifest.h"
#include "extensions/common/manifest_constants.h"
#endif
@@ -579,11 +579,11 @@ void PolicyUIHandler::SendPolicyNames() const {
if (schema != schema_map.end()) {
// Get policy names from the extension's policy schema.
// Store in a map, not an array, for faster lookup on JS side.
- const policy::PolicySchemaMap* policies = schema->second->GetProperties();
- policy::PolicySchemaMap::const_iterator it_policies;
- for (it_policies = policies->begin(); it_policies != policies->end();
- ++it_policies) {
- policy_names->SetBoolean(it_policies->first, true);
+ policy::Schema policy_schema = schema->second;
+ for (policy::Schema::Iterator it_policies =
+ policy_schema.GetPropertiesIterator();
+ !it_policies.IsAtEnd(); it_policies.Advance()) {
+ policy_names->SetBoolean(it_policies.key(), true);
}
}
extension_value->Set("policyNames", policy_names);
diff --git a/chrome/common/extensions/api/storage/storage_schema_manifest_handler.cc b/chrome/common/extensions/api/storage/storage_schema_manifest_handler.cc
index 28c8557..d95a967 100644
--- a/chrome/common/extensions/api/storage/storage_schema_manifest_handler.cc
+++ b/chrome/common/extensions/api/storage/storage_schema_manifest_handler.cc
@@ -15,7 +15,7 @@
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/permissions/api_permission.h"
-#include "components/policy/core/common/policy_schema.h"
+#include "components/policy/core/common/schema.h"
#include "extensions/common/install_warning.h"
#include "extensions/common/manifest.h"
#include "extensions/common/manifest_constants.h"
@@ -29,13 +29,13 @@ StorageSchemaManifestHandler::StorageSchemaManifestHandler() {}
StorageSchemaManifestHandler::~StorageSchemaManifestHandler() {}
// static
-scoped_ptr<policy::PolicySchema> StorageSchemaManifestHandler::GetSchema(
+scoped_ptr<policy::SchemaOwner> StorageSchemaManifestHandler::GetSchema(
const Extension* extension,
std::string* error) {
if (!extension->HasAPIPermission(APIPermission::kStorage)) {
*error = base::StringPrintf("The storage permission is required to use %s",
kStorageManagedSchema);
- return scoped_ptr<policy::PolicySchema>();
+ return scoped_ptr<policy::SchemaOwner>();
}
std::string path;
extension->manifest()->GetString(kStorageManagedSchema, &path);
@@ -43,20 +43,20 @@ scoped_ptr<policy::PolicySchema> StorageSchemaManifestHandler::GetSchema(
if (file.IsAbsolute() || file.ReferencesParent()) {
*error = base::StringPrintf("%s must be a relative path without ..",
kStorageManagedSchema);
- return scoped_ptr<policy::PolicySchema>();
+ return scoped_ptr<policy::SchemaOwner>();
}
file = extension->path().AppendASCII(path);
if (!base::PathExists(file)) {
*error =
base::StringPrintf("File does not exist: %s", file.value().c_str());
- return scoped_ptr<policy::PolicySchema>();
+ return scoped_ptr<policy::SchemaOwner>();
}
std::string content;
if (!base::ReadFileToString(file, &content)) {
*error = base::StringPrintf("Can't read %s", file.value().c_str());
- return scoped_ptr<policy::PolicySchema>();
+ return scoped_ptr<policy::SchemaOwner>();
}
- return policy::PolicySchema::Parse(content, error);
+ return policy::SchemaOwner::Parse(content, error);
}
bool StorageSchemaManifestHandler::Parse(Extension* extension,
diff --git a/chrome/common/extensions/api/storage/storage_schema_manifest_handler.h b/chrome/common/extensions/api/storage/storage_schema_manifest_handler.h
index c988362..d2406d6 100644
--- a/chrome/common/extensions/api/storage/storage_schema_manifest_handler.h
+++ b/chrome/common/extensions/api/storage/storage_schema_manifest_handler.h
@@ -9,7 +9,7 @@
#include "chrome/common/extensions/manifest_handler.h"
namespace policy {
-class PolicySchema;
+class SchemaOwner;
}
namespace extensions {
@@ -24,8 +24,8 @@ class StorageSchemaManifestHandler : public ManifestHandler {
// If the schema is invalid then NULL is returned, and the failure reason
// is stored in |error|.
// This function does file I/O and must be called on a thread that allows I/O.
- static scoped_ptr<policy::PolicySchema> GetSchema(const Extension* extension,
- std::string* error);
+ static scoped_ptr<policy::SchemaOwner> GetSchema(const Extension* extension,
+ std::string* error);
private:
// ManifestHandler implementation:
diff --git a/components/components_tests.gypi b/components/components_tests.gypi
index 491e214..94b8700 100644
--- a/components/components_tests.gypi
+++ b/components/components_tests.gypi
@@ -116,7 +116,6 @@
}],
['configuration_policy==1', {
'sources': [
- 'policy/core/common/policy_schema_unittest.cc',
'policy/core/common/schema_unittest.cc',
],
}],
diff --git a/components/policy.gypi b/components/policy.gypi
index 7471212..8dd3bb1 100644
--- a/components/policy.gypi
+++ b/components/policy.gypi
@@ -22,8 +22,6 @@
'sources': [
'policy/core/common/policy_pref_names.cc',
'policy/core/common/policy_pref_names.h',
- 'policy/core/common/policy_schema.cc',
- 'policy/core/common/policy_schema.h',
'policy/core/common/schema.cc',
'policy/core/common/schema.h',
'policy/core/common/schema_internal.h',
diff --git a/components/policy/core/common/policy_schema.cc b/components/policy/core/common/policy_schema.cc
deleted file mode 100644
index 8c3145c..0000000
--- a/components/policy/core/common/policy_schema.cc
+++ /dev/null
@@ -1,244 +0,0 @@
-// 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 "components/policy/core/common/policy_schema.h"
-
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "base/stl_util.h"
-#include "components/json_schema/json_schema_constants.h"
-#include "components/json_schema/json_schema_validator.h"
-
-namespace policy {
-
-namespace {
-
-const char kJSONSchemaVersion[] = "http://json-schema.org/draft-03/schema#";
-
-// Describes the properties of a TYPE_DICTIONARY policy schema.
-class DictionaryPolicySchema : public PolicySchema {
- public:
- static scoped_ptr<PolicySchema> Parse(const base::DictionaryValue& schema,
- std::string* error);
-
- virtual ~DictionaryPolicySchema();
-
- virtual const PolicySchemaMap* GetProperties() const OVERRIDE;
- virtual const PolicySchema* GetSchemaForAdditionalProperties() const OVERRIDE;
-
- private:
- DictionaryPolicySchema();
-
- PolicySchemaMap properties_;
- scoped_ptr<PolicySchema> additional_properties_;
-
- DISALLOW_COPY_AND_ASSIGN(DictionaryPolicySchema);
-};
-
-// Describes the items of a TYPE_LIST policy schema.
-class ListPolicySchema : public PolicySchema {
- public:
- static scoped_ptr<PolicySchema> Parse(const base::DictionaryValue& schema,
- std::string* error);
-
- virtual ~ListPolicySchema();
-
- virtual const PolicySchema* GetSchemaForItems() const OVERRIDE;
-
- private:
- ListPolicySchema();
-
- scoped_ptr<PolicySchema> items_schema_;
-
- DISALLOW_COPY_AND_ASSIGN(ListPolicySchema);
-};
-
-bool SchemaTypeToValueType(const std::string& type_string,
- base::Value::Type* type) {
- // Note: "any" is not an accepted type.
- static const struct {
- const char* schema_type;
- base::Value::Type value_type;
- } kSchemaToValueTypeMap[] = {
- { json_schema_constants::kArray, base::Value::TYPE_LIST },
- { json_schema_constants::kBoolean, base::Value::TYPE_BOOLEAN },
- { json_schema_constants::kInteger, base::Value::TYPE_INTEGER },
- { json_schema_constants::kNull, base::Value::TYPE_NULL },
- { json_schema_constants::kNumber, base::Value::TYPE_DOUBLE },
- { json_schema_constants::kObject, base::Value::TYPE_DICTIONARY },
- { json_schema_constants::kString, base::Value::TYPE_STRING },
- };
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSchemaToValueTypeMap); ++i) {
- if (kSchemaToValueTypeMap[i].schema_type == type_string) {
- *type = kSchemaToValueTypeMap[i].value_type;
- return true;
- }
- }
- return false;
-}
-
-scoped_ptr<PolicySchema> ParseSchema(const base::DictionaryValue& schema,
- std::string* error) {
- std::string type_string;
- if (!schema.GetString(json_schema_constants::kType, &type_string)) {
- *error = "The schema type must be declared.";
- return scoped_ptr<PolicySchema>();
- }
-
- base::Value::Type type = base::Value::TYPE_NULL;
- if (!SchemaTypeToValueType(type_string, &type)) {
- *error = "The \"any\" type can't be used.";
- return scoped_ptr<PolicySchema>();
- }
-
- switch (type) {
- case base::Value::TYPE_DICTIONARY:
- return DictionaryPolicySchema::Parse(schema, error);
- case base::Value::TYPE_LIST:
- return ListPolicySchema::Parse(schema, error);
- default:
- return make_scoped_ptr(new PolicySchema(type));
- }
-}
-
-DictionaryPolicySchema::DictionaryPolicySchema()
- : PolicySchema(base::Value::TYPE_DICTIONARY) {}
-
-DictionaryPolicySchema::~DictionaryPolicySchema() {
- STLDeleteValues(&properties_);
-}
-
-const PolicySchemaMap* DictionaryPolicySchema::GetProperties() const {
- return &properties_;
-}
-
-const PolicySchema*
- DictionaryPolicySchema::GetSchemaForAdditionalProperties() const {
- return additional_properties_.get();
-}
-
-// static
-scoped_ptr<PolicySchema> DictionaryPolicySchema::Parse(
- const base::DictionaryValue& schema,
- std::string* error) {
- scoped_ptr<DictionaryPolicySchema> dict_schema(new DictionaryPolicySchema());
-
- const base::DictionaryValue* dict = NULL;
- const base::DictionaryValue* properties = NULL;
- if (schema.GetDictionary(json_schema_constants::kProperties, &properties)) {
- for (base::DictionaryValue::Iterator it(*properties);
- !it.IsAtEnd(); it.Advance()) {
- // This should have been verified by the JSONSchemaValidator.
- CHECK(it.value().GetAsDictionary(&dict));
- scoped_ptr<PolicySchema> sub_schema = ParseSchema(*dict, error);
- if (!sub_schema)
- return scoped_ptr<PolicySchema>();
- dict_schema->properties_[it.key()] = sub_schema.release();
- }
- }
-
- if (schema.GetDictionary(json_schema_constants::kAdditionalProperties,
- &dict)) {
- scoped_ptr<PolicySchema> sub_schema = ParseSchema(*dict, error);
- if (!sub_schema)
- return scoped_ptr<PolicySchema>();
- dict_schema->additional_properties_ = sub_schema.Pass();
- }
-
- return dict_schema.PassAs<PolicySchema>();
-}
-
-ListPolicySchema::ListPolicySchema()
- : PolicySchema(base::Value::TYPE_LIST) {}
-
-ListPolicySchema::~ListPolicySchema() {}
-
-const PolicySchema* ListPolicySchema::GetSchemaForItems() const {
- return items_schema_.get();
-}
-
-scoped_ptr<PolicySchema> ListPolicySchema::Parse(
- const base::DictionaryValue& schema,
- std::string* error) {
- const base::DictionaryValue* dict = NULL;
- if (!schema.GetDictionary(json_schema_constants::kItems, &dict)) {
- *error = "Arrays must declare a single schema for their items.";
- return scoped_ptr<PolicySchema>();
- }
- scoped_ptr<PolicySchema> items_schema = ParseSchema(*dict, error);
- if (!items_schema)
- return scoped_ptr<PolicySchema>();
-
- scoped_ptr<ListPolicySchema> list_schema(new ListPolicySchema());
- list_schema->items_schema_ = items_schema.Pass();
- return list_schema.PassAs<PolicySchema>();
-}
-
-} // namespace
-
-PolicySchema::PolicySchema(base::Value::Type type)
- : type_(type) {}
-
-PolicySchema::~PolicySchema() {}
-
-const PolicySchemaMap* PolicySchema::GetProperties() const {
- NOTREACHED();
- return NULL;
-}
-
-const PolicySchema* PolicySchema::GetSchemaForAdditionalProperties() const {
- NOTREACHED();
- return NULL;
-}
-
-const PolicySchema* PolicySchema::GetSchemaForProperty(
- const std::string& key) const {
- const PolicySchemaMap* properties = GetProperties();
- PolicySchemaMap::const_iterator it = properties->find(key);
- return it == properties->end() ? GetSchemaForAdditionalProperties()
- : it->second;
-}
-
-const PolicySchema* PolicySchema::GetSchemaForItems() const {
- NOTREACHED();
- return NULL;
-}
-
-// static
-scoped_ptr<PolicySchema> PolicySchema::Parse(const std::string& content,
- std::string* error) {
- // Validate as a generic JSON schema.
- scoped_ptr<base::DictionaryValue> dict =
- JSONSchemaValidator::IsValidSchema(content, error);
- if (!dict)
- return scoped_ptr<PolicySchema>();
-
- // Validate the schema version.
- std::string string_value;
- if (!dict->GetString(json_schema_constants::kSchema, &string_value) ||
- string_value != kJSONSchemaVersion) {
- *error = "Must declare JSON Schema v3 version in \"$schema\".";
- return scoped_ptr<PolicySchema>();
- }
-
- // Validate the main type.
- if (!dict->GetString(json_schema_constants::kType, &string_value) ||
- string_value != json_schema_constants::kObject) {
- *error =
- "The main schema must have a type attribute with \"object\" value.";
- return scoped_ptr<PolicySchema>();
- }
-
- // Checks for invalid attributes at the top-level.
- if (dict->HasKey(json_schema_constants::kAdditionalProperties) ||
- dict->HasKey(json_schema_constants::kPatternProperties)) {
- *error = "\"additionalProperties\" and \"patternProperties\" are not "
- "supported at the main schema.";
- return scoped_ptr<PolicySchema>();
- }
-
- return ParseSchema(*dict, error);
-}
-
-} // namespace policy
diff --git a/components/policy/core/common/policy_schema.h b/components/policy/core/common/policy_schema.h
deleted file mode 100644
index c48ee6f..0000000
--- a/components/policy/core/common/policy_schema.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// 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 COMPONENTS_POLICY_CORE_COMMON_POLICY_SCHEMA_H_
-#define COMPONENTS_POLICY_CORE_COMMON_POLICY_SCHEMA_H_
-
-#include <map>
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/values.h"
-#include "components/policy/policy_export.h"
-
-namespace policy {
-
-class PolicySchema;
-typedef std::map<std::string, PolicySchema*> PolicySchemaMap;
-
-// Maps known policy keys to their expected types, and recursively describes
-// the known keys within dictionary or list types.
-class POLICY_EXPORT PolicySchema {
- public:
-
- // Parses |schema| as a JSON v3 schema, and additionally verifies that:
- // - the version is JSON schema v3;
- // - the top-level entry is of type "object";
- // - the top-level object doesn't contain "additionalProperties" nor
- // "patternProperties";
- // - each "property" maps to a schema with one "type";
- // - the type "any" is not used.
- // If all the checks pass then the parsed PolicySchema is returned; otherwise
- // returns NULL.
- static scoped_ptr<PolicySchema> Parse(const std::string& schema,
- std::string* error);
-
- explicit PolicySchema(base::Value::Type type);
- virtual ~PolicySchema();
-
- // Returns the expected type for this policy. At the top-level PolicySchema
- // this is always TYPE_DICTIONARY.
- base::Value::Type type() const { return type_; }
-
- // It is invalid to call these methods when type() is not TYPE_DICTIONARY.
- //
- // GetProperties() returns a map of the known property names to their schemas;
- // the map is never NULL.
- // GetSchemaForAdditionalProperties() returns the schema that should be used
- // for keys not found in the map, and may be NULL.
- // GetSchemaForProperty() is a utility method that combines both, returning
- // the mapped schema if found in GetProperties(), otherwise returning
- // GetSchemaForAdditionalProperties().
- virtual const PolicySchemaMap* GetProperties() const;
- virtual const PolicySchema* GetSchemaForAdditionalProperties() const;
- const PolicySchema* GetSchemaForProperty(const std::string& key) const;
-
- // It is invalid to call this method when type() is not TYPE_LIST.
- // Returns the type of the entries of this "array", which is never NULL.
- virtual const PolicySchema* GetSchemaForItems() const;
-
- private:
- const base::Value::Type type_;
-
- DISALLOW_COPY_AND_ASSIGN(PolicySchema);
-};
-
-} // namespace policy
-
-#endif // COMPONENTS_POLICY_CORE_COMMON_POLICY_SCHEMA_H_
diff --git a/components/policy/core/common/policy_schema_unittest.cc b/components/policy/core/common/policy_schema_unittest.cc
deleted file mode 100644
index bfbdd65..0000000
--- a/components/policy/core/common/policy_schema_unittest.cc
+++ /dev/null
@@ -1,193 +0,0 @@
-// 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 "components/policy/core/common/policy_schema.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace policy {
-
-namespace {
-
-#define SCHEMA_VERSION "\"$schema\":\"http://json-schema.org/draft-03/schema#\""
-#define OBJECT_TYPE "\"type\":\"object\""
-
-bool ParseFails(const std::string& content) {
- std::string error;
- scoped_ptr<PolicySchema> schema = PolicySchema::Parse(content, &error);
- EXPECT_TRUE(schema || !error.empty());
- return !schema;
-}
-
-} // namespace
-
-TEST(PolicySchemaTest, MinimalSchema) {
- EXPECT_FALSE(ParseFails(
- "{"
- SCHEMA_VERSION ","
- OBJECT_TYPE
- "}"));
-}
-
-TEST(PolicySchemaTest, InvalidSchemas) {
- EXPECT_TRUE(ParseFails(""));
- EXPECT_TRUE(ParseFails("omg"));
- EXPECT_TRUE(ParseFails("\"omg\""));
- EXPECT_TRUE(ParseFails("123"));
- EXPECT_TRUE(ParseFails("[]"));
- EXPECT_TRUE(ParseFails("null"));
- EXPECT_TRUE(ParseFails("{}"));
- EXPECT_TRUE(ParseFails("{" SCHEMA_VERSION "}"));
- EXPECT_TRUE(ParseFails("{" OBJECT_TYPE "}"));
-
- EXPECT_TRUE(ParseFails(
- "{"
- SCHEMA_VERSION ","
- OBJECT_TYPE ","
- "\"additionalProperties\": { \"type\":\"object\" }"
- "}"));
-
- EXPECT_TRUE(ParseFails(
- "{"
- SCHEMA_VERSION ","
- OBJECT_TYPE ","
- "\"patternProperties\": { \"a+b*\": { \"type\": \"object\" } }"
- "}"));
-
- EXPECT_TRUE(ParseFails(
- "{"
- SCHEMA_VERSION ","
- OBJECT_TYPE ","
- "\"properties\": { \"Policy\": { \"type\": \"bogus\" } }"
- "}"));
-
- EXPECT_TRUE(ParseFails(
- "{"
- SCHEMA_VERSION ","
- OBJECT_TYPE ","
- "\"properties\": { \"Policy\": { \"type\": [\"string\", \"number\"] } }"
- "}"));
-
- EXPECT_TRUE(ParseFails(
- "{"
- SCHEMA_VERSION ","
- OBJECT_TYPE ","
- "\"properties\": { \"Policy\": { \"type\": \"any\" } }"
- "}"));
-}
-
-TEST(PolicySchemaTest, ValidSchema) {
- std::string error;
- scoped_ptr<PolicySchema> schema = PolicySchema::Parse(
- "{"
- SCHEMA_VERSION ","
- OBJECT_TYPE ","
- "\"properties\": {"
- " \"Boolean\": { \"type\": \"boolean\" },"
- " \"Integer\": { \"type\": \"integer\" },"
- " \"Null\": { \"type\": \"null\" },"
- " \"Number\": { \"type\": \"number\" },"
- " \"String\": { \"type\": \"string\" },"
- " \"Array\": {"
- " \"type\": \"array\","
- " \"items\": { \"type\": \"string\" }"
- " },"
- " \"ArrayOfObjects\": {"
- " \"type\": \"array\","
- " \"items\": {"
- " \"type\": \"object\","
- " \"properties\": {"
- " \"one\": { \"type\": \"string\" },"
- " \"two\": { \"type\": \"integer\" }"
- " }"
- " }"
- " },"
- " \"ArrayOfArray\": {"
- " \"type\": \"array\","
- " \"items\": {"
- " \"type\": \"array\","
- " \"items\": { \"type\": \"string\" }"
- " }"
- " },"
- " \"Object\": {"
- " \"type\": \"object\","
- " \"properties\": {"
- " \"one\": { \"type\": \"boolean\" },"
- " \"two\": { \"type\": \"integer\" }"
- " },"
- " \"additionalProperties\": { \"type\": \"string\" }"
- " }"
- "}"
- "}", &error);
- ASSERT_TRUE(schema) << error;
-
- ASSERT_EQ(base::Value::TYPE_DICTIONARY, schema->type());
- EXPECT_FALSE(schema->GetSchemaForProperty("invalid"));
-
- const PolicySchema* sub = schema->GetSchemaForProperty("Boolean");
- ASSERT_TRUE(sub);
- EXPECT_EQ(base::Value::TYPE_BOOLEAN, sub->type());
-
- sub = schema->GetSchemaForProperty("Integer");
- ASSERT_TRUE(sub);
- EXPECT_EQ(base::Value::TYPE_INTEGER, sub->type());
-
- sub = schema->GetSchemaForProperty("Null");
- ASSERT_TRUE(sub);
- EXPECT_EQ(base::Value::TYPE_NULL, sub->type());
-
- sub = schema->GetSchemaForProperty("Number");
- ASSERT_TRUE(sub);
- EXPECT_EQ(base::Value::TYPE_DOUBLE, sub->type());
- sub = schema->GetSchemaForProperty("String");
- ASSERT_TRUE(sub);
- EXPECT_EQ(base::Value::TYPE_STRING, sub->type());
-
- sub = schema->GetSchemaForProperty("Array");
- ASSERT_TRUE(sub);
- ASSERT_EQ(base::Value::TYPE_LIST, sub->type());
- sub = sub->GetSchemaForItems();
- ASSERT_TRUE(sub);
- EXPECT_EQ(base::Value::TYPE_STRING, sub->type());
-
- sub = schema->GetSchemaForProperty("ArrayOfObjects");
- ASSERT_TRUE(sub);
- ASSERT_EQ(base::Value::TYPE_LIST, sub->type());
- sub = sub->GetSchemaForItems();
- ASSERT_TRUE(sub);
- EXPECT_EQ(base::Value::TYPE_DICTIONARY, sub->type());
- const PolicySchema* subsub = sub->GetSchemaForProperty("one");
- ASSERT_TRUE(subsub);
- EXPECT_EQ(base::Value::TYPE_STRING, subsub->type());
- subsub = sub->GetSchemaForProperty("two");
- ASSERT_TRUE(subsub);
- EXPECT_EQ(base::Value::TYPE_INTEGER, subsub->type());
- subsub = sub->GetSchemaForProperty("invalid");
- EXPECT_FALSE(subsub);
-
- sub = schema->GetSchemaForProperty("ArrayOfArray");
- ASSERT_TRUE(sub);
- ASSERT_EQ(base::Value::TYPE_LIST, sub->type());
- sub = sub->GetSchemaForItems();
- ASSERT_TRUE(sub);
- ASSERT_EQ(base::Value::TYPE_LIST, sub->type());
- sub = sub->GetSchemaForItems();
- ASSERT_TRUE(sub);
- EXPECT_EQ(base::Value::TYPE_STRING, sub->type());
-
- sub = schema->GetSchemaForProperty("Object");
- ASSERT_TRUE(sub);
- ASSERT_EQ(base::Value::TYPE_DICTIONARY, sub->type());
- subsub = sub->GetSchemaForProperty("one");
- ASSERT_TRUE(subsub);
- EXPECT_EQ(base::Value::TYPE_BOOLEAN, subsub->type());
- subsub = sub->GetSchemaForProperty("two");
- ASSERT_TRUE(subsub);
- EXPECT_EQ(base::Value::TYPE_INTEGER, subsub->type());
- subsub = sub->GetSchemaForProperty("undeclared");
- ASSERT_TRUE(subsub);
- EXPECT_EQ(base::Value::TYPE_STRING, subsub->type());
-}
-
-} // namespace policy
diff --git a/components/policy/core/common/schema.cc b/components/policy/core/common/schema.cc
index cbfde46..b3e63d7 100644
--- a/components/policy/core/common/schema.cc
+++ b/components/policy/core/common/schema.cc
@@ -74,6 +74,8 @@ Schema Schema::Iterator::schema() const {
return Schema(it_->schema);
}
+Schema::Schema() : schema_(NULL) {}
+
Schema::Schema(const internal::SchemaNode* schema) : schema_(schema) {}
Schema::Schema(const Schema& schema) : schema_(schema.schema_) {}
@@ -112,7 +114,7 @@ Schema Schema::GetKnownProperty(const std::string& key) const {
properties_node->begin, properties_node->end, key, CompareKeys);
if (it != properties_node->end && it->key == key)
return Schema(it->schema);
- return Schema(NULL);
+ return Schema();
}
Schema Schema::GetAdditionalProperties() const {
diff --git a/components/policy/core/common/schema.h b/components/policy/core/common/schema.h
index a81b7ad..7a734bf 100644
--- a/components/policy/core/common/schema.h
+++ b/components/policy/core/common/schema.h
@@ -30,7 +30,14 @@ struct POLICY_EXPORT PropertiesNode;
// Use the SchemaOwner class to parse a schema and get Schema objects.
class POLICY_EXPORT Schema {
public:
+ // Builds an empty, invalid schema.
+ Schema();
+
+ // Builds a schema pointing to the inner structure of |schema|. If |schema|
+ // is NULL then this Schema instance will be invalid.
+ // Does not take ownership of |schema|.
explicit Schema(const internal::SchemaNode* schema);
+
Schema(const Schema& schema);
Schema& operator=(const Schema& schema);