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

Unified Diff: chrome/browser/policy/policy_schema.cc

Issue 15133005: Added a PolicySchema class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 7 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/policy/policy_schema.cc
diff --git a/chrome/browser/policy/policy_schema.cc b/chrome/browser/policy/policy_schema.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f976e05cb17b2ecc0453c68475b947a0e0e0b412
--- /dev/null
+++ b/chrome/browser/policy/policy_schema.cc
@@ -0,0 +1,243 @@
+// Copyright (c) 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 "chrome/browser/policy/policy_schema.h"
+
+#include "base/json/json_reader.h"
bartfab (slow) 2013/05/21 11:02:40 What is this used for?
Joao da Silva 2013/05/21 17:16:25 It's not used, removed.
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "chrome/common/json_schema/json_schema_constants.h"
+#include "chrome/common/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;
bartfab (slow) 2013/05/21 11:02:40 #include "base/compiler_specific.h"
Joao da Silva 2013/05/21 17:16:25 Done.
+ 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 },
bartfab (slow) 2013/05/21 11:02:40 nit: Why a single space after { and a double space
Joao da Silva 2013/05/21 17:16:25 Ha, that was vi aligning at tab boundaries. Fixed.
+ { 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.";
bartfab (slow) 2013/05/21 11:02:40 You can't be sure that the schema was "any" here.
Joao da Silva 2013/05/21 17:16:25 Actually only "any" could trigger this, because |s
+ 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);
bartfab (slow) 2013/05/21 11:02:40 nit: You can additionally make |it| const.
Joao da Silva 2013/05/21 17:16:25 A const_iterator is already a const pointer to som
bartfab (slow) 2013/05/21 18:09:56 Yes, preventing |it| from being reset is what I wa
+ 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\"";
bartfab (slow) 2013/05/21 11:02:40 Nit: Above this line, all error strings were full
Joao da Silva 2013/05/21 17:16:25 Done.
+ 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

Powered by Google App Engine
This is Rietveld 408576698