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..5d2dfdbd083a9df9f657999a136ac23f6b1a63eb |
--- /dev/null |
+++ b/chrome/browser/policy/policy_schema.cc |
@@ -0,0 +1,107 @@ |
+// 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" |
+#include "base/logging.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#"; |
+ |
+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; |
+} |
+ |
+} // namespace |
+ |
+// static |
+scoped_ptr<PolicySchema> PolicySchema::Parse(const std::string& content, |
+ std::string* error) { |
+ // Validate as a generic JSON schema. |
+ scoped_ptr<base::DictionaryValue> schema = |
+ JSONSchemaValidator::IsValidSchema(content, error); |
+ if (!schema) |
+ return scoped_ptr<PolicySchema>(); |
+ |
+ // Validate the schema version. |
+ std::string string_value; |
+ if (!schema->GetString(json_schema_constants::kSchema, &string_value) || |
+ string_value != kJSONSchemaVersion) { |
+ *error = "Must declare JSON Schema v3 version in \"$schema\""; |
Mattias Nissler (ping if slow)
2013/05/15 10:04:12
Is this a good idea? This will prevent upgrading t
Joao da Silva
2013/05/19 13:17:08
If a new format is introduced then Chrome X will s
|
+ return scoped_ptr<PolicySchema>(); |
+ } |
+ |
+ // Validate the main type. |
+ if (!schema->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>(); |
+ } |
+ |
+ // Validate the properties and convert into a TypeMap. |
+ if (schema->HasKey(json_schema_constants::kAdditionalProperties) || |
+ schema->HasKey(json_schema_constants::kPatternProperties)) { |
+ *error = "\"additionalProperties\" and \"patternProperties\" are not " |
+ "supported at the main schema"; |
Mattias Nissler (ping if slow)
2013/05/15 10:04:12
Ditto: Should this be a hard error or merely a war
Joao da Silva
2013/05/19 13:17:08
This restriction is forced because some policy loa
|
+ return scoped_ptr<PolicySchema>(); |
+ } |
+ |
+ TypeMap map; |
+ const base::DictionaryValue* properties = NULL; |
+ if (schema->GetDictionary(json_schema_constants::kProperties, &properties)) { |
+ for (base::DictionaryValue::Iterator it(*properties); |
+ !it.IsAtEnd(); it.Advance()) { |
+ const base::DictionaryValue* dict = NULL; |
+ // This should have been verified by the JSONSchemaValidator. |
+ CHECK(it.value().GetAsDictionary(&dict)); |
+ std::string type_string; |
+ if (!dict->GetString(json_schema_constants::kType, &type_string)) { |
+ *error = "The types of the main properties must be string values"; |
+ return scoped_ptr<PolicySchema>(); |
+ } |
+ base::Value::Type type = base::Value::TYPE_NULL; |
+ if (!SchemaTypeToValueType(type_string, &type)) { |
+ *error = "The type of main properties can't be \"any\""; |
Mattias Nissler (ping if slow)
2013/05/15 10:04:12
Forward-compatibility?
Joao da Silva
2013/05/19 13:17:08
Same rationale again; we can roll an updated versi
|
+ return scoped_ptr<PolicySchema>(); |
+ } |
+ map[it.key()] = type; |
+ } |
+ } |
+ |
+ scoped_ptr<PolicySchema> policy_schema(new PolicySchema()); |
+ policy_schema->type_map_.swap(map); |
+ return policy_schema.Pass(); |
+} |
+ |
+PolicySchema::~PolicySchema() {} |
+ |
+PolicySchema::PolicySchema() {} |
+ |
+} // namespace policy |