Start validating json
Make sure json matches the schema, or don't load the file.
Also start installing json files using CMakeLists instead of
in the recipe.
Change-Id: I78622b961d1185d864d6ddd27e5baad34bc3ef5e
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ce5d5e1..f14f97f 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -108,4 +108,4 @@
install (TARGETS fru-device entity-manager DESTINATION bin)
install (DIRECTORY configurations DESTINATION share)
install (DIRECTORY overlay_templates DESTINATION share)
-# install (DIRECTORY schemas DESTINATION share/configurations)
+install (DIRECTORY schemas DESTINATION share/configurations)
diff --git a/include/Utils.hpp b/include/Utils.hpp
index d991f0d..1e54477 100644
--- a/include/Utils.hpp
+++ b/include/Utils.hpp
@@ -16,8 +16,12 @@
#pragma once
#include <experimental/filesystem>
+#include <nlohmann/json.hpp>
bool find_files(const std::experimental::filesystem::path &dir_path,
const std::string &match_string,
std::vector<std::experimental::filesystem::path> &found_paths,
unsigned int symlink_depth = 1);
+
+bool validateJson(const nlohmann::json &schemaFile,
+ const nlohmann::json &input);
diff --git a/src/EntityManager.cpp b/src/EntityManager.cpp
index ab658b2..81df6e1 100644
--- a/src/EntityManager.cpp
+++ b/src/EntityManager.cpp
@@ -33,8 +33,9 @@
#include <experimental/filesystem>
constexpr const char *OUTPUT_DIR = "/var/configuration/";
-constexpr const char *CONFIGURATION_DIR = "/usr/share/configurations";
-constexpr const char *schemaFile = "schema.json";
+constexpr const char *configurationDirectory = "/usr/share/configurations";
+constexpr const char *schemaDirectory = "/usr/share/configurations/schemas";
+constexpr const char *globalSchema = "global.json";
constexpr const char *TEMPLATE_CHAR = "$";
constexpr const size_t PROPERTIES_CHANGED_UNTIL_FLUSH_COUNT = 20;
constexpr const int32_t MAX_MAPPER_DEPTH = 0;
@@ -960,19 +961,32 @@
{
// find configuration files
std::vector<fs::path> jsonPaths;
- if (!find_files(fs::path(CONFIGURATION_DIR), R"(.*\.json)", jsonPaths, 0))
+ if (!find_files(fs::path(configurationDirectory), R"(.*\.json)", jsonPaths,
+ 0))
{
std::cerr << "Unable to find any configuration files in "
- << CONFIGURATION_DIR << "\n";
+ << configurationDirectory << "\n";
return false;
}
+
+ std::ifstream schemaStream(std::string(schemaDirectory) + "/" +
+ globalSchema);
+ if (!schemaStream.good())
+ {
+ std::cerr
+ << "Cannot open schema file, cannot validate JSON, exiting\n\n";
+ std::exit(EXIT_FAILURE);
+ }
+ nlohmann::json schema = nlohmann::json::parse(schemaStream, nullptr, false);
+ if (schema.is_discarded())
+ {
+ std::cerr
+ << "Illegal schema file detected, cannot validate JSON, exiting\n";
+ std::exit(EXIT_FAILURE);
+ }
+
for (auto &jsonPath : jsonPaths)
{
- if (boost::algorithm::ends_with(jsonPath.string(), schemaFile))
- {
- // todo: parse using schema
- continue;
- }
std::ifstream jsonStream(jsonPath.c_str());
if (!jsonStream.good())
{
@@ -985,6 +999,12 @@
std::cerr << "syntax error in " << jsonPath.string() << "\n";
continue;
}
+ if (!validateJson(schema, data))
+ {
+ std::cerr << "Error validating " << jsonPath.string() << "\n";
+ continue;
+ }
+
if (data.type() == nlohmann::json::value_t::array)
{
for (auto &d : data)
diff --git a/src/Utils.cpp b/src/Utils.cpp
index b5c3787..6db1157 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -18,6 +18,10 @@
#include <experimental/filesystem>
#include <fstream>
#include <regex>
+#include <valijson/adapters/nlohmann_json_adapter.hpp>
+#include <valijson/schema.hpp>
+#include <valijson/schema_parser.hpp>
+#include <valijson/validator.hpp>
namespace fs = std::experimental::filesystem;
@@ -45,4 +49,19 @@
}
}
return true;
+}
+
+bool validateJson(const nlohmann::json &schemaFile, const nlohmann::json &input)
+{
+ valijson::Schema schema;
+ valijson::SchemaParser parser;
+ valijson::adapters::NlohmannJsonAdapter schemaAdapter(schemaFile);
+ parser.populateSchema(schemaAdapter, schema);
+ valijson::Validator validator;
+ valijson::adapters::NlohmannJsonAdapter targetAdapter(input);
+ if (!validator.validate(schema, targetAdapter, NULL))
+ {
+ return false;
+ }
+ return true;
}
\ No newline at end of file