mirror of
https://github.com/Telecominfraproject/wlan-cloud-owprov.git
synced 2025-11-01 19:17:47 +00:00
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
This commit is contained in:
@@ -43,8 +43,8 @@ find_package(OpenSSL REQUIRED)
|
|||||||
find_package(ZLIB REQUIRED)
|
find_package(ZLIB REQUIRED)
|
||||||
find_package(Poco REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite)
|
find_package(Poco REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite)
|
||||||
find_package(nlohmann_json REQUIRED)
|
find_package(nlohmann_json REQUIRED)
|
||||||
find_package(nlohmann_json_schema_validator REQUIRED)
|
|
||||||
find_package(fmt REQUIRED)
|
find_package(fmt REQUIRED)
|
||||||
|
find_package(valijson REQUIRED)
|
||||||
|
|
||||||
if(SMALL_BUILD)
|
if(SMALL_BUILD)
|
||||||
find_package(Poco REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite)
|
find_package(Poco REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite)
|
||||||
@@ -210,6 +210,5 @@ target_link_libraries(owprov PUBLIC
|
|||||||
${MySQL_LIBRARIES}
|
${MySQL_LIBRARIES}
|
||||||
${ZLIB_LIBRARIES}
|
${ZLIB_LIBRARIES}
|
||||||
CppKafka::cppkafka
|
CppKafka::cppkafka
|
||||||
fmt::fmt
|
fmt::fmt)
|
||||||
nlohmann_json_schema_validator)
|
|
||||||
|
|
||||||
|
|||||||
@@ -87,8 +87,8 @@ namespace OpenWifi{
|
|||||||
}
|
}
|
||||||
auto Config=RawObject->get("configuration").toString();
|
auto Config=RawObject->get("configuration").toString();
|
||||||
Poco::JSON::Object Answer;
|
Poco::JSON::Object Answer;
|
||||||
std::string Error;
|
std::vector<std::string> Error;
|
||||||
auto Res = ValidateUCentralConfiguration(Config,Error);
|
auto Res = ValidateUCentralConfiguration(Config,Error, GetBoolParameter("strict",true));
|
||||||
Answer.set("valid",Res);
|
Answer.set("valid",Res);
|
||||||
Answer.set("error", Error);
|
Answer.set("error", Error);
|
||||||
return ReturnObject(Answer);
|
return ReturnObject(Answer);
|
||||||
@@ -124,9 +124,9 @@ namespace OpenWifi{
|
|||||||
return BadRequest(RESTAPI::Errors::InvalidDeviceTypes);
|
return BadRequest(RESTAPI::Errors::InvalidDeviceTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
RESTAPI::Errors::msg Error;
|
std::vector<std::string> Errors;
|
||||||
if(!ValidateConfigBlock(NewObject,Error)) {
|
if(!ValidateConfigBlock(NewObject,Errors)) {
|
||||||
return BadRequest(Error);
|
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(DB_.CreateRecord(NewObject)) {
|
if(DB_.CreateRecord(NewObject)) {
|
||||||
@@ -171,9 +171,9 @@ namespace OpenWifi{
|
|||||||
if(!NewObject.deviceTypes.empty())
|
if(!NewObject.deviceTypes.empty())
|
||||||
Existing.deviceTypes = NewObject.deviceTypes;
|
Existing.deviceTypes = NewObject.deviceTypes;
|
||||||
|
|
||||||
RESTAPI::Errors::msg Error;
|
std::vector<std::string> Errors;
|
||||||
if(!ValidateConfigBlock( NewObject,Error)) {
|
if(!ValidateConfigBlock( NewObject,Errors)) {
|
||||||
return BadRequest(Error);
|
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(RawObject->has("configuration")) {
|
if(RawObject->has("configuration")) {
|
||||||
|
|||||||
@@ -406,7 +406,7 @@ namespace OpenWifi {
|
|||||||
return EntityDB::RootUUID();
|
return EntityDB::RootUUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool ValidateConfigBlock(const ProvObjects::DeviceConfiguration &Config, RESTAPI::Errors::msg & Error) {
|
inline bool ValidateConfigBlock(const ProvObjects::DeviceConfiguration &Config, std::vector<std::string> &Errors) {
|
||||||
static const std::vector<std::string> SectionNames{ "globals", "interfaces", "metrics", "radios", "services",
|
static const std::vector<std::string> SectionNames{ "globals", "interfaces", "metrics", "radios", "services",
|
||||||
"unit", "definitions", "ethernet", "switch", "config-raw",
|
"unit", "definitions", "ethernet", "switch", "config-raw",
|
||||||
"third-party" };
|
"third-party" };
|
||||||
@@ -414,8 +414,7 @@ namespace OpenWifi {
|
|||||||
for(const auto &i:Config.configuration) {
|
for(const auto &i:Config.configuration) {
|
||||||
Poco::JSON::Parser P;
|
Poco::JSON::Parser P;
|
||||||
if(i.name.empty()) {
|
if(i.name.empty()) {
|
||||||
std::cout << "Name is empty" << std::endl;
|
Errors.push_back("Name is empty");
|
||||||
Error = RESTAPI::Errors::NameMustBeSet;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,25 +423,23 @@ namespace OpenWifi {
|
|||||||
auto N = Blocks->getNames();
|
auto N = Blocks->getNames();
|
||||||
for (const auto &j: N) {
|
for (const auto &j: N) {
|
||||||
if (std::find(SectionNames.cbegin(), SectionNames.cend(), j) == SectionNames.cend()) {
|
if (std::find(SectionNames.cbegin(), SectionNames.cend(), j) == SectionNames.cend()) {
|
||||||
Error = RESTAPI::Errors::UnknownConfigurationSection;
|
Errors.push_back("Unknown block name");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (const Poco::JSON::JSONException &E ) {
|
} catch (const Poco::JSON::JSONException &E ) {
|
||||||
Error = RESTAPI::Errors::InvalidJSONDocument;
|
Errors.push_back("Invalid JSON document");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
std::string ErrorText;
|
if (ValidateUCentralConfiguration(i.configuration, Errors,true)) {
|
||||||
if (ValidateUCentralConfiguration(i.configuration, ErrorText)) {
|
|
||||||
// std::cout << "Block: " << i.name << " is valid" << std::endl;
|
// std::cout << "Block: " << i.name << " is valid" << std::endl;
|
||||||
} else {
|
} else {
|
||||||
Error = RESTAPI::Errors::ConfigBlockInvalid ;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
std::cout << "Exception in validation" << std::endl;
|
Errors.push_back("Invalid configuration caused an exception");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,12 +447,11 @@ namespace OpenWifi {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Type> std::map<std::string,std::string> CreateObjects(Type & NewObject, RESTAPIHandler & R, RESTAPI::Errors::msg & Error) {
|
template <typename Type> std::map<std::string,std::string> CreateObjects(Type & NewObject, RESTAPIHandler & R, std::vector<std::string> & Errors) {
|
||||||
std::map<std::string,std::string> Result;
|
std::map<std::string,std::string> Result;
|
||||||
|
|
||||||
auto createObjects = R.GetParameter("createObjects","");
|
auto createObjects = R.GetParameter("createObjects","");
|
||||||
if(!createObjects.empty()) {
|
if(!createObjects.empty()) {
|
||||||
std::cout << "createObjects: " << createObjects << std::endl;
|
|
||||||
Poco::JSON::Parser P;
|
Poco::JSON::Parser P;
|
||||||
auto Objects = P.parse(createObjects).extract<Poco::JSON::Object::Ptr>();
|
auto Objects = P.parse(createObjects).extract<Poco::JSON::Object::Ptr>();
|
||||||
if(Objects->isArray("objects")) {
|
if(Objects->isArray("objects")) {
|
||||||
@@ -467,7 +463,6 @@ namespace OpenWifi {
|
|||||||
ProvObjects::Location LC;
|
ProvObjects::Location LC;
|
||||||
if (LC.from_json(LocationDetails)) {
|
if (LC.from_json(LocationDetails)) {
|
||||||
if constexpr(std::is_same_v<Type,ProvObjects::Venue>) {
|
if constexpr(std::is_same_v<Type,ProvObjects::Venue>) {
|
||||||
std::cout << "Location decoded: " << LC.info.name << std::endl;
|
|
||||||
std::string ParentEntity = FindParentEntity(NewObject);
|
std::string ParentEntity = FindParentEntity(NewObject);
|
||||||
ProvObjects::CreateObjectInfo(R.UserInfo_.userinfo, LC.info);
|
ProvObjects::CreateObjectInfo(R.UserInfo_.userinfo, LC.info);
|
||||||
LC.entity = ParentEntity;
|
LC.entity = ParentEntity;
|
||||||
@@ -479,7 +474,6 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if constexpr(std::is_same_v<Type,ProvObjects::Operator>) {
|
if constexpr(std::is_same_v<Type,ProvObjects::Operator>) {
|
||||||
std::cout << "Location decoded: " << LC.info.name << std::endl;
|
|
||||||
std::string ParentEntity = FindParentEntity(NewObject);
|
std::string ParentEntity = FindParentEntity(NewObject);
|
||||||
ProvObjects::CreateObjectInfo(R.UserInfo_.userinfo, LC.info);
|
ProvObjects::CreateObjectInfo(R.UserInfo_.userinfo, LC.info);
|
||||||
LC.entity = ParentEntity;
|
LC.entity = ParentEntity;
|
||||||
@@ -491,7 +485,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Error = RESTAPI::Errors::InvalidJSONDocument;
|
Errors.push_back("Invalid JSON document");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (Object->has("contact")) {
|
} else if (Object->has("contact")) {
|
||||||
@@ -507,10 +501,9 @@ namespace OpenWifi {
|
|||||||
ProvObjects::DeviceConfiguration DC;
|
ProvObjects::DeviceConfiguration DC;
|
||||||
if(DC.from_json(ConfigurationDetails)) {
|
if(DC.from_json(ConfigurationDetails)) {
|
||||||
if constexpr(std::is_same_v<Type, ProvObjects::InventoryTag>) {
|
if constexpr(std::is_same_v<Type, ProvObjects::InventoryTag>) {
|
||||||
if(!ValidateConfigBlock(DC,Error)) {
|
if(!ValidateConfigBlock(DC,Errors)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
std::cout << "Configuration decoded: " << DC.info.name << std::endl;
|
|
||||||
ProvObjects::CreateObjectInfo(R.UserInfo_.userinfo, DC.info);
|
ProvObjects::CreateObjectInfo(R.UserInfo_.userinfo, DC.info);
|
||||||
if (StorageService()->ConfigurationDB().CreateRecord(DC)) {
|
if (StorageService()->ConfigurationDB().CreateRecord(DC)) {
|
||||||
NewObject.deviceConfiguration = DC.info.id;
|
NewObject.deviceConfiguration = DC.info.id;
|
||||||
@@ -518,7 +511,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Error = RESTAPI::Errors::InvalidJSONDocument;
|
Errors.push_back("Invalid JSON document");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,10 +239,10 @@ namespace OpenWifi{
|
|||||||
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
|
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
RESTAPI::Errors::msg Error=RESTAPI::Errors::SUCCESS;
|
std::vector<std::string> Errors;
|
||||||
auto ObjectsCreated = CreateObjects(NewObject,*this,Error);
|
auto ObjectsCreated = CreateObjects(NewObject,*this,Errors);
|
||||||
if(Error.err_num != 0) {
|
if(!Errors.empty()) {
|
||||||
return BadRequest(Error);
|
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(DB_.CreateRecord(NewObject)) {
|
if(DB_.CreateRecord(NewObject)) {
|
||||||
@@ -396,10 +396,10 @@ namespace OpenWifi{
|
|||||||
Existing.state = NewObject.state;
|
Existing.state = NewObject.state;
|
||||||
}
|
}
|
||||||
|
|
||||||
RESTAPI::Errors::msg Error=RESTAPI::Errors::SUCCESS;
|
std::vector<std::string> Errors;
|
||||||
auto ObjectsCreated = CreateObjects(NewObject,*this,Error);
|
auto ObjectsCreated = CreateObjects(NewObject,*this,Errors);
|
||||||
if(Error.err_num != 0) {
|
if(!Errors.empty()) {
|
||||||
return BadRequest(Error);
|
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ObjectsCreated.empty()) {
|
if(!ObjectsCreated.empty()) {
|
||||||
|
|||||||
@@ -185,9 +185,10 @@ namespace OpenWifi{
|
|||||||
NewObject.children.clear();
|
NewObject.children.clear();
|
||||||
|
|
||||||
RESTAPI::Errors::msg Error=RESTAPI::Errors::SUCCESS;
|
RESTAPI::Errors::msg Error=RESTAPI::Errors::SUCCESS;
|
||||||
auto ObjectsCreated = CreateObjects(NewObject,*this,Error);
|
std::vector<std::string> Errors;
|
||||||
|
auto ObjectsCreated = CreateObjects(NewObject,*this,Errors);
|
||||||
if(Error.err_num != 0) {
|
if(Error.err_num != 0) {
|
||||||
return BadRequest(Error);
|
return BadRequest(RESTAPI::Errors::InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(DB_.CreateRecord(NewObject)) {
|
if(DB_.CreateRecord(NewObject)) {
|
||||||
@@ -355,10 +356,10 @@ namespace OpenWifi{
|
|||||||
NewObject.parent = Existing.parent;
|
NewObject.parent = Existing.parent;
|
||||||
NewObject.entity = Existing.entity;
|
NewObject.entity = Existing.entity;
|
||||||
|
|
||||||
RESTAPI::Errors::msg Error=RESTAPI::Errors::SUCCESS;
|
std::vector<std::string> Errors;
|
||||||
auto ObjectsCreated = CreateObjects(NewObject,*this,Error);
|
auto ObjectsCreated = CreateObjects(NewObject,*this,Errors);
|
||||||
if(Error.err_num != 0) {
|
if(!Errors.empty()) {
|
||||||
return BadRequest(Error);
|
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ObjectsCreated.empty()) {
|
if(!ObjectsCreated.empty()) {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,11 +4,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <nlohmann/json-schema.hpp>
|
|
||||||
#include "framework/SubSystemServer.h"
|
#include "framework/SubSystemServer.h"
|
||||||
|
|
||||||
using nlohmann::json;
|
#include <valijson/adapters/poco_json_adapter.hpp>
|
||||||
using nlohmann::json_schema::json_validator;
|
#include <valijson/utils/poco_json_utils.hpp>
|
||||||
|
#include <valijson/schema.hpp>
|
||||||
|
#include <valijson/schema_parser.hpp>
|
||||||
|
#include <valijson/validator.hpp>
|
||||||
|
#include <valijson/constraints/constraint.hpp>
|
||||||
|
#include <valijson/constraints/constraint_visitor.hpp>
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
class ConfigurationValidator : public SubSystemServer {
|
class ConfigurationValidator : public SubSystemServer {
|
||||||
@@ -19,17 +23,19 @@ namespace OpenWifi {
|
|||||||
return instance_;
|
return instance_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Validate(const std::string &C, std::string &Error);
|
bool Validate(const std::string &C, std::vector<std::string> &Errors, bool Strict);
|
||||||
static void my_format_checker(const std::string &format, const std::string &value);
|
|
||||||
int Start() override;
|
int Start() override;
|
||||||
void Stop() override;
|
void Stop() override;
|
||||||
void reinitialize(Poco::Util::Application &self) override;
|
void reinitialize(Poco::Util::Application &self) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool Initialized_=false;
|
bool Initialized_=false;
|
||||||
bool Working_=false;
|
bool Working_=false;
|
||||||
void Init();
|
void Init();
|
||||||
nlohmann::json RootSchema_;
|
std::unique_ptr<valijson::Schema> RootSchema_;
|
||||||
|
std::unique_ptr<valijson::SchemaParser> SchemaParser_;
|
||||||
|
std::unique_ptr<valijson::adapters::PocoJsonAdapter> PocoJsonAdapter_;
|
||||||
|
Poco::JSON::Object::Ptr SchemaDocPtr_;
|
||||||
|
|
||||||
ConfigurationValidator():
|
ConfigurationValidator():
|
||||||
SubSystemServer("ConfigValidator", "CFG-VALIDATOR", "config.validator") {
|
SubSystemServer("ConfigValidator", "CFG-VALIDATOR", "config.validator") {
|
||||||
@@ -37,6 +43,6 @@ namespace OpenWifi {
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline auto ConfigurationValidator() { return ConfigurationValidator::instance(); }
|
inline auto ConfigurationValidator() { return ConfigurationValidator::instance(); }
|
||||||
inline bool ValidateUCentralConfiguration(const std::string &C, std::string &Error) { return ConfigurationValidator::instance()->Validate(C, Error); }
|
inline bool ValidateUCentralConfiguration(const std::string &C, std::vector<std::string> &Error, bool strict) { return ConfigurationValidator::instance()->Validate(C, Error, strict); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user