stephb9959
2022-11-03 22:33:46 -07:00
parent da31483c78
commit 01d7a048dd
12 changed files with 418 additions and 4 deletions

View File

@@ -203,7 +203,7 @@ add_executable(owprov
src/ProvWebSocketClient.cpp src/ProvWebSocketClient.h
src/Tasks/VenueRebooter.h src/Tasks/VenueUpgrade.h
src/sdks/SDK_fms.cpp src/sdks/SDK_fms.h
)
src/storage/storage_overrides.cpp src/storage/storage_overrides.h src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h)
target_link_libraries(owprov PUBLIC
${Poco_LIBRARIES}

2
build
View File

@@ -1 +1 @@
9
15

View File

@@ -1220,6 +1220,40 @@ components:
items:
$ref: '#/components/schemas/SubscriberDevice'
ConfigurationOverride:
type: object
properties:
source:
type: string
reason:
type: string
parameterName:
type: string
parameterType:
enum:
- string
- integer
- boolean
parameterValue:
type: string
modified:
type: integer
format: int64
ConfigurationOverrideList:
type: object
properties:
serialNumber:
type: string
managementPolicy:
type: string
format: uuid
overrides:
type: array
items:
$ref: '#/components/schemas/ConfigurationOverride'
#########################################################################################
##
## These are endpoints that all services in the OPenWiFI stack must provide
@@ -2211,6 +2245,94 @@ paths:
404:
$ref: '#/components/responses/NotFound'
/configurationOverrides/{serialNumber}:
get:
tags:
- Configuration Overrides
operationId: getCponfigurationOverrides
summary: retrieve a list of configuration overrides for a given device
parameters:
- in: path
name: serialNumber
schema:
type: string
required: true
responses:
200:
description: Return a list of configuration overrides.
content:
application/json:
schema:
$ref: '#/components/schemas/ConfigurationOverrideList'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
delete:
tags:
- Configuration Overrides
operationId: deleteCponfigurationOverrides
summary: delete all configuration overrides for a given device from a given source
parameters:
- in: path
name: serialNumber
schema:
type: string
required: true
- in: query
name: source
schema:
type: string
required: true
responses:
200:
$ref: '#/components/responses/Success'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
put:
tags:
- Configuration Overrides
operationId: modifyConfigurationOverrides
summary: modify configuration overrides for a given device for a given source
parameters:
- in: path
name: serialNumber
schema:
type: string
required: true
- in: query
name: source
schema:
type: string
required: true
requestBody:
description: Information used to modify the override list
content:
application/json:
schema:
$ref: '#/components/schemas/ConfigurationOverrideList'
responses:
200:
description: Return the modified configuration overrides.
content:
application/json:
schema:
$ref: '#/components/schemas/ConfigurationOverrideList'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/venue:
get:
tags:

View File

@@ -0,0 +1,106 @@
//
// Created by stephane bourque on 2022-11-03.
//
#include <algorithm>
#include "RESTAPI_overrides_handler.h"
#include "framework/utils.h"
namespace OpenWifi {
void RESTAPI_overrides_handler::DoGet() {
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
if(!Utils::NormalizeMac(SerialNumber)) {
return BadRequest(RESTAPI::Errors::InvalidSerialNumber);
}
ProvObjects::ConfigurationOverrideList ExistingObject;
if(!DB_.GetRecord("serialNumber", SerialNumber, ExistingObject)) {
return NotFound();
}
Poco::JSON::Object Answer;
ExistingObject.to_json(Answer);
return ReturnObject(Answer);
}
void RESTAPI_overrides_handler::DoDelete() {
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
if(!Utils::NormalizeMac(SerialNumber)) {
return BadRequest(RESTAPI::Errors::InvalidSerialNumber);
}
auto Source = GetParameter("source","");
if(Source.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
ProvObjects::ConfigurationOverrideList ExistingObject;
if(!DB_.GetRecord("serialNumber", SerialNumber, ExistingObject)) {
return NotFound();
}
ExistingObject.overrides.erase( std::remove_if( ExistingObject.overrides.begin(), ExistingObject.overrides.end(),
[Source](const ProvObjects::ConfigurationOverride &O) ->bool {
return O.source==Source;
}),ExistingObject.overrides.end());
if(DB_.UpdateRecord("serialNumber", SerialNumber, ExistingObject)) {
return OK();
}
return BadRequest(RESTAPI::Errors::NoRecordsDeleted);
}
void RESTAPI_overrides_handler::DoPut() {
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
if(!Utils::NormalizeMac(SerialNumber)) {
return BadRequest(RESTAPI::Errors::InvalidSerialNumber);
}
auto Source = GetParameter("source","");
if(Source.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
ProvObjects::ConfigurationOverrideList NewObject;
if(!NewObject.from_json(ParsedBody_)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
ProvObjects::ConfigurationOverrideList ExistingObject;
if(!DB_.GetRecord("serialNumber", SerialNumber, ExistingObject)) {
ExistingObject.serialNumber = SerialNumber;
DB_.CreateRecord(ExistingObject);
} else {
// remove all the old records with that source.
ExistingObject.overrides.erase( std::remove_if( ExistingObject.overrides.begin(), ExistingObject.overrides.end(),
[Source](const ProvObjects::ConfigurationOverride &O) ->bool {
return O.source==Source;
}),ExistingObject.overrides.end());
}
for(auto & override:NewObject.overrides) {
if(override.parameterName.empty()) {
continue;
}
if(override.parameterType!="string" && override.parameterType!="boolean" && override.parameterType!="integer") {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
override.source = Source;
override.modified = Utils::Now();
ExistingObject.overrides.emplace_back(override);
}
if(DB_.UpdateRecord("serialNumber",SerialNumber,ExistingObject)) {
Poco::JSON::Object Answer;
ExistingObject.to_json(Answer);
return ReturnObject(Answer);
}
return BadRequest(RESTAPI::Errors::RecordNotUpdated);
}
} // OpenWifi

View File

@@ -0,0 +1,31 @@
//
// Created by stephane bourque on 2022-11-03.
//
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_overrides_handler : public RESTAPIHandler {
public:
RESTAPI_overrides_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/configurationOverrides/{serialNumber}"}; };
private:
OverridesDB &DB_=StorageService()->OverridesDB();
void DoGet() final ;
void DoPost() final {} ;
void DoPut() final ;
void DoDelete() final ;
};
}

View File

@@ -34,6 +34,7 @@
#include "RESTAPI/RESTAPI_op_contact_list_handler.h"
#include "RESTAPI/RESTAPI_op_location_handler.h"
#include "RESTAPI/RESTAPI_op_location_list_handler.h"
#include "RESTAPI/RESTAPI_overrides_handler.h"
#include "framework/RESTAPI_SystemCommand.h"
#include "framework/RESTAPI_WebSocketServer.h"
@@ -76,7 +77,8 @@ namespace OpenWifi {
RESTAPI_op_contact_list_handler,
RESTAPI_op_location_handler,
RESTAPI_op_location_list_handler,
RESTAPI_asset_server
RESTAPI_asset_server,
RESTAPI_overrides_handler
>(Path,Bindings,L, S, TransactionId);
}
@@ -115,7 +117,8 @@ namespace OpenWifi {
RESTAPI_op_contact_handler,
RESTAPI_op_contact_list_handler,
RESTAPI_op_location_handler,
RESTAPI_op_location_list_handler
RESTAPI_op_location_list_handler,
RESTAPI_overrides_handler
>(Path, Bindings, L, S, TransactionId);
}
}

View File

@@ -1195,6 +1195,48 @@ namespace OpenWifi::ProvObjects {
return false;
}
void ConfigurationOverride::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"source",source);
field_to_json(Obj,"reason",reason);
field_to_json(Obj,"parameterName",parameterName);
field_to_json(Obj,"parameterType",parameterType);
field_to_json(Obj,"parameterValue",parameterValue);
field_to_json(Obj,"modified",modified);
}
bool ConfigurationOverride::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"source",source);
field_from_json(Obj,"reason",reason);
field_from_json(Obj,"parameterName",parameterName);
field_from_json(Obj,"parameterType",parameterType);
field_from_json(Obj,"parameterValue",parameterValue);
field_from_json(Obj,"modified",modified);
return true;
} catch(...) {
}
return false;
}
void ConfigurationOverrideList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"serialNumber",serialNumber);
field_to_json(Obj,"managementPolicy",managementPolicy);
field_to_json(Obj,"overrides",overrides);
}
bool ConfigurationOverrideList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"serialNumber",serialNumber);
field_from_json(Obj,"managementPolicy",managementPolicy);
field_from_json(Obj,"overrides",overrides);
return true;
} catch(...) {
}
return false;
}
}

View File

@@ -693,6 +693,27 @@ namespace OpenWifi::ProvObjects {
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ConfigurationOverride {
std::string source;
std::string reason;
std::string parameterName;
std::string parameterType;
std::string parameterValue;
std::uint64_t modified;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ConfigurationOverrideList {
std::string serialNumber;
Types::UUID_t managementPolicy;
std::vector<ConfigurationOverride> overrides;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I);
bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I);
bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I);

View File

@@ -37,6 +37,7 @@ namespace OpenWifi {
SubscriberDeviceDB_ = std::make_unique<OpenWifi::SubscriberDeviceDB>(dbType_, *Pool_, Logger());
OpLocationDB_ = std::make_unique<OpenWifi::OpLocationDB>(dbType_, *Pool_, Logger());
OpContactDB_ = std::make_unique<OpenWifi::OpContactDB>(dbType_, *Pool_, Logger());
OverridesDB_ = std::make_unique<OpenWifi::OverridesDB>(dbType_, *Pool_, Logger());
EntityDB_->Create();
PolicyDB_->Create();
@@ -56,6 +57,7 @@ namespace OpenWifi {
SubscriberDeviceDB_->Create();
OpLocationDB_->Create();
OpContactDB_->Create();
OverridesDB_->Create();
ExistFunc_[EntityDB_->Prefix()] = [=](const char *F, std::string &V) -> bool { return EntityDB_->Exists(F,V); };
ExistFunc_[PolicyDB_->Prefix()] = [=](const char *F, std::string &V) -> bool { return PolicyDB_->Exists(F,V); };
@@ -75,6 +77,7 @@ namespace OpenWifi {
ExistFunc_[SubscriberDeviceDB_->Prefix()] = [=](const char *F, std::string &V) ->bool { return SubscriberDeviceDB_->Exists(F,V); };
ExistFunc_[OpLocationDB_->Prefix()] = [=](const char *F, std::string &V) ->bool { return OpLocationDB_->Exists(F,V); };
ExistFunc_[OpContactDB_->Prefix()] = [=](const char *F, std::string &V) ->bool { return OpContactDB_->Exists(F,V); };
ExistFunc_[OverridesDB_->Prefix()] = [=](const char *F, std::string &V) ->bool { return OverridesDB_->Exists(F,V); };
ExpandFunc_[EntityDB_->Prefix()] = [=](const char *F, std::string &V, std::string &Name, std::string & Description) -> bool { return EntityDB_->GetNameAndDescription(F,V, Name, Description); };
ExpandFunc_[PolicyDB_->Prefix()] = [=](const char *F, std::string &V, std::string &Name, std::string & Description) -> bool { return PolicyDB_->GetNameAndDescription(F,V, Name, Description); };
@@ -94,6 +97,7 @@ namespace OpenWifi {
ExpandFunc_[SubscriberDeviceDB_->Prefix()] = [=](const char *F, std::string &V, std::string &Name, std::string & Description) ->bool { return SubscriberDeviceDB_->GetNameAndDescription(F,V, Name, Description); };
ExpandFunc_[OpLocationDB_->Prefix()] = [=](const char *F, std::string &V, std::string &Name, std::string & Description) ->bool { return OpLocationDB_->GetNameAndDescription(F,V, Name, Description); };
ExpandFunc_[OpContactDB_->Prefix()] = [=](const char *F, std::string &V, std::string &Name, std::string & Description) ->bool { return OpContactDB_->GetNameAndDescription(F,V, Name, Description); };
ExpandFunc_[OverridesDB_->Prefix()] = [=]( [[maybe_unused]] const char *F, [[maybe_unused]] std::string &V, [[maybe_unused]] std::string &Name, [[maybe_unused]] std::string & Description) ->bool { return false; };
InventoryDB_->InitializeSerialCache();

View File

@@ -27,6 +27,7 @@
#include "storage/storage_operataor.h"
#include "storage/storage_service_class.h"
#include "storage/storage_sub_devices.h"
#include "storage/storage_overrides.h"
#include "Poco/URI.h"
#include "framework/ow_constants.h"
@@ -64,6 +65,7 @@ namespace OpenWifi {
OpenWifi::SubscriberDeviceDB & SubscriberDeviceDB() { return *SubscriberDeviceDB_; };
OpenWifi::OpLocationDB & OpLocationDB() { return *OpLocationDB_; };
OpenWifi::OpContactDB & OpContactDB() { return *OpContactDB_; };
OpenWifi::OverridesDB & OverridesDB() { return *OverridesDB_; };
bool Validate(const Poco::URI::QueryParameters &P, RESTAPI::Errors::msg &Error);
bool Validate(const Types::StringVec &P, std::string &Error);
@@ -116,6 +118,7 @@ namespace OpenWifi {
std::unique_ptr<OpenWifi::SubscriberDeviceDB> SubscriberDeviceDB_;
std::unique_ptr<OpenWifi::OpLocationDB> OpLocationDB_;
std::unique_ptr<OpenWifi::OpContactDB> OpContactDB_;
std::unique_ptr<OpenWifi::OverridesDB> OverridesDB_;
std::string DefaultOperator_;

View File

@@ -0,0 +1,50 @@
//
// Created by stephane bourque on 2022-11-03.
//
#include "storage_overrides.h"
#include "framework/OpenWifiTypes.h"
#include "framework/RESTAPI_utils.h"
#include "SerialNumberCache.h"
namespace OpenWifi {
static ORM::FieldVec OverridesDB_Fields{
// object info
ORM::Field{"serialNumber",64, true},
ORM::Field{"managementPolicy", ORM::FieldType::FT_TEXT},
ORM::Field{"overrides", ORM::FieldType::FT_TEXT}
};
static ORM::IndexVec OverridesDB_Indexes{
};
OverridesDB::OverridesDB(OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L) :
DB(T, "overrides", OverridesDB_Fields, OverridesDB_Indexes, P, L, "ovr") {}
bool OverridesDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) {
to = Version();
std::vector<std::string> Script{
};
for (const auto &i: Script) {
try {
auto Session = Pool_.get();
Session << i, Poco::Data::Keywords::now;
} catch (...) {
}
}
return true;
}
}
template<> void ORM::DB<OpenWifi::OverridesDBRecordType, OpenWifi::ProvObjects::ConfigurationOverrideList>::Convert(const OpenWifi::OverridesDBRecordType &In, OpenWifi::ProvObjects::ConfigurationOverrideList &Out) {
Out.serialNumber = In.get<0>();
Out.managementPolicy = In.get<1>();
Out.overrides = OpenWifi::RESTAPI_utils::to_object_array<OpenWifi::ProvObjects::ConfigurationOverride>(In.get<2>());
}
template<> void ORM::DB< OpenWifi::OverridesDBRecordType, OpenWifi::ProvObjects::ConfigurationOverrideList>::Convert(const OpenWifi::ProvObjects::ConfigurationOverrideList &In, OpenWifi::OverridesDBRecordType &Out) {
Out.set<0>(In.serialNumber);
Out.set<1>(In.managementPolicy);
Out.set<2>(OpenWifi::RESTAPI_utils::to_string(In.overrides));
}

View File

@@ -0,0 +1,32 @@
//
// Created by stephane bourque on 2022-11-03.
//
#pragma once
#include "framework/orm.h"
#include "RESTObjects/RESTAPI_ProvObjects.h"
namespace OpenWifi {
typedef Poco::Tuple<
std::string,
std::string,
std::string
> OverridesDBRecordType;
class OverridesDB : public ORM::DB<OverridesDBRecordType, ProvObjects::ConfigurationOverrideList> {
public:
explicit OverridesDB( OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);
virtual ~OverridesDB() {};
inline uint32_t Version() override {
return 1;
}
bool Upgrade(uint32_t from, uint32_t &to) override;
private:
};
} // OpenWifi