Compare commits

..

4 Commits

Author SHA1 Message Date
TIP Automation User
9bc5086f24 Chg: update image tag in helm values to v2.9.0 2023-03-31 19:26:05 +00:00
TIP Automation User
71eefca353 Chg: update image tag in helm values to v2.9.0-RC2 2023-03-20 16:53:40 +00:00
Stephane Bourque
1cccd2aa73 Merge pull request #88 from Telecominfraproject/main
https://telecominfraproject.atlassian.net/browse/WIFI-12342
2023-03-02 11:30:51 -08:00
TIP Automation User
198888d554 Chg: update image tag in helm values to v2.9.0-RC1 2023-02-28 18:27:42 +00:00
61 changed files with 5396 additions and 6350 deletions

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.13)
project(owprov VERSION 2.11.0)
project(owprov VERSION 2.9.0)
set(CMAKE_CXX_STANDARD 17)
@@ -117,7 +117,6 @@ add_executable(owprov
src/framework/MicroServiceExtra.h
src/framework/ConfigurationValidator.cpp
src/framework/ConfigurationValidator.h
src/framework/default_device_types.h
src/UI_Prov_WebSocketNotifications.h
src/UI_Prov_WebSocketNotifications.cpp
src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp

2
build
View File

@@ -1 +1 @@
4
21

View File

@@ -42,7 +42,6 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
STORAGE_TYPE_MYSQL_PASSWORD=${STORAGE_TYPE_MYSQL_PASSWORD:-"owprov"} \
STORAGE_TYPE_MYSQL_DATABASE=${STORAGE_TYPE_MYSQL_DATABASE:-"owprov"} \
STORAGE_TYPE_MYSQL_PORT=${STORAGE_TYPE_MYSQL_PORT:-"3306"} \
RRM_PROVIDERS=${RRM_PROVIDERS:-"owrrm"} \
envsubst < /owprov.properties.tmpl > $OWPROV_CONFIG/owprov.properties
fi

View File

@@ -9,7 +9,7 @@ fullnameOverride: ""
images:
owprov:
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owprov
tag: v2.11.0-RC1
tag: v2.9.0
pullPolicy: Always
# regcred:
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io

View File

@@ -1331,6 +1331,12 @@ components:
- $ref: '#/components/schemas/StringList'
- $ref: '#/components/schemas/TagValuePairList'
SystemCommandResults:
type: object
oneOf:
- $ref: '#/components/schemas/StringList'
- $ref: '#/components/schemas/TagValuePairList'
NoteInfo:
type: object
properties:
@@ -1370,33 +1376,6 @@ components:
type: integer
format: int64
SystemResources:
type: object
properties:
numberOfFileDescriptors:
type: integer
format: int64
currRealMem:
type: integer
format: int64
peakRealMem:
type: integer
format: int64
currVirtMem:
type: integer
format: int64
peakVirtMem:
type: integer
format: int64
SystemCommandResults:
type: object
oneOf:
- $ref: '#/components/schemas/SystemResources'
- $ref: '#/components/schemas/SystemInfoResults'
- $ref: '#/components/schemas/StringList'
- $ref: '#/components/schemas/TagValuePairList'
Dashboard:
type: object
properties:
@@ -2279,7 +2258,7 @@ paths:
get:
tags:
- Configuration Overrides
operationId: getConfigurationOverrides
operationId: getCponfigurationOverrides
summary: retrieve a list of configuration overrides for a given device
parameters:
- in: path
@@ -2303,7 +2282,7 @@ paths:
delete:
tags:
- Configuration Overrides
operationId: deleteConfigurationOverrides
operationId: deleteCponfigurationOverrides
summary: delete all configuration overrides for a given device from a given source
parameters:
- in: path
@@ -4444,12 +4423,15 @@ paths:
type: string
enum:
- info
- extraConfiguration
- resources
required: true
responses:
200:
$ref: '#/components/schemas/SystemCommandResults'
description: Successful command execution
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/SystemInfoResults'
403:
$ref: '#/components/responses/Unauthorized'
404:

View File

@@ -37,12 +37,10 @@ openwifi.system.data = ${SYSTEM_DATA}
openwifi.system.debug = false
openwifi.system.uri.private = ${SYSTEM_URI_PRIVATE}
openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC}
openwifi.system.commandchannel = /tmp/app.owprov
openwifi.system.commandchannel = /tmp/app.ucentralfms
openwifi.system.uri.ui = ${SYSTEM_URI_UI}
openwifi.security.restapi.disable = ${SECURITY_RESTAPI_DISABLE}
rrm.providers = ${RRM_PROVIDERS}
#############################
# Generic information for all micro services
#############################

View File

@@ -41,7 +41,7 @@ namespace OpenWifi {
Payload.set("ObjectType", OT);
std::ostringstream OS;
Payload.stringify(OS);
KafkaManager()->PostMessage(KafkaTopics::PROVISIONING_CHANGE, Ops[op], std::make_shared<std::string>(OS.str()));
KafkaManager()->PostMessage(KafkaTopics::PROVISIONING_CHANGE, Ops[op], OS.str());
return true;
}

View File

@@ -90,9 +90,9 @@ namespace OpenWifi {
}
if (!Existing.contacts.empty()) {
for (const auto &contact_uuid : Existing.contacts)
for (const auto &i : Existing.contacts)
StorageService()->ContactDB().DeleteInUse(
"id", contact_uuid, StorageService()->VenueDB().Prefix(), UUID);
"id", i, StorageService()->VenueDB().Prefix(), UUID);
}
if (!Existing.location.empty())
StorageService()->LocationDB().DeleteInUse("id", Existing.location,
@@ -101,9 +101,9 @@ namespace OpenWifi {
StorageService()->PolicyDB().DeleteInUse("id", Existing.managementPolicy,
StorageService()->VenueDB().Prefix(), UUID);
if (!Existing.deviceConfiguration.empty()) {
for (auto &configuration_uuid : Existing.deviceConfiguration)
for (auto &i : Existing.deviceConfiguration)
StorageService()->ConfigurationDB().DeleteInUse(
"id", configuration_uuid, StorageService()->VenueDB().Prefix(), UUID);
"id", i, StorageService()->VenueDB().Prefix(), UUID);
}
if (!Existing.parent.empty())
StorageService()->VenueDB().DeleteChild("id", Existing.parent, UUID);
@@ -157,10 +157,6 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::EntityMustExist);
}
if(StorageService()->VenueDB().DoesVenueNameAlreadyExist(NewObject.info.name,NewObject.entity, NewObject.parent)) {
return BadRequest(RESTAPI::Errors::VenuesNameAlreadyExists);
}
if (!NewObject.contacts.empty()) {
for (const auto &i : NewObject.contacts) {
if (!StorageService()->ContactDB().Exists("id", i)) {
@@ -436,7 +432,7 @@ namespace OpenWifi {
std::string MoveFromEntity, MoveToEntity;
if (AssignIfPresent(RawObject, "entity", MoveToEntity)) {
if (MoveToEntity.empty() || !StorageService()->EntityDB().Exists("id", MoveToEntity)) {
if (!MoveToEntity.empty() && !StorageService()->EntityDB().Exists("id", MoveToEntity)) {
return BadRequest(RESTAPI::Errors::EntityMustExist);
}
MoveFromEntity = Existing.entity;
@@ -445,7 +441,7 @@ namespace OpenWifi {
std::string MoveToVenue, MoveFromVenue;
if (AssignIfPresent(RawObject, "venue", MoveToVenue)) {
if (MoveToVenue.empty() || !StorageService()->VenueDB().Exists("id", MoveToVenue)) {
if (!MoveToVenue.empty() && !StorageService()->VenueDB().Exists("id", MoveToVenue)) {
return BadRequest(RESTAPI::Errors::VenueMustExist);
}
MoveFromVenue = Existing.parent;
@@ -454,7 +450,7 @@ namespace OpenWifi {
std::string MoveFromLocation, MoveToLocation;
if (AssignIfPresent(RawObject, "location", MoveToLocation)) {
if (MoveToLocation.empty() ||
if (!MoveToLocation.empty() &&
!StorageService()->LocationDB().Exists("id", MoveToLocation)) {
return BadRequest(RESTAPI::Errors::LocationMustExist);
}
@@ -464,8 +460,8 @@ namespace OpenWifi {
Types::UUIDvec_t MoveFromContacts, MoveToContacts;
if (AssignIfPresent(RawObject, "contacts", MoveToContacts)) {
for (const auto &contact : NewObject.contacts) {
if (!StorageService()->ContactDB().Exists("id", contact)) {
for (const auto &i : NewObject.contacts) {
if (!StorageService()->ContactDB().Exists("id", i)) {
return BadRequest(RESTAPI::Errors::ContactMustExist);
}
}
@@ -475,7 +471,7 @@ namespace OpenWifi {
std::string MoveFromPolicy, MoveToPolicy;
if (AssignIfPresent(RawObject, "managementPolicy", MoveToPolicy)) {
if (MoveToPolicy.empty() || !StorageService()->PolicyDB().Exists("id", MoveToPolicy)) {
if (!MoveToPolicy.empty() && !StorageService()->PolicyDB().Exists("id", MoveToPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
MoveFromPolicy = Existing.managementPolicy;
@@ -485,8 +481,8 @@ namespace OpenWifi {
Types::UUIDvec_t MoveToConfigurations, MoveFromConfigurations;
if (RawObject->has("deviceConfiguration")) {
MoveToConfigurations = NewObject.deviceConfiguration;
for (auto &configuration : MoveToConfigurations) {
if (!StorageService()->ConfigurationDB().Exists("id", configuration)) {
for (auto &i : MoveToConfigurations) {
if (!StorageService()->ConfigurationDB().Exists("id", i)) {
return BadRequest(RESTAPI::Errors::ConfigurationMustExist);
}
}

View File

@@ -13,7 +13,6 @@
#ifdef TIP_GATEWAY_SERVICE
#include "AP_WS_Server.h"
#include "CapabilitiesCache.h"
#include "RADIUSSessionTracker.h"
#endif
#include "RESTAPI_GWobjects.h"
@@ -30,7 +29,6 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "serialNumber", SerialNumber);
#ifdef TIP_GATEWAY_SERVICE
field_to_json(Obj, "deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible));
field_to_json(Obj, "hasRADIUSSessions", RADIUSSessionTracker()->HasSessions(SerialNumber));
#endif
field_to_json(Obj, "macAddress", MACAddress);
field_to_json(Obj, "manufacturer", Manufacturer);
@@ -56,9 +54,6 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "pendingConfiguration", pendingConfiguration);
field_to_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd);
field_to_json(Obj, "restrictionDetails", restrictionDetails);
field_to_json(Obj, "pendingUUID", pendingUUID);
field_to_json(Obj, "simulated", simulated);
field_to_json(Obj, "lastRecordedContact", lastRecordedContact);
}
void Device::to_json_with_status(Poco::JSON::Object &Obj) const {
@@ -68,7 +63,7 @@ namespace OpenWifi::GWObjects {
ConnectionState ConState;
if (AP_WS_Server()->GetState(SerialNumber, ConState)) {
ConState.to_json(SerialNumber,Obj);
ConState.to_json(Obj);
} else {
field_to_json(Obj, "ipAddress", "");
field_to_json(Obj, "txBytes", (uint64_t)0);
@@ -80,13 +75,6 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "associations_2G", (uint64_t)0);
field_to_json(Obj, "associations_5G", (uint64_t)0);
field_to_json(Obj, "associations_6G", (uint64_t)0);
field_to_json(Obj, "hasRADIUSSessions", false);
field_to_json(Obj, "hasGPS", ConState.hasGPS);
field_to_json(Obj, "sanity", ConState.sanity);
field_to_json(Obj, "memoryUsed", ConState.memoryUsed);
field_to_json(Obj, "sanity", ConState.sanity);
field_to_json(Obj, "load", ConState.load);
field_to_json(Obj, "temperature", ConState.temperature);
}
#endif
}
@@ -96,32 +84,20 @@ namespace OpenWifi::GWObjects {
field_from_json(Obj, "serialNumber", SerialNumber);
field_from_json(Obj, "deviceType", DeviceType);
field_from_json(Obj, "macAddress", MACAddress);
field_from_json(Obj, "manufacturer", Manufacturer);
field_from_json(Obj, "UUID", UUID);
field_from_json(Obj, "configuration", Configuration);
field_from_json(Obj, "notes", Notes);
field_from_json(Obj, "createdTimestamp", CreationTimestamp);
field_from_json(Obj, "lastConfigurationChange", LastConfigurationChange);
field_from_json(Obj, "lastConfigurationDownload", LastConfigurationDownload);
field_from_json(Obj, "lastFWUpdate", LastFWUpdate);
field_from_json(Obj, "manufacturer", Manufacturer);
field_from_json(Obj, "owner", Owner);
field_from_json(Obj, "location", Location);
field_from_json(Obj, "venue", Venue);
field_from_json(Obj, "firmware", Firmware);
field_from_json(Obj, "compatible", Compatible);
field_from_json(Obj, "fwUpdatePolicy", FWUpdatePolicy);
field_from_json(Obj, "devicePassword", DevicePassword);
field_from_json(Obj, "subscriber", subscriber);
field_from_json(Obj, "entity", entity);
field_from_json(Obj, "modified", modified);
field_from_json(Obj, "locale", locale);
field_from_json(Obj, "restrictedDevice", restrictedDevice);
field_from_json(Obj, "pendingConfiguration", pendingConfiguration);
field_from_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd);
field_from_json(Obj, "restrictionDetails", restrictionDetails);
field_from_json(Obj, "pendingUUID", pendingUUID);
field_from_json(Obj, "simulated", simulated);
field_from_json(Obj, "lastRecordedContact", lastRecordedContact);
return true;
} catch (const Poco::Exception &E) {
}
@@ -189,8 +165,6 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "waitingForFile", WaitingForFile);
field_to_json(Obj, "attachFile", AttachDate);
field_to_json(Obj, "executionTime", executionTime);
field_to_json(Obj, "lastTry", lastTry);
field_to_json(Obj, "deferred", deferred);
}
bool DefaultConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -224,7 +198,7 @@ namespace OpenWifi::GWObjects {
return false;
}
void ConnectionState::to_json([[maybe_unused]] const std::string &SerialNumber, Poco::JSON::Object &Obj) {
void ConnectionState::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "ipAddress", Address);
field_to_json(Obj, "txBytes", TX);
field_to_json(Obj, "rxBytes", RX);
@@ -246,20 +220,6 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "connectionCompletionTime", connectionCompletionTime);
field_to_json(Obj, "totalConnectionTime", Utils::Now() - started);
field_to_json(Obj, "certificateExpiryDate", certificateExpiryDate);
#ifdef TIP_GATEWAY_SERVICE
hasRADIUSSessions = RADIUSSessionTracker()->HasSessions(SerialNumber);
AP_WS_Server()->ExtendedAttributes(SerialNumber, hasGPS, sanity,
memoryUsed,
load,
temperature);
#endif
field_to_json(Obj, "hasRADIUSSessions", hasRADIUSSessions );
field_to_json(Obj, "hasGPS", hasGPS);
field_to_json(Obj, "sanity", sanity);
field_to_json(Obj, "memoryUsed", memoryUsed);
field_to_json(Obj, "sanity", sanity);
field_to_json(Obj, "load", load);
field_to_json(Obj, "temperature", temperature);
switch (VerifiedCertificate) {
case NO_CERTIFICATE:
@@ -274,9 +234,6 @@ namespace OpenWifi::GWObjects {
case VERIFIED:
field_to_json(Obj, "verifiedCertificate", "VERIFIED");
break;
case SIMULATED:
field_to_json(Obj, "verifiedCertificate", "SIMULATED");
break;
default:
field_to_json(Obj, "verifiedCertificate", "NO_CERTIFICATE");
break;
@@ -533,29 +490,6 @@ namespace OpenWifi::GWObjects {
return false;
}
void RangeOptions::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "NO_IR", NO_IR);
field_to_json(Obj, "AUTO_BW", AUTO_BW);
field_to_json(Obj, "DFS", DFS);
field_to_json(Obj, "NO_OUTDOOR", NO_OUTDOOR);
field_to_json(Obj, "wmmrule_ETSI", wmmrule_ETSI);
field_to_json(Obj, "NO_OFDM", NO_OFDM);
}
void FrequencyRange::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "from", from);
field_to_json(Obj, "to", to);
field_to_json(Obj, "channelWidth", channelWidth);
field_to_json(Obj, "powerDb", powerDb);
field_to_json(Obj, "options", options);
}
void RegulatoryCountryInfo::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "country", country);
field_to_json(Obj, "domain", domain);
field_to_json(Obj, "ranges", ranges);
}
void DeviceRestrictionsKeyInfo::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "vendor", vendor);
field_to_json(Obj, "algo", algo);
@@ -610,42 +544,4 @@ namespace OpenWifi::GWObjects {
(T.commands != commands) || (T.developer != developer) || (T.ssh != ssh) ||
(T.key_info != key_info) || (T.country != country));
}
void RADIUSSession::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "started", started);
field_to_json(Obj, "lastTransaction", lastTransaction);
field_to_json(Obj, "destination", destination);
field_to_json(Obj, "serialNumber", serialNumber);
field_to_json(Obj, "userName", userName);
field_to_json(Obj, "accountingSessionId", accountingSessionId);
field_to_json(Obj, "accountingMultiSessionId", accountingMultiSessionId);
field_to_json(Obj, "inputPackets", inputPackets);
field_to_json(Obj, "outputPackets", outputPackets);
field_to_json(Obj, "inputOctets", inputOctets);
field_to_json(Obj, "outputOctets", outputOctets);
field_to_json(Obj, "inputGigaWords", inputGigaWords);
field_to_json(Obj, "outputGigaWords", outputGigaWords);
field_to_json(Obj, "sessionTime", sessionTime);
field_to_json(Obj, "callingStationId", callingStationId);
field_to_json(Obj, "chargeableUserIdentity", chargeableUserIdentity);
field_to_json(Obj, "interface", interface);
field_to_json(Obj, "secret", secret);
}
void RADIUSSessionList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "sessions", sessions);
}
bool RadiusCoADMParameters::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "accountingSessionId", accountingSessionId);
field_from_json(Obj, "accountingMultiSessionId", accountingMultiSessionId);
field_from_json(Obj, "callingStationId", callingStationId);
field_from_json(Obj, "chargeableUserIdentity", chargeableUserIdentity);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
} // namespace OpenWifi::GWObjects

View File

@@ -11,13 +11,9 @@
#include "Poco/JSON/Object.h"
#include "RESTAPI_SecurityObjects.h"
#ifdef TIP_GATEWAY_SERVICE
#include <RADIUS_helpers.h>
#endif
namespace OpenWifi::GWObjects {
enum CertificateValidation { NO_CERTIFICATE, VALID_CERTIFICATE, MISMATCH_SERIAL, VERIFIED, SIMULATED };
enum CertificateValidation { NO_CERTIFICATE, VALID_CERTIFICATE, MISMATCH_SERIAL, VERIFIED };
struct ConnectionState {
uint64_t MessageCount = 0;
@@ -42,14 +38,8 @@ namespace OpenWifi::GWObjects {
uint64_t sessionId = 0;
double connectionCompletionTime = 0.0;
std::uint64_t certificateExpiryDate = 0;
bool hasRADIUSSessions = false;
bool hasGPS = false;
std::uint64_t sanity=0;
std::double_t memoryUsed=0.0;
std::double_t load=0.0;
std::double_t temperature=0.0;
void to_json(const std::string &SerialNumber, Poco::JSON::Object &Obj) ;
void to_json(Poco::JSON::Object &Obj) const;
};
struct DeviceRestrictionsKeyInfo {
@@ -106,9 +96,6 @@ namespace OpenWifi::GWObjects {
std::string pendingConfiguration;
std::string pendingConfigurationCmd;
DeviceRestrictions restrictionDetails;
std::uint64_t pendingUUID = 0;
bool simulated=false;
std::uint64_t lastRecordedContact=0;
void to_json(Poco::JSON::Object &Obj) const;
void to_json_with_status(Poco::JSON::Object &Obj) const;
@@ -201,11 +188,7 @@ namespace OpenWifi::GWObjects {
uint64_t AttachSize = 0;
std::string AttachType;
double executionTime = 0.0;
std::uint64_t lastTry = 0;
bool deferred = false;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct BlackListedDevice {
@@ -351,76 +334,4 @@ namespace OpenWifi::GWObjects {
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RangeOptions {
bool NO_IR=false;
bool AUTO_BW=false;
bool DFS=false;
bool NO_OUTDOOR=false;
bool wmmrule_ETSI=false;
bool NO_OFDM=false;
void to_json(Poco::JSON::Object &Obj) const;
};
struct FrequencyRange {
float from = 0.0;
float to = 0.0;
int channelWidth = 0;
int powerDb = 0;
RangeOptions options;
void to_json(Poco::JSON::Object &Obj) const;
};
struct RegulatoryCountryInfo {
std::string country;
std::string domain;
std::vector<FrequencyRange> ranges;
void to_json(Poco::JSON::Object &Obj) const;
};
using RegulatoryInfoCountryMap = std::map<std::string,RegulatoryCountryInfo>;
struct RADIUSSession {
std::uint64_t started=0,
lastTransaction=0;
std::string serialNumber,
destination,
userName,
accountingSessionId,
accountingMultiSessionId,
callingStationId,
chargeableUserIdentity,
secret,
interface;
std::uint64_t inputPackets = 0,
outputPackets = 0,
inputOctets = 0,
outputOctets = 0,
inputGigaWords = 0,
outputGigaWords = 0;
std::uint32_t sessionTime = 0;
#ifdef TIP_GATEWAY_SERVICE
RADIUS::RadiusPacket accountingPacket;
#endif
void to_json(Poco::JSON::Object &Obj) const;
};
struct RADIUSSessionList {
std::vector<RADIUSSession> sessions;
void to_json(Poco::JSON::Object &Obj) const;
};
struct RadiusCoADMParameters {
std::string accountingSessionId,
accountingMultiSessionId,
callingStationId,
chargeableUserIdentity;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
} // namespace OpenWifi::GWObjects

View File

@@ -4,19 +4,17 @@
#include "ALBserver.h"
#include "fmt/format.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/utils.h"
#include "framework/MicroServiceFuncs.h"
#include "fmt/format.h"
namespace OpenWifi {
void ALBRequestHandler::handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response) {
void ALBRequestHandler::handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) {
Utils::SetThreadName("alb-request");
try {
if((id_ % 100) == 0) {
Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.",
Request.clientAddress().toString(), id_));
Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.", Request.clientAddress().toString(), id_));
}
Response.setChunkedTransferEncoding(true);
Response.setContentType("text/html");
@@ -26,23 +24,27 @@ namespace OpenWifi {
Response.set("Connection", "keep-alive");
Response.setVersion(Poco::Net::HTTPMessage::HTTP_1_1);
std::ostream &Answer = Response.send();
Answer << ALBHealthCheckServer()->CallbackText();
Answer << "process Alive and kicking!";
} catch (...) {
}
}
ALBRequestHandlerFactory::ALBRequestHandlerFactory(Poco::Logger &L) : Logger_(L) {}
ALBRequestHandlerFactory::ALBRequestHandlerFactory(Poco::Logger & L):
Logger_(L) {
}
ALBRequestHandler *
ALBRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &request) {
ALBRequestHandler* ALBRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest& request) {
if (request.getURI() == "/")
return new ALBRequestHandler(Logger_, req_id_++);
else
return nullptr;
}
ALBHealthCheckServer::ALBHealthCheckServer()
: SubSystemServer("ALBHealthCheckServer", "ALB-SVR", "alb") {}
ALBHealthCheckServer::ALBHealthCheckServer() :
SubSystemServer("ALBHealthCheckServer", "ALB-SVR", "alb")
{
}
int ALBHealthCheckServer::Start() {
if(MicroServiceConfigGetBool("alb.enable",false)) {
@@ -58,8 +60,7 @@ namespace OpenWifi {
Socket_ = std::make_unique<Poco::Net::ServerSocket>(SockAddr, Port_);
auto Params = new Poco::Net::HTTPServerParams;
Params->setName("ws:alb");
Server_ = std::make_unique<Poco::Net::HTTPServer>(
new ALBRequestHandlerFactory(Logger()), *Socket_, Params);
Server_ = std::make_unique<Poco::Net::HTTPServer>(new ALBRequestHandlerFactory(Logger()), *Socket_, Params);
Server_->start();
}

View File

@@ -7,38 +7,37 @@
#include "framework/SubSystemServer.h"
#include "Poco/Net/HTTPRequestHandler.h"
#include "Poco/Net/HTTPRequestHandlerFactory.h"
#include "Poco/Net/HTTPServer.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
#include "Poco/Net/HTTPRequestHandlerFactory.h"
#include "Poco/Net/HTTPServer.h"
namespace OpenWifi {
class ALBRequestHandler: public Poco::Net::HTTPRequestHandler {
public:
explicit ALBRequestHandler(Poco::Logger &L, uint64_t id) : Logger_(L), id_(id) {}
explicit ALBRequestHandler(Poco::Logger & L, uint64_t id)
: Logger_(L), id_(id) {
}
void handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response) override;
void handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override;
private:
Poco::Logger & Logger_;
uint64_t id_;
};
class ALBRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
class ALBRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory
{
public:
explicit ALBRequestHandlerFactory(Poco::Logger & L);
ALBRequestHandler *
createRequestHandler(const Poco::Net::HTTPServerRequest &request) override;
ALBRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request) override;
private:
Poco::Logger &Logger_;
inline static std::atomic_uint64_t req_id_=1;
};
typedef std::string ALBHealthMessageCallback();
class ALBHealthCheckServer : public SubSystemServer {
public:
ALBHealthCheckServer();
@@ -50,22 +49,10 @@ namespace OpenWifi {
int Start() override;
void Stop() override;
inline void RegisterExtendedHealthMessage(ALBHealthMessageCallback *F) {
Callback_=F;
};
inline std::string CallbackText() {
if(Callback_== nullptr) {
return "process Alive and kicking!";
} else {
return Callback_();
}
}
private:
std::unique_ptr<Poco::Net::HTTPServer> Server_;
std::unique_ptr<Poco::Net::ServerSocket> Socket_;
ALBHealthMessageCallback *Callback_= nullptr;
int Port_ = 0;
mutable std::atomic_bool Running_=false;
};
@@ -73,3 +60,4 @@ namespace OpenWifi {
inline auto ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); }
} // namespace OpenWifi

View File

@@ -4,19 +4,22 @@
#pragma once
#include "Poco/JSON/Parser.h"
#include "Poco/Logger.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/JSON/Parser.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/URI.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
inline void API_Proxy(Poco::Logger &Logger, Poco::Net::HTTPServerRequest *Request,
Poco::Net::HTTPServerResponse *Response, const char *ServiceType,
const char *PathRewrite, uint64_t msTimeout_ = 10000) {
inline void API_Proxy( Poco::Logger &Logger,
Poco::Net::HTTPServerRequest *Request,
Poco::Net::HTTPServerResponse *Response,
const char * ServiceType,
const char * PathRewrite,
uint64_t msTimeout_ = 10000 ) {
try {
auto Services = MicroServiceGetServices(ServiceType);
for(auto const &Svc:Services) {
@@ -28,8 +31,7 @@ namespace OpenWifi {
// std::cout << " Source: " << SourceURI.toString() << std::endl;
// std::cout << "Destination: " << DestinationURI.toString() << std::endl;
Poco::Net::HTTPSClientSession Session(DestinationURI.getHost(),
DestinationURI.getPort());
Poco::Net::HTTPSClientSession Session(DestinationURI.getHost(), DestinationURI.getPort());
Session.setKeepAlive(true);
Session.setTimeout(Poco::Timespan(msTimeout_/1000, msTimeout_ % 1000));
Poco::Net::HTTPRequest ProxyRequest(Request->getMethod(),
@@ -74,8 +76,7 @@ namespace OpenWifi {
try {
std::istream &ProxyResponseStream = Session.receiveResponse(ProxyResponse);
Poco::JSON::Parser P2;
auto ProxyResponseBody =
P2.parse(ProxyResponseStream).extract<Poco::JSON::Object::Ptr>();
auto ProxyResponseBody = P2.parse(ProxyResponseStream).extract<Poco::JSON::Object::Ptr>();
Poco::JSON::Stringifier::condense(ProxyResponseBody,SSR);
Response->setContentType("application/json");
Response->setContentLength(SSR.str().size());
@@ -83,6 +84,7 @@ namespace OpenWifi {
Response->sendBuffer(SSR.str().c_str(),SSR.str().size());
return;
} catch( const Poco::Exception & E) {
}
Response->setStatus(ProxyResponse.getStatus());
Response->send();
@@ -94,4 +96,4 @@ namespace OpenWifi {
Logger.log(E);
}
}
} // namespace OpenWifi
}

View File

@@ -4,13 +4,13 @@
#pragma once
#include <string>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#include "Poco/File.h"
#include "Poco/StreamCopier.h"
#include "Poco/File.h"
#include "framework/MicroServiceFuncs.h"
@@ -18,6 +18,7 @@
namespace OpenWifi {
class AppServiceRegistry {
public:
AppServiceRegistry() {
@@ -41,7 +42,9 @@ namespace OpenWifi {
return *instance_;
}
inline ~AppServiceRegistry() { Save(); }
inline ~AppServiceRegistry() {
Save();
}
inline void Save() {
std::istringstream IS( to_string(Registry_));
@@ -96,4 +99,4 @@ namespace OpenWifi {
inline auto AppServiceRegistry() { return AppServiceRegistry::instance(); }
} // namespace OpenWifi
}

View File

@@ -4,27 +4,28 @@
#include "Poco/Net/HTTPServerResponse.h"
#include "fmt/format.h"
#include "framework/AuthClient.h"
#include "framework/MicroServiceNames.h"
#include "framework/OpenAPIRequests.h"
#include "framework/utils.h"
#include "fmt/format.h"
namespace OpenWifi {
bool AuthClient::RetrieveTokenInformation(const std::string & SessionToken,
SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID, bool &Expired, bool &Contacted,
bool Sub) {
std::uint64_t TID,
bool & Expired, bool & Contacted, bool Sub) {
try {
Types::StringPairVec QueryData;
QueryData.push_back(std::make_pair("token",SessionToken));
std::string AlternateURIForLogging = fmt::format(
"{}?token={}", Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken",
Utils::SanitizeToken(SessionToken));
std::string AlternateURIForLogging = fmt::format("{}?token={}", Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken", Utils::SanitizeToken(SessionToken));
OpenAPIRequestGet Req( uSERVICE_SECURITY,
Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken",
QueryData, 10000, AlternateURIForLogging);
QueryData,
10000,
AlternateURIForLogging
);
Poco::JSON::Object::Ptr Response;
auto StatusCode = Req.Do(Response);
@@ -49,15 +50,14 @@ namespace OpenWifi {
}
}
} catch (...) {
poco_error(Logger(), fmt::format("Failed to retrieve token={} for TID={}",
Utils::SanitizeToken(SessionToken), TID));
poco_error(Logger(),fmt::format("Failed to retrieve token={} for TID={}", Utils::SanitizeToken(SessionToken), TID));
}
Expired = false;
return false;
}
bool AuthClient::IsAuthorized(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
bool AuthClient::IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, bool Sub) {
auto User = Cache_.get(SessionToken);
if(!User.isNull()) {
@@ -75,14 +75,16 @@ namespace OpenWifi {
bool AuthClient::RetrieveApiKeyInformation(const std::string & SessionToken,
SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID, bool &Expired, bool &Contacted,
[[maybe_unused]] bool &Suspended) {
std::uint64_t TID,
bool & Expired, bool & Contacted, [[maybe_unused]] bool & Suspended) {
try {
Types::StringPairVec QueryData;
QueryData.push_back(std::make_pair("apikey",SessionToken));
std::string AlternateURIForLogging =
fmt::format("/api/v1/validateApiKey?apiKey={}", Utils::SanitizeToken(SessionToken));
OpenAPIRequestGet Req(uSERVICE_SECURITY, "/api/v1/validateApiKey", QueryData, 10000,
std::string AlternateURIForLogging = fmt::format("/api/v1/validateApiKey?apiKey={}", Utils::SanitizeToken(SessionToken));
OpenAPIRequestGet Req( uSERVICE_SECURITY,
"/api/v1/validateApiKey" ,
QueryData,
10000,
AlternateURIForLogging);
Poco::JSON::Object::Ptr Response;
@@ -94,29 +96,24 @@ namespace OpenWifi {
Contacted = true;
if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_OK) {
if (Response->has("tokenInfo") && Response->has("userInfo") &&
Response->has("expiresOn")) {
if(Response->has("tokenInfo") && Response->has("userInfo") && Response->has("expiresOn")) {
UInfo.from_json(Response);
Expired = false;
ApiKeyCache_.update(SessionToken,
ApiKeyCacheEntry{.UserInfo = UInfo,
.ExpiresOn = Response->get("expiresOn")});
ApiKeyCache_.update(SessionToken, ApiKeyCacheEntry{ .UserInfo = UInfo, .ExpiresOn = Response->get("expiresOn")});
return true;
} else {
return false;
}
}
} catch (...) {
poco_error(Logger(), fmt::format("Failed to retrieve api key={} for TID={}",
Utils::SanitizeToken(SessionToken), TID));
poco_error(Logger(),fmt::format("Failed to retrieve api key={} for TID={}", Utils::SanitizeToken(SessionToken), TID));
}
Expired = false;
return false;
}
bool AuthClient::IsValidApiKey(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
bool &Expired, bool &Contacted, bool &Suspended) {
bool AuthClient::IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy &UInfo,
std::uint64_t TID, bool &Expired, bool &Contacted, bool & Suspended) {
auto User = ApiKeyCache_.get(SessionToken);
if (!User.isNull()) {
if(User->ExpiresOn < Utils::Now()) {

View File

@@ -4,9 +4,9 @@
#pragma once
#include "Poco/ExpireLRUCache.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#include "framework/SubSystemServer.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#include "Poco/ExpireLRUCache.h"
#include "framework/utils.h"
namespace OpenWifi {
@@ -14,8 +14,10 @@ namespace OpenWifi {
class AuthClient : public SubSystemServer {
public:
explicit AuthClient() noexcept
: SubSystemServer("Authentication", "AUTH-CLNT", "authentication") {}
explicit AuthClient() noexcept:
SubSystemServer("Authentication", "AUTH-CLNT", "authentication")
{
}
static auto instance() {
static auto instance_ = new AuthClient;
@@ -27,7 +29,9 @@ namespace OpenWifi {
std::uint64_t ExpiresOn;
};
inline int Start() override { return 0; }
inline int Start() override {
return 0;
}
inline void Stop() override {
poco_information(Logger(),"Stopping...");
@@ -46,27 +50,30 @@ namespace OpenWifi {
}
bool RetrieveTokenInformation(const std::string & SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, bool Sub=false);
bool RetrieveApiKeyInformation(const std::string & SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, bool & Suspended);
bool IsAuthorized(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, bool Sub = false);
bool IsValidApiKey(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
bool IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, bool & Suspended) ;
private:
Poco::ExpireLRUCache<std::string, OpenWifi::SecurityObjects::UserInfoAndPolicy> Cache_{
512, 1200000};
Poco::ExpireLRUCache<std::string,OpenWifi::SecurityObjects::UserInfoAndPolicy> Cache_{512,1200000 };
Poco::ExpireLRUCache<std::string,ApiKeyCacheEntry> ApiKeyCache_{512,1200000 };
};
inline auto AuthClient() { return AuthClient::instance(); }
} // namespace OpenWifi

View File

@@ -152,4 +152,4 @@ namespace OpenWifi::CIDR {
[[nodiscard]] inline bool ValidateIpRanges(const Types::StringVec &Ranges) {
return std::all_of(cbegin(Ranges), cend(Ranges), ValidateRange);
}
} // namespace OpenWifi::CIDR
}

View File

@@ -2,8 +2,8 @@
// Created by stephane bourque on 2021-09-14.
//
#include <fstream>
#include <iostream>
#include <fstream>
#include <regex>
#include "ConfigurationValidator.h"
@@ -17,15 +17,14 @@
#include "fmt/format.h"
#include <valijson/adapters/poco_json_adapter.hpp>
#include <valijson/constraints/constraint.hpp>
#include <valijson/utils/poco_json_utils.hpp>
#include <valijson/schema.hpp>
#include <valijson/schema_parser.hpp>
#include <valijson/utils/poco_json_utils.hpp>
#include <valijson/validator.hpp>
#include <valijson/constraints/constraint.hpp>
static const std::string GitUCentralJSONSchemaFile{
"https://raw.githubusercontent.com/Telecominfraproject/wlan-ucentral-schema/main/"
"ucentral.schema.json"};
"https://raw.githubusercontent.com/Telecominfraproject/wlan-ucentral-schema/main/ucentral.schema.json"};
static std::string DefaultUCentralSchema = R"foo(
@@ -37,10 +36,6 @@ static std::string DefaultUCentralSchema = R"foo(
"uuid": {
"type": "integer"
},
"public_ip_lookup": {
"type": "string",
"format": "uc-fqdn"
},
"unit": {
"$ref": "#/$defs/unit"
},
@@ -638,6 +633,26 @@ static std::string DefaultUCentralSchema = R"foo(
"type": "string",
"format": "uc-timeout",
"default": "6h"
},
"relay-server": {
"type": "string",
"format": "ipv4",
"example": "192.168.2.1"
},
"circuit-id-format": {
"type": "string",
"example": [
"\\{Interface\\}:\\{VLAN-Id\\}:\\{SSID\\}:\\{Model\\}:\\{Name\\}:\\{AP-MAC\\}:\\{Location\\}",
"\\{AP-MAC\\};\\{SSID\\};\\{Crypto\\}",
"\\{Name\\} \\{ESSID\\}"
]
},
"remote-id-format": {
"type": "string",
"example": [
"\\{Client-MAC-hex\\} \\{SSID\\}",
"\\{AP-MAC-hex\\} \\{SSID\\}"
]
}
}
},
@@ -1216,32 +1231,6 @@ static std::string DefaultUCentralSchema = R"foo(
"secret"
]
},
"secondary": {
"type": "object",
"properties": {
"host": {
"type": "string",
"format": "uc-host",
"examples": [
"192.168.1.10"
]
},
"port": {
"type": "integer",
"maximum": 65535,
"minimum": 1024,
"examples": [
1812
]
},
"secret": {
"type": "string",
"examples": [
"secret"
]
}
}
},
"request-attribute": {
"type": "array",
"items": {
@@ -1319,25 +1308,6 @@ static std::string DefaultUCentralSchema = R"foo(
"value": "Example Operator"
}
]
},
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"maximum": 255,
"minimum": 1
},
"hex-value": {
"type": "string"
}
},
"examples": [
{
"id": 32,
"value": "0a0b0c0d"
}
]
}
]
}
@@ -1687,236 +1657,6 @@ static std::string DefaultUCentralSchema = R"foo(
}
}
},
"service.captive.click": {
"type": "object",
"properties": {
"auth-mode": {
"type": "string",
"const": "click-to-continue"
}
}
},
"service.captive.radius": {
"type": "object",
"properties": {
"auth-mode": {
"type": "string",
"const": "radius"
},
"auth-server": {
"type": "string",
"format": "uc-host",
"examples": [
"192.168.1.10"
]
},
"auth-port": {
"type": "integer",
"maximum": 65535,
"minimum": 1024,
"default": 1812
},
"auth-secret": {
"type": "string",
"examples": [
"secret"
]
},
"acct-server": {
"type": "string",
"format": "uc-host",
"examples": [
"192.168.1.10"
]
},
"acct-port": {
"type": "integer",
"maximum": 65535,
"minimum": 1024,
"default": 1812
},
"acct-secret": {
"type": "string",
"examples": [
"secret"
]
},
"acct-interval": {
"type": "integer",
"default": 600
}
}
},
"service.captive.credentials": {
"type": "object",
"properties": {
"auth-mode": {
"type": "string",
"const": "credentials"
},
"credentials": {
"type": "array",
"items": {
"type": "object",
"properties": {
"username": {
"type": "string"
},
"password": {
"type": "string"
}
}
}
}
}
},
"service.captive.uam": {
"type": "object",
"properties": {
"auth-mode": {
"type": "string",
"const": "uam"
},
"uam-port": {
"type": "integer",
"maximum": 65535,
"minimum": 1024,
"default": 3990
},
"uam-secret": {
"type": "string"
},
"uam-server": {
"type": "string"
},
"nasid": {
"type": "string"
},
"nasmac": {
"type": "string"
},
"auth-server": {
"type": "string",
"format": "uc-host",
"examples": [
"192.168.1.10"
]
},
"auth-port": {
"type": "integer",
"maximum": 65535,
"minimum": 1024,
"default": 1812
},
"auth-secret": {
"type": "string",
"examples": [
"secret"
]
},
"acct-server": {
"type": "string",
"format": "uc-host",
"examples": [
"192.168.1.10"
]
},
"acct-port": {
"type": "integer",
"maximum": 65535,
"minimum": 1024,
"default": 1812
},
"acct-secret": {
"type": "string",
"examples": [
"secret"
]
},
"acct-interval": {
"type": "integer",
"default": 600
},
"ssid": {
"type": "string"
},
"mac-format": {
"type": "string",
"enum": [
"aabbccddeeff",
"aa-bb-cc-dd-ee-ff",
"aa:bb:cc:dd:ee:ff",
"AABBCCDDEEFF",
"AA:BB:CC:DD:EE:FF",
"AA-BB-CC-DD-EE-FF"
]
},
"final-redirect-url": {
"type": "string",
"enum": [
"default",
"uam"
]
},
"mac-auth": {
"type": "boolean",
"default": "default"
},
"radius-gw-proxy": {
"type": "boolean",
"default": false
}
}
},
"service.captive": {
"allOf": [
{
"oneOf": [
{
"$ref": "#/$defs/service.captive.click"
},
{
"$ref": "#/$defs/service.captive.radius"
},
{
"$ref": "#/$defs/service.captive.credentials"
},
{
"$ref": "#/$defs/service.captive.uam"
}
]
},
{
"type": "object",
"properties": {
"walled-garden-fqdn": {
"type": "array",
"items": {
"type": "string"
}
},
"walled-garden-ipaddr": {
"type": "array",
"items": {
"type": "string",
"format": "uc-ip"
}
},
"web-root": {
"type": "string",
"format": "uc-base64"
},
"idle-timeout": {
"type": "integer",
"default": 600
},
"session-timeout": {
"type": "integer"
}
}
}
]
},
"interface.ssid": {
"type": "object",
"properties": {
@@ -1969,10 +1709,6 @@ static std::string DefaultUCentralSchema = R"foo(
"isolate-clients": {
"type": "boolean"
},
"strict-forwarding": {
"type": "boolean",
"default": false
},
"power-save": {
"type": "boolean"
},
@@ -2041,15 +1777,8 @@ static std::string DefaultUCentralSchema = R"foo(
"$ref": "#/$defs/interface.ssid.rate-limit"
},
"roaming": {
"anyOf": [
{
"$ref": "#/$defs/interface.ssid.roaming"
},
{
"type": "boolean"
}
]
},
"radius": {
"$ref": "#/$defs/interface.ssid.radius"
},
@@ -2065,9 +1794,6 @@ static std::string DefaultUCentralSchema = R"foo(
"access-control-list": {
"$ref": "#/$defs/interface.ssid.acl"
},
"captive": {
"$ref": "#/$defs/service.captive"
},
"hostapd-bss-raw": {
"type": "array",
"items": {
@@ -2235,17 +1961,6 @@ static std::string DefaultUCentralSchema = R"foo(
]
}
},
"vlan-awareness": {
"type": "object",
"properties": {
"first": {
"type": "integer"
},
"last": {
"type": "integer"
}
}
},
"vlan": {
"$ref": "#/$defs/interface.vlan"
},
@@ -2368,10 +2083,6 @@ static std::string DefaultUCentralSchema = R"foo(
"examples": [
"01234567890123456789012345678901"
]
},
"mutual-tls": {
"type": "boolean",
"default": true
}
}
},
@@ -2981,6 +2692,236 @@ static std::string DefaultUCentralSchema = R"foo(
}
}
},
"service.captive.click": {
"type": "object",
"properties": {
"auth-mode": {
"type": "string",
"const": "click-to-continue"
}
}
},
"service.captive.radius": {
"type": "object",
"properties": {
"auth-mode": {
"type": "string",
"const": "radius"
},
"auth-server": {
"type": "string",
"format": "uc-host",
"examples": [
"192.168.1.10"
]
},
"auth-port": {
"type": "integer",
"maximum": 65535,
"minimum": 1024,
"default": 1812
},
"auth-secret": {
"type": "string",
"examples": [
"secret"
]
},
"acct-server": {
"type": "string",
"format": "uc-host",
"examples": [
"192.168.1.10"
]
},
"acct-port": {
"type": "integer",
"maximum": 65535,
"minimum": 1024,
"default": 1812
},
"acct-secret": {
"type": "string",
"examples": [
"secret"
]
},
"acct-interval": {
"type": "integer",
"default": 600
}
}
},
"service.captive.credentials": {
"type": "object",
"properties": {
"auth-mode": {
"type": "string",
"const": "credentials"
},
"credentials": {
"type": "array",
"items": {
"type": "object",
"properties": {
"username": {
"type": "string"
},
"password": {
"type": "string"
}
}
}
}
}
},
"service.captive.uam": {
"type": "object",
"properties": {
"auth-mode": {
"type": "string",
"const": "uam"
},
"uam-port": {
"type": "integer",
"maximum": 65535,
"minimum": 1024,
"default": 3990
},
"uam-secret": {
"type": "string"
},
"uam-server": {
"type": "string"
},
"nasid": {
"type": "string"
},
"nasmac": {
"type": "string"
},
"auth-server": {
"type": "string",
"format": "uc-host",
"examples": [
"192.168.1.10"
]
},
"auth-port": {
"type": "integer",
"maximum": 65535,
"minimum": 1024,
"default": 1812
},
"auth-secret": {
"type": "string",
"examples": [
"secret"
]
},
"acct-server": {
"type": "string",
"format": "uc-host",
"examples": [
"192.168.1.10"
]
},
"acct-port": {
"type": "integer",
"maximum": 65535,
"minimum": 1024,
"default": 1812
},
"acct-secret": {
"type": "string",
"examples": [
"secret"
]
},
"acct-interval": {
"type": "integer",
"default": 600
},
"ssid": {
"type": "string"
},
"mac-format": {
"type": "string",
"enum": [
"aabbccddeeff",
"aa-bb-cc-dd-ee-ff",
"aa:bb:cc:dd:ee:ff",
"AABBCCDDEEFF",
"AA:BB:CC:DD:EE:FF",
"AA-BB-CC-DD-EE-FF"
]
},
"final-redirect-url": {
"type": "string",
"enum": [
"default",
"uam"
]
},
"mac-auth": {
"type": "boolean",
"default": "default"
},
"radius-gw-proxy": {
"type": "boolean",
"default": false
}
}
},
"service.captive": {
"allOf": [
{
"oneOf": [
{
"$ref": "#/$defs/service.captive.click"
},
{
"$ref": "#/$defs/service.captive.radius"
},
{
"$ref": "#/$defs/service.captive.credentials"
},
{
"$ref": "#/$defs/service.captive.uam"
}
]
},
{
"type": "object",
"properties": {
"walled-garden-fqdn": {
"type": "array",
"items": {
"type": "string"
}
},
"walled-garden-ipaddr": {
"type": "array",
"items": {
"type": "string",
"format": "uc-ip"
}
},
"web-root": {
"type": "string",
"format": "uc-base64"
},
"idle-timeout": {
"type": "integer",
"default": 600
},
"session-timeout": {
"type": "integer"
}
}
}
]
},
"service.gps": {
"type": "object",
"properties": {
@@ -2999,32 +2940,6 @@ static std::string DefaultUCentralSchema = R"foo(
}
}
},
"service.dhcp-relay": {
"type": "object",
"properties": {
"select-ports": {
"type": "array",
"items": {
"type": "string"
}
},
"vlans": {
"type": "array",
"items": {
"type": "object",
"properties": {
"vlan": {
"type": "number"
},
"relay-server": {
"type": "string",
"format": "uc-ip"
}
}
}
}
}
},
"service": {
"type": "object",
"properties": {
@@ -3084,9 +2999,6 @@ static std::string DefaultUCentralSchema = R"foo(
},
"gps": {
"$ref": "#/$defs/service.gps"
},
"dhcp-relay": {
"$ref": "#/$defs/service.dhcp-relay"
}
}
},
@@ -3179,20 +3091,6 @@ static std::string DefaultUCentralSchema = R"foo(
}
}
},
"metrics.wifi-scan": {
"type": "object",
"properties": {
"interval": {
"type": "integer"
},
"verbose": {
"type": "boolean"
},
"information-elements": {
"type": "boolean"
}
}
},
"metrics.telemetry": {
"type": "object",
"properties": {
@@ -3202,27 +3100,7 @@ static std::string DefaultUCentralSchema = R"foo(
"types": {
"type": "array",
"items": {
"type": "string",
"enum": [
"ssh",
"health",
"health.dns",
"health.dhcp",
"health.radius",
"health.memory",
"client",
"client.join",
"client.leave",
"client.key-mismatch",
"wifi",
"wifi.start",
"wifi.stop",
"wired",
"wired.carrier-up",
"wired.carrier-down",
"unit",
"unit.boot-up"
]
"type": "string"
}
}
}
@@ -3233,27 +3111,7 @@ static std::string DefaultUCentralSchema = R"foo(
"types": {
"type": "array",
"items": {
"type": "string",
"enum": [
"ssh",
"health",
"health.dns",
"health.dhcp",
"health.radius",
"health.memory",
"client",
"client.join",
"client.leave",
"client.key-mismatch",
"wifi",
"wifi.start",
"wifi.stop",
"wired",
"wired.carrier-up",
"wired.carrier-down",
"unit",
"unit.boot-up"
]
"type": "string"
}
}
}
@@ -3273,9 +3131,6 @@ static std::string DefaultUCentralSchema = R"foo(
"dhcp-snooping": {
"$ref": "#/$defs/metrics.dhcp-snooping"
},
"wifi-scan": {
"$ref": "#/$defs/metrics.wifi-scan"
},
"telemetry": {
"$ref": "#/$defs/metrics.telemetry"
},
@@ -3329,6 +3184,7 @@ static std::string DefaultUCentralSchema = R"foo(
)foo";
static inline bool IsIPv4(const std::string &value) {
Poco::Net::IPAddress A;
return ((Poco::Net::IPAddress::tryParse(value, A) && A.family() == Poco::Net::IPAddress::IPv4));
@@ -3386,68 +3242,57 @@ bool ExternalValijsonFormatChecker(const std::string &format, const std::string
if (format == "uc-cidr4") {
if (IsCIDRv4(value))
return true;
if (results)
results->pushError(context, fmt::format("{} is not a valid CIDR IPv4 block", value));
if(results) results->pushError(context,fmt::format("{} is not a valid CIDR IPv4 block",value));
} else if (format == "uc-cidr6") {
if (IsCIDRv6(value))
return true;
if (results)
results->pushError(context, fmt::format("{} is not a valid CIDR IPv6 block", value));
if(results) results->pushError(context,fmt::format("{} is not a valid CIDR IPv6 block",value));
} else if (format == "uc-cidr") {
if (IsCIDR(value))
return true;
if (results)
results->pushError(context, fmt::format("{} is not a valid CIDR block", value));
if(results) results->pushError(context,fmt::format("{} is not a valid CIDR block",value));
} else if (format == "uc-mac") {
if (std::regex_match(value, mac_regex))
return true;
if (results)
results->pushError(context, fmt::format("{} is not a valid MAC address", value));
if(results) results->pushError(context,fmt::format("{} is not a valid MAC address",value));
} else if (format == "uc-timeout") {
if (std::regex_match(value, uc_timeout_regex))
return true;
if (results)
results->pushError(context, fmt::format("{} is not a valid timeout value", value));
if(results) results->pushError(context,fmt::format("{} is not a valid timeout value",value));
} else if (format == "uc-host") {
if (IsIP(value))
return true;
if (std::regex_match(value, host_regex))
return true;
if (results)
results->pushError(context, fmt::format("{} is not a valid hostname", value));
if(results) results->pushError(context,fmt::format("{} is not a valid hostname",value));
} else if (format == "fqdn" || format == "uc-fqdn") {
if (std::regex_match(value, host_regex))
return true;
if (results)
results->pushError(context, fmt::format("{} is not a valid FQDN", value));
if(results) results->pushError(context,fmt::format("{} is not a valid FQDN",value));
} else if (format == "uc-base64") {
std::string s{value};
Poco::trimInPlace(s);
if ((s.size() % 4 == 0) && std::regex_match(s, b64_regex))
return true;
if (results)
results->pushError(context, fmt::format("{} is not a valid base 64 value", value));
if(results) results->pushError(context,fmt::format("{} is not a valid base 64 value",value));
} else if (format == "uri") {
try {
Poco::URI uri(value);
return true;
} catch (...) {
}
if (results)
results->pushError(context, fmt::format("{} is not a valid URL", value));
if(results) results->pushError(context,fmt::format("{} is not a valid URL",value));
} else if (format == "uc-portrange") {
try {
if (IsPortRangeIsValid(value))
return true;
} catch (...) {
}
if (results)
results->pushError(context, fmt::format("{} is not a valid post range", value));
if(results) results->pushError(context,fmt::format("{} is not a valid post range",value));
} else if (format == "ip") {
if (IsIP(value))
return true;
if (results)
results->pushError(context, fmt::format("{} is not a valid IP address", value));
if(results) results->pushError(context,fmt::format("{} is not a valid IP address",value));
}
return true;
}
@@ -3459,7 +3304,9 @@ namespace OpenWifi {
return 0;
}
void ConfigurationValidator::Stop() {}
void ConfigurationValidator::Stop() {
}
bool ConfigurationValidator::SetSchema(const std::string &SchemaStr) {
try {
@@ -3503,22 +3350,21 @@ namespace OpenWifi {
schema_file << input.rdbuf();
input.close();
if(SetSchema(schema_file.str())) {
poco_information(
Logger(), "Using uCentral data model validation schema from local file.");
poco_information(Logger(),
"Using uCentral data model validation schema from local file.");
return;
}
}
} catch (const Poco::Exception &E) {
} catch (...) {
}
SetSchema(DefaultUCentralSchema);
poco_information(Logger(),
"Using uCentral data model validation schema from built-in default.");
poco_information(Logger(),"Using uCentral data model validation schema from built-in default.");
}
bool ConfigurationValidator::Validate(const std::string &C, std::vector<std::string> &Errors,
bool Strict) {
bool ConfigurationValidator::Validate(const std::string &C, std::vector<std::string> &Errors, bool Strict) {
if(Working_) {
try {
Poco::JSON::Parser P;
@@ -3536,8 +3382,7 @@ namespace OpenWifi {
} catch(const Poco::Exception &E) {
Logger().log(E);
} catch(const std::exception &E) {
Logger().warning(
fmt::format("Error wile validating a configuration (1): {}", E.what()));
Logger().warning(fmt::format("Error wile validating a configuration (1): {}", E.what()));
} catch(...) {
Logger().warning("Error wile validating a configuration (2)");
}
@@ -3553,4 +3398,4 @@ namespace OpenWifi {
Init();
}
} // namespace OpenWifi
}

View File

@@ -7,16 +7,17 @@
#include "framework/SubSystemServer.h"
#include <valijson/adapters/poco_json_adapter.hpp>
#include <valijson/constraints/constraint.hpp>
#include <valijson/constraints/constraint_visitor.hpp>
#include <valijson/utils/poco_json_utils.hpp>
#include <valijson/schema.hpp>
#include <valijson/schema_parser.hpp>
#include <valijson/utils/poco_json_utils.hpp>
#include <valijson/validator.hpp>
#include <valijson/constraints/constraint.hpp>
#include <valijson/constraints/constraint_visitor.hpp>
namespace OpenWifi {
class ConfigurationValidator : public SubSystemServer {
public:
static auto instance() {
static auto instance_ = new ConfigurationValidator;
return instance_;
@@ -37,13 +38,12 @@ namespace OpenWifi {
Poco::JSON::Object::Ptr SchemaDocPtr_;
bool SetSchema(const std::string &SchemaStr);
ConfigurationValidator()
: SubSystemServer("ConfigValidator", "CFG-VALIDATOR", "config.validator") {}
ConfigurationValidator():
SubSystemServer("ConfigValidator", "CFG-VALIDATOR", "config.validator") {
}
};
inline auto ConfigurationValidator() { return ConfigurationValidator::instance(); }
inline bool ValidateUCentralConfiguration(const std::string &C, std::vector<std::string> &Error,
bool strict) {
return ConfigurationValidator::instance()->Validate(C, Error, strict);
inline bool ValidateUCentralConfiguration(const std::string &C, std::vector<std::string> &Error, bool strict) { return ConfigurationValidator::instance()->Validate(C, Error, strict); }
}
} // namespace OpenWifi

View File

@@ -4,9 +4,9 @@
#pragma once
#include <vector>
#include <string>
#include <utility>
#include <vector>
namespace OpenWifi {
@@ -264,6 +264,8 @@ namespace OpenWifi {
{ .code= "EH", .name= "Western Sahara" },
{ .code= "YE", .name= "Yemen" },
{ .code= "ZM", .name= "Zambia" },
{.code = "ZW", .name = "Zimbabwe"}};
{ .code= "ZW", .name= "Zimbabwe" }
};
}
} // namespace OpenWifi

View File

@@ -4,30 +4,29 @@
#include "framework/EventBusManager.h"
#include "framework/KafkaManager.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/utils.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
EventBusManager::EventBusManager(Poco::Logger &L) : Logger_(L) {}
EventBusManager::EventBusManager(Poco::Logger &L) :
Logger_(L) {
}
void EventBusManager::run() {
Running_ = true;
Utils::SetThreadName("fmwk:EventMgr");
auto Msg = std::make_shared<std::string>(MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN));
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg,
false);
auto Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN);
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false);
while(Running_) {
Poco::Thread::trySleep((unsigned long)MicroServiceDaemonBusTimer());
if(!Running_)
break;
Msg = std::make_shared<std::string>(MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE));
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(),
Msg, false);
Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE);
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false);
}
Msg = std::make_shared<std::string>(MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE));
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg,
false);
Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE);
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false);
};
void EventBusManager::Start() {

View File

@@ -4,8 +4,8 @@
#pragma once
#include "Poco/Logger.h"
#include "Poco/Runnable.h"
#include "Poco/Logger.h"
#include "Poco/Thread.h"
namespace OpenWifi {
@@ -25,3 +25,4 @@ namespace OpenWifi {
};
} // namespace OpenWifi

View File

@@ -4,54 +4,50 @@
#include "KafkaManager.h"
#include "fmt/format.h"
#include "framework/MicroServiceFuncs.h"
#include "fmt/format.h"
namespace OpenWifi {
void KafkaLoggerFun([[maybe_unused]] cppkafka::KafkaHandleBase &handle, int level,
const std::string &facility, const std::string &message) {
void KafkaLoggerFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int level, const std::string & facility, const std::string &message) {
switch ((cppkafka::LogLevel) level) {
case cppkafka::LogLevel::LogNotice: {
poco_notice(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
poco_notice(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
case cppkafka::LogLevel::LogDebug: {
poco_debug(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
poco_debug(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
case cppkafka::LogLevel::LogInfo: {
poco_information(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
poco_information(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
case cppkafka::LogLevel::LogWarning: {
poco_warning(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
poco_warning(KafkaManager()->Logger(), fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
case cppkafka::LogLevel::LogAlert:
case cppkafka::LogLevel::LogCrit: {
poco_critical(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
poco_critical(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
case cppkafka::LogLevel::LogErr:
case cppkafka::LogLevel::LogEmerg:
default: {
poco_error(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
poco_error(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
}
}
inline void KafkaErrorFun([[maybe_unused]] cppkafka::KafkaHandleBase &handle, int error,
const std::string &reason) {
poco_error(KafkaManager()->Logger(),
fmt::format("kafka-error: {}, reason: {}", error, reason));
inline void KafkaErrorFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int error, const std::string &reason) {
poco_error(KafkaManager()->Logger(),fmt::format("kafka-error: {}, reason: {}", error, reason));
}
inline void AddKafkaSecurity(cppkafka::Configuration & Config) {
auto CA = MicroServiceConfigGetString("openwifi.kafka.ssl.ca.location","");
auto Certificate =
MicroServiceConfigGetString("openwifi.kafka.ssl.certificate.location", "");
auto Certificate = MicroServiceConfigGetString("openwifi.kafka.ssl.certificate.location","");
auto Key = MicroServiceConfigGetString("openwifi.kafka.ssl.key.location","");
auto Password = MicroServiceConfigGetString("openwifi.kafka.ssl.key.password","");
@@ -65,29 +61,29 @@ namespace OpenWifi {
Config.set("ssl.key.password", Password);
}
void KafkaManager::initialize(Poco::Util::Application & self) {
SubSystemServer::initialize(self);
KafkaEnabled_ = MicroServiceConfigGetBool("openwifi.kafka.enable",false);
}
inline void KafkaProducer::run() {
Poco::Logger &Logger_ =
Poco::Logger::create("KAFKA-PRODUCER", KafkaManager()->Logger().getChannel());
Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-PRODUCER", KafkaManager()->Logger().getChannel());
poco_information(Logger_,"Starting...");
Utils::SetThreadName("Kafka:Prod");
cppkafka::Configuration Config(
{{"client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "")},
{"metadata.broker.list",
MicroServiceConfigGetString("openwifi.kafka.brokerlist", "")}});
cppkafka::Configuration Config({
{ "client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "") },
{ "metadata.broker.list", MicroServiceConfigGetString("openwifi.kafka.brokerlist", "") }
});
AddKafkaSecurity(Config);
Config.set_log_callback(KafkaLoggerFun);
Config.set_error_callback(KafkaErrorFun);
KafkaManager()->SystemInfoWrapper_ =
R"lit({ "system" : { "id" : )lit" + std::to_string(MicroServiceID()) +
KafkaManager()->SystemInfoWrapper_ = R"lit({ "system" : { "id" : )lit" +
std::to_string(MicroServiceID()) +
R"lit( , "host" : ")lit" + MicroServicePrivateEndPoint() +
R"lit(" } , "payload" : )lit" ;
@@ -99,13 +95,11 @@ namespace OpenWifi {
try {
auto Msg = dynamic_cast<KafkaMessage *>(Note.get());
if (Msg != nullptr) {
Producer.produce(cppkafka::MessageBuilder(Msg->Topic())
.key(Msg->Key())
.payload(Msg->Payload()));
Producer.produce(
cppkafka::MessageBuilder(Msg->Topic()).key(Msg->Key()).payload(Msg->Payload()));
}
} catch (const cppkafka::HandleException &E) {
poco_warning(Logger_,
fmt::format("Caught a Kafka exception (producer): {}", E.what()));
poco_warning(Logger_,fmt::format("Caught a Kafka exception (producer): {}", E.what()));
} catch( const Poco::Exception &E) {
Logger_.log(E);
} catch (...) {
@@ -119,25 +113,27 @@ namespace OpenWifi {
inline void KafkaConsumer::run() {
Utils::SetThreadName("Kafka:Cons");
Poco::Logger &Logger_ =
Poco::Logger::create("KAFKA-CONSUMER", KafkaManager()->Logger().getChannel());
Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-CONSUMER", KafkaManager()->Logger().getChannel());
poco_information(Logger_,"Starting...");
cppkafka::Configuration Config(
{{"client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "")},
cppkafka::Configuration Config({
{ "client.id", MicroServiceConfigGetString("openwifi.kafka.client.id","") },
{ "metadata.broker.list", MicroServiceConfigGetString("openwifi.kafka.brokerlist","") },
{ "group.id", MicroServiceConfigGetString("openwifi.kafka.group.id","") },
{ "enable.auto.commit", MicroServiceConfigGetBool("openwifi.kafka.auto.commit",false) },
{ "auto.offset.reset", "latest" } ,
{"enable.partition.eof", false}});
{ "enable.partition.eof", false }
});
AddKafkaSecurity(Config);
Config.set_log_callback(KafkaLoggerFun);
Config.set_error_callback(KafkaErrorFun);
cppkafka::TopicConfiguration topic_config = {{"auto.offset.reset", "smallest"}};
cppkafka::TopicConfiguration topic_config = {
{ "auto.offset.reset", "smallest" }
};
// Now configure it to be the default topic config
Config.set_default_topic_configuration(topic_config);
@@ -166,27 +162,24 @@ namespace OpenWifi {
Running_ = true;
while(Running_) {
try {
std::vector<cppkafka::Message> MsgVec =
Consumer.poll_batch(BatchSize, std::chrono::milliseconds(100));
std::vector<cppkafka::Message> MsgVec = Consumer.poll_batch(BatchSize, std::chrono::milliseconds(100));
for(auto const &Msg:MsgVec) {
if (!Msg)
continue;
if (Msg.get_error()) {
if (!Msg.is_eof()) {
poco_error(Logger_,
fmt::format("Error: {}", Msg.get_error().to_string()));
poco_error(Logger_,fmt::format("Error: {}", Msg.get_error().to_string()));
}
if(!AutoCommit)
Consumer.async_commit(Msg);
continue;
}
KafkaManager()->Dispatch(Msg.get_topic().c_str(), Msg.get_key(), std::make_shared<std::string>(Msg.get_payload()));
KafkaManager()->Dispatch(Msg.get_topic(), Msg.get_key(),Msg.get_payload() );
if (!AutoCommit)
Consumer.async_commit(Msg);
}
} catch (const cppkafka::HandleException &E) {
poco_warning(Logger_,
fmt::format("Caught a Kafka exception (consumer): {}", E.what()));
poco_warning(Logger_,fmt::format("Caught a Kafka exception (consumer): {}", E.what()));
} catch (const Poco::Exception &E) {
Logger_.log(E);
} catch (...) {
@@ -212,8 +205,7 @@ namespace OpenWifi {
}
}
void KafkaProducer::Produce(const char *Topic, const std::string &Key,
std::shared_ptr<std::string> Payload) {
void KafkaProducer::Produce(const std::string &Topic, const std::string &Key, const std::string &Payload) {
std::lock_guard G(Mutex_);
Queue_.enqueueNotification( new KafkaMessage(Topic,Key,Payload));
}
@@ -248,8 +240,7 @@ namespace OpenWifi {
}
}
auto KafkaDispatcher::RegisterTopicWatcher(const std::string &Topic,
Types::TopicNotifyFunction &F) {
auto KafkaDispatcher::RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) {
std::lock_guard G(Mutex_);
auto It = Notifiers_.find(Topic);
if(It == Notifiers_.end()) {
@@ -275,8 +266,7 @@ namespace OpenWifi {
}
}
void KafkaDispatcher::Dispatch(const char *Topic, const std::string &Key,
const std::shared_ptr<std::string> Payload) {
void KafkaDispatcher::Dispatch(const std::string &Topic, const std::string &Key, const std::string &Payload) {
std::lock_guard G(Mutex_);
auto It = Notifiers_.find(Topic);
if(It!=Notifiers_.end()) {
@@ -285,8 +275,7 @@ namespace OpenWifi {
}
void KafkaDispatcher::run() {
Poco::Logger &Logger_ =
Poco::Logger::create("KAFKA-DISPATCHER", KafkaManager()->Logger().getChannel());
Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-DISPATCHER", KafkaManager()->Logger().getChannel());
poco_information(Logger_,"Starting...");
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
Utils::SetThreadName("kafka:dispatch");
@@ -312,6 +301,7 @@ namespace OpenWifi {
T.push_back(TopicName);
}
int KafkaManager::Start() {
if(!KafkaEnabled_)
return 0;
@@ -332,25 +322,21 @@ namespace OpenWifi {
}
}
void KafkaManager::PostMessage(const char *topic, const std::string &key,
const std::shared_ptr<std::string> PayLoad, bool WrapMessage) {
void KafkaManager::PostMessage(const std::string &topic, const std::string & key, const std::string &PayLoad, bool WrapMessage ) {
if(KafkaEnabled_) {
ProducerThr_.Produce(topic,key,WrapMessage ? WrapSystemId(PayLoad) : PayLoad);
}
}
void KafkaManager::Dispatch(const char *Topic, const std::string &Key,
const std::shared_ptr<std::string> Payload) {
void KafkaManager::Dispatch(const std::string &Topic, const std::string & Key, const std::string &Payload) {
Dispatcher_.Dispatch(Topic, Key, Payload);
}
[[nodiscard]] const std::shared_ptr<std::string> KafkaManager::WrapSystemId(const std::shared_ptr<std::string> PayLoad) {
*PayLoad = SystemInfoWrapper_ + *PayLoad + "}";
return PayLoad;
[[nodiscard]] std::string KafkaManager::WrapSystemId(const std::string & PayLoad) {
return SystemInfoWrapper_ + PayLoad + "}";
}
uint64_t KafkaManager::RegisterTopicWatcher(const std::string &Topic,
Types::TopicNotifyFunction &F) {
uint64_t KafkaManager::RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) {
if(KafkaEnabled_) {
return Dispatcher_.RegisterTopicWatcher(Topic,F);
} else {
@@ -364,16 +350,16 @@ namespace OpenWifi {
}
}
void KafkaManager::Topics(std::vector<std::string> &T) { Dispatcher_.Topics(T); }
void KafkaManager::Topics(std::vector<std::string> &T) {
Dispatcher_.Topics(T);
}
void KafkaManager::PartitionAssignment(const cppkafka::TopicPartitionList& partitions) {
poco_information(
Logger(), fmt::format("Partition assigned: {}...", partitions.front().get_partition()));
poco_information(Logger(),fmt::format("Partition assigned: {}...", partitions.front().get_partition()));
}
void KafkaManager::PartitionRevocation(const cppkafka::TopicPartitionList& partitions) {
poco_information(Logger(), fmt::format("Partition revocation: {}...",
partitions.front().get_partition()));
poco_information(Logger(),fmt::format("Partition revocation: {}...",partitions.front().get_partition()));
}
} // namespace OpenWifi

View File

@@ -7,10 +7,10 @@
#include "Poco/Notification.h"
#include "Poco/NotificationQueue.h"
#include "framework/KafkaTopics.h"
#include "framework/OpenWifiTypes.h"
#include "framework/SubSystemServer.h"
#include "framework/OpenWifiTypes.h"
#include "framework/utils.h"
#include "framework/KafkaTopics.h"
#include "cppkafka/cppkafka.h"
@@ -18,17 +18,18 @@ namespace OpenWifi {
class KafkaMessage: public Poco::Notification {
public:
KafkaMessage(const char * Topic, const std::string &Key, std::shared_ptr<std::string> Payload)
: Topic_(Topic), Key_(Key), Payload_(Payload) {}
KafkaMessage( const std::string &Topic, const std::string &Key, const std::string & Payload) :
Topic_(Topic), Key_(Key), Payload_(Payload) {
}
inline const char * Topic() { return Topic_; }
inline const std::string & Topic() { return Topic_; }
inline const std::string & Key() { return Key_; }
inline const std::string &Payload() { return *Payload_; }
inline const std::string & Payload() { return Payload_; }
private:
const char *Topic_;
std::string Topic_;
std::string Key_;
std::shared_ptr<std::string> Payload_;
std::string Payload_;
};
class KafkaProducer : public Poco::Runnable {
@@ -36,7 +37,7 @@ namespace OpenWifi {
void run () override;
void Start();
void Stop();
void Produce(const char *Topic, const std::string &Key, std::shared_ptr<std::string> Payload);
void Produce(const std::string &Topic, const std::string &Key, const std::string &Payload);
private:
std::recursive_mutex Mutex_;
@@ -63,7 +64,7 @@ namespace OpenWifi {
void Stop();
auto RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F);
void UnregisterTopicWatcher(const std::string &Topic, int Id);
void Dispatch(const char *Topic, const std::string &Key, const std::shared_ptr<std::string> Payload);
void Dispatch(const std::string &Topic, const std::string &Key, const std::string &Payload);
void run() override;
void Topics(std::vector<std::string> &T);
@@ -78,6 +79,7 @@ namespace OpenWifi {
class KafkaManager : public SubSystemServer {
public:
friend class KafkaConsumer;
friend class KafkaProducer;
@@ -91,10 +93,9 @@ namespace OpenWifi {
int Start() override;
void Stop() override;
void PostMessage(const char *topic, const std::string &key,
std::shared_ptr<std::string> PayLoad, bool WrapMessage = true);
void Dispatch(const char *Topic, const std::string &Key, std::shared_ptr<std::string> Payload);
[[nodiscard]] const std::shared_ptr<std::string> WrapSystemId(std::shared_ptr<std::string> PayLoad);
void PostMessage(const std::string &topic, const std::string & key, const std::string &PayLoad, bool WrapMessage = true );
void Dispatch(const std::string &Topic, const std::string & Key, const std::string &Payload);
[[nodiscard]] std::string WrapSystemId(const std::string & PayLoad);
[[nodiscard]] inline bool Enabled() const { return KafkaEnabled_; }
uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F);
void UnregisterTopicWatcher(const std::string &Topic, uint64_t Id);
@@ -110,9 +111,12 @@ namespace OpenWifi {
void PartitionAssignment(const cppkafka::TopicPartitionList& partitions);
void PartitionRevocation(const cppkafka::TopicPartitionList& partitions);
KafkaManager() noexcept : SubSystemServer("KafkaManager", "KAFKA-SVR", "openwifi.kafka") {}
KafkaManager() noexcept:
SubSystemServer("KafkaManager", "KAFKA-SVR", "openwifi.kafka") {
}
};
inline auto KafkaManager() { return KafkaManager::instance(); }
} // namespace OpenWifi

View File

@@ -10,32 +10,33 @@
#include <string>
namespace OpenWifi::KafkaTopics {
inline const char * HEALTHCHECK = "healthcheck";
inline const char * STATE = "state";
inline const char * CONNECTION = "connection";
inline const char * WIFISCAN = "wifiscan";
inline const char * ALERTS = "alerts";
inline const char * COMMAND = "command";
inline const char * SERVICE_EVENTS = "service_events";
inline const char * DEVICE_EVENT_QUEUE = "device_event_queue";
inline const char * DEVICE_TELEMETRY = "device_telemetry";
inline const char * PROVISIONING_CHANGE = "provisioning_change";
static const std::string HEALTHCHECK{"healthcheck"};
static const std::string STATE{"state"};
static const std::string CONNECTION{"connection"};
static const std::string WIFISCAN{"wifiscan"};
static const std::string ALERTS{"alerts"};
static const std::string COMMAND{"command"};
static const std::string SERVICE_EVENTS{"service_events"};
static const std::string DEVICE_EVENT_QUEUE{"device_event_queue"};
static const std::string DEVICE_TELEMETRY{"device_telemetry"};
static const std::string PROVISIONING_CHANGE{"provisioning_change"};
namespace ServiceEvents {
inline const char * EVENT_JOIN = "join";
inline const char * EVENT_LEAVE = "leave";
inline const char * EVENT_KEEP_ALIVE = "keep-alive";
inline const char * EVENT_REMOVE_TOKEN = "remove-token";
static const std::string EVENT_JOIN{"join"};
static const std::string EVENT_LEAVE{"leave"};
static const std::string EVENT_KEEP_ALIVE{"keep-alive"};
static const std::string EVENT_REMOVE_TOKEN{"remove-token"};
namespace Fields {
inline const char * EVENT = "event";
inline const char * ID = "id";
inline const char * TYPE = "type";
inline const char * PUBLIC = "publicEndPoint";
inline const char * PRIVATE = "privateEndPoint";
inline const char * KEY = "key";
inline const char * VRSN = "version";
inline const char * TOKEN = "token";
} // namespace Fields
} // namespace ServiceEvents
} // namespace OpenWifi::KafkaTopics
static const std::string EVENT{"event"};
static const std::string ID{"id"};
static const std::string TYPE{"type"};
static const std::string PUBLIC{"publicEndPoint"};
static const std::string PRIVATE{"privateEndPoint"};
static const std::string KEY{"key"};
static const std::string VRSN{"version"};
static const std::string TOKEN{"token"};
}
}
}

View File

@@ -2,39 +2,40 @@
// Created by stephane bourque on 2022-10-26.
//
#include "Poco/AsyncChannel.h"
#include "Poco/ConsoleChannel.h"
#include "Poco/FileChannel.h"
#include "Poco/ConsoleChannel.h"
#include "Poco/PatternFormatter.h"
#include "Poco/FormattingChannel.h"
#include "Poco/JSON/JSONException.h"
#include "Poco/AsyncChannel.h"
#include "Poco/NullChannel.h"
#include "Poco/SplitterChannel.h"
#include "Poco/Net/HTTPStreamFactory.h"
#include "Poco/Net/HTTPSStreamFactory.h"
#include "Poco/Net/FTPSStreamFactory.h"
#include "Poco/Net/FTPStreamFactory.h"
#include "Poco/Net/HTTPSStreamFactory.h"
#include "Poco/Net/HTTPStreamFactory.h"
#include "Poco/Net/SSLManager.h"
#include "Poco/NullChannel.h"
#include "Poco/PatternFormatter.h"
#include "Poco/SplitterChannel.h"
#include "Poco/JSON/JSONException.h"
#include "framework/ALBserver.h"
#include "framework/AuthClient.h"
#include "framework/KafkaManager.h"
#include "framework/MicroService.h"
#include "framework/MicroServiceErrorHandler.h"
#include "framework/MicroServiceNames.h"
#include "framework/RESTAPI_ExtServer.h"
#include "framework/RESTAPI_GenericServerAccounting.h"
#include "framework/RESTAPI_IntServer.h"
#include "framework/UI_WebSocketClientServer.h"
#include "framework/WebSocketLogger.h"
#include "framework/MicroServiceNames.h"
#include "framework/AuthClient.h"
#include "framework/ALBserver.h"
#include "framework/KafkaManager.h"
#include "framework/RESTAPI_GenericServerAccounting.h"
#include "framework/RESTAPI_ExtServer.h"
#include "framework/RESTAPI_IntServer.h"
#include "framework/utils.h"
#include "framework/WebSocketLogger.h"
namespace OpenWifi {
void MicroService::Exit(int Reason) { std::exit(Reason); }
void MicroService::Exit(int Reason) {
std::exit(Reason);
}
void MicroService::BusMessageReceived([[maybe_unused]] const std::string &Key,
const std::string &Payload) {
void MicroService::BusMessageReceived([[maybe_unused]] const std::string &Key, const std::string & Payload) {
std::lock_guard G(InfraMutex_);
try {
Poco::JSON::Parser P;
@@ -53,45 +54,21 @@ namespace OpenWifi {
Object->has(KafkaTopics::ServiceEvents::Fields::PRIVATE) &&
Object->has(KafkaTopics::ServiceEvents::Fields::VRSN) &&
Object->has(KafkaTopics::ServiceEvents::Fields::KEY)) {
auto PrivateEndPoint =
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString();
if (Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE &&
Services_.find(PrivateEndPoint) != Services_.end()) {
auto PrivateEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString();
if (Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE && Services_.find(PrivateEndPoint) != Services_.end()) {
Services_[PrivateEndPoint].LastUpdate = Utils::Now();
} else if (Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) {
Services_.erase(PrivateEndPoint);
poco_debug(
logger(),
fmt::format(
"Service {} ID={} leaving system.",
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
.toString(),
ID));
} else if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN ||
Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE) {
poco_debug(
logger(),
fmt::format(
"Service {} ID={} joining system.",
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
.toString(),
ID));
poco_debug(logger(),fmt::format("Service {} ID={} leaving system.",Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),ID));
} else if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN || Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE) {
poco_debug(logger(),fmt::format("Service {} ID={} joining system.",Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),ID));
Services_[PrivateEndPoint] = Types::MicroServiceMeta{
.Id = ID,
.Type = Poco::toLower(
Object->get(KafkaTopics::ServiceEvents::Fields::TYPE)
.toString()),
.PrivateEndPoint =
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
.toString(),
.PublicEndPoint =
Object->get(KafkaTopics::ServiceEvents::Fields::PUBLIC)
.toString(),
.AccessKey =
Object->get(KafkaTopics::ServiceEvents::Fields::KEY)
.toString(),
.Version = Object->get(KafkaTopics::ServiceEvents::Fields::VRSN)
.toString(),
.Type = Poco::toLower(Object->get(KafkaTopics::ServiceEvents::Fields::TYPE).toString()),
.PrivateEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),
.PublicEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PUBLIC).toString(),
.AccessKey = Object->get(KafkaTopics::ServiceEvents::Fields::KEY).toString(),
.Version = Object->get(KafkaTopics::ServiceEvents::Fields::VRSN).toString(),
.LastUpdate = Utils::Now() };
std::string SvcList;
@@ -101,36 +78,25 @@ namespace OpenWifi {
else
SvcList += ", " + Svc.second.Type;
}
poco_information(
logger(),
fmt::format("Current list of microservices: {}", SvcList));
poco_information(logger(),fmt::format("Current list of microservices: {}", SvcList));
}
} else {
poco_error(
logger(),
fmt::format("KAFKA-MSG: invalid event '{}', missing a field.",
Event));
poco_error(logger(),fmt::format("KAFKA-MSG: invalid event '{}', missing a field.",Event));
}
} else if (Event==KafkaTopics::ServiceEvents::EVENT_REMOVE_TOKEN) {
if(Object->has(KafkaTopics::ServiceEvents::Fields::TOKEN)) {
#ifndef TIP_SECURITY_SERVICE
AuthClient()->RemovedCachedToken(
Object->get(KafkaTopics::ServiceEvents::Fields::TOKEN).toString());
AuthClient()->RemovedCachedToken(Object->get(KafkaTopics::ServiceEvents::Fields::TOKEN).toString());
#endif
} else {
poco_error(
logger(),
fmt::format("KAFKA-MSG: invalid event '{}', missing token", Event));
poco_error(logger(),fmt::format("KAFKA-MSG: invalid event '{}', missing token",Event));
}
} else {
poco_error(logger(),
fmt::format("Unknown Event: {} Source: {}", Event, ID));
poco_error(logger(),fmt::format("Unknown Event: {} Source: {}", Event, ID));
}
}
} else {
poco_error(logger(),"Bad bus message.");
std::ostringstream os;
Object->stringify(std::cout);
}
auto i=Services_.begin();
@@ -171,16 +137,14 @@ namespace OpenWifi {
void MicroService::LoadConfigurationFile() {
std::string Location = Poco::Environment::get(DAEMON_CONFIG_ENV_VAR,".");
ConfigFileName_ =
ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_;
ConfigFileName_ = ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_;
Poco::Path ConfigFile(ConfigFileName_);
if (!ConfigFile.isFile()) {
std::cerr << DAEMON_APP_NAME << ": Configuration " << ConfigFile.toString()
<< " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR +
" env variable the path of the " + DAEMON_PROPERTIES_FILENAME +
" file."
<< std::endl;
if(!ConfigFile.isFile())
{
std::cerr << DAEMON_APP_NAME << ": Configuration "
<< ConfigFile.toString() << " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR
+ " env variable the path of the " + DAEMON_PROPERTIES_FILENAME + " file." << std::endl;
std::exit(Poco::Util::Application::EXIT_CONFIG);
}
@@ -199,8 +163,7 @@ namespace OpenWifi {
std::string KeyFile = ConfigPath("openwifi.service.key","");
if(!KeyFile.empty()) {
std::string KeyFilePassword = ConfigPath("openwifi.service.key.password", "");
AppKey_ = Poco::SharedPtr<Poco::Crypto::RSAKey>(
new Poco::Crypto::RSAKey("", KeyFile, KeyFilePassword));
AppKey_ = Poco::SharedPtr<Poco::Crypto::RSAKey>(new Poco::Crypto::RSAKey("", KeyFile, KeyFilePassword));
Cipher_ = CipherFactory_.createCipher(*AppKey_);
Signer_.setRSAKey(AppKey_);
Signer_.addAllAlgorithms();
@@ -225,13 +188,11 @@ namespace OpenWifi {
initialized = true;
LoadConfigurationFile();
auto LoggingDestination =
MicroService::instance().ConfigGetString("logging.type", "file");
auto LoggingFormat = MicroService::instance().ConfigGetString(
"logging.format", "%Y-%m-%d %H:%M:%S.%i %s: [%p][thr:%I] %t");
auto LoggingDestination = MicroService::instance().ConfigGetString("logging.type", "file");
auto LoggingFormat = MicroService::instance().ConfigGetString("logging.format",
"%Y-%m-%d %H:%M:%S.%i %s: [%p][thr:%I] %t");
auto UseAsyncLogs_ = MicroService::instance().ConfigGetBool("logging.asynch", true);
auto DisableWebSocketLogging =
MicroService::instance().ConfigGetBool("logging.websocket", false);
auto DisableWebSocketLogging = MicroService::instance().ConfigGetBool("logging.websocket",false);
if (LoggingDestination == "null") {
Poco::AutoPtr<Poco::NullChannel> DevNull(new Poco::NullChannel);
@@ -245,12 +206,10 @@ namespace OpenWifi {
} else if (LoggingDestination == "syslog") {
SetSyslogLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
} else {
SetFileLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat,
DAEMON_ROOT_ENV_VAR);
SetFileLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat, DAEMON_ROOT_ENV_VAR);
}
auto Level = Poco::Logger::parseLevel(
MicroService::instance().ConfigGetString("logging.level", "debug"));
auto Level = Poco::Logger::parseLevel(MicroService::instance().ConfigGetString("logging.level", "debug"));
Poco::Logger::root().setLevel(Level);
if(!DisableWebSocketLogging) {
static const UI_WebSocketClientServer::NotificationTypeIdVec Notifications = {
@@ -260,14 +219,12 @@ namespace OpenWifi {
}
}
void MicroService::SetConsoleLogs(bool UseAsync, bool DisableWebSocketLogging,
const std::string &FormatterPattern) {
void MicroService::SetConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern) {
Poco::AutoPtr<Poco::ConsoleChannel> Console(new Poco::ConsoleChannel);
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", FormatterPattern);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
new Poco::FormattingChannel(Formatter, Console));
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, Console));
if(DisableWebSocketLogging) {
if(UseAsync) {
@@ -288,18 +245,15 @@ namespace OpenWifi {
Poco::Logger::root().setChannel(Splitter);
}
}
Poco::Logger::root().information(fmt::format("Enabled console logs: asynch={} websocket={}",
UseAsync, DisableWebSocketLogging));
Poco::Logger::root().information(fmt::format("Enabled console logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging));
}
void MicroService::SetColorConsoleLogs(bool UseAsync, bool DisableWebSocketLogging,
const std::string &FormatterPattern) {
void MicroService::SetColorConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern) {
Poco::AutoPtr<Poco::ColorConsoleChannel> Console(new Poco::ColorConsoleChannel);
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", FormatterPattern);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
new Poco::FormattingChannel(Formatter, Console));
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, Console));
if(DisableWebSocketLogging) {
if(UseAsync) {
@@ -320,28 +274,20 @@ namespace OpenWifi {
Poco::Logger::root().setChannel(Splitter);
}
}
Poco::Logger::root().information(
fmt::format("Enabled color console logs: asynch={} websocket={}", UseAsync,
DisableWebSocketLogging));
Poco::Logger::root().information(fmt::format("Enabled color console logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging));
}
void MicroService::SetSQLLogs([[maybe_unused]] bool UseAsync,
[[maybe_unused]] bool DisableWebSocketLogging,
[[maybe_unused]] const std::string &FormatterPattern) {
//"CREATE TABLE T_POCO_LOG (Source VARCHAR, Name VARCHAR, ProcessId INTEGER, Thread VARCHAR,
//ThreadId INTEGER, Priority INTEGER, Text VARCHAR, DateTime DATE)"
void MicroService::SetSQLLogs([[maybe_unused]] bool UseAsync,[[maybe_unused]] bool DisableWebSocketLogging,[[maybe_unused]] const std::string & FormatterPattern) {
//"CREATE TABLE T_POCO_LOG (Source VARCHAR, Name VARCHAR, ProcessId INTEGER, Thread VARCHAR, ThreadId INTEGER, Priority INTEGER, Text VARCHAR, DateTime DATE)"
}
void MicroService::SetSyslogLogs([[maybe_unused]] bool UseAsync,
[[maybe_unused]] bool DisableWebSocketLogging,
[[maybe_unused]] const std::string &FormatterPattern) {}
void MicroService::SetSyslogLogs([[maybe_unused]] bool UseAsync,[[maybe_unused]] bool DisableWebSocketLogging,[[maybe_unused]] const std::string & FormatterPattern) {
void MicroService::SetFileLogs(bool UseAsync, bool DisableWebSocketLogging,
const std::string &FormatterPattern,
const std::string &root_env_var) {
}
void MicroService::SetFileLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern, const std::string & root_env_var) {
std::string DefaultLogPath = fmt::format("${}/logs",root_env_var);
auto LoggingLocationDir =
MicroService::instance().ConfigPath("logging.path", DefaultLogPath);
auto LoggingLocationDir = MicroService::instance().ConfigPath("logging.path", DefaultLogPath);
Poco::File LD(LoggingLocationDir);
try {
if(!LD.exists()) {
@@ -360,8 +306,7 @@ namespace OpenWifi {
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", FormatterPattern);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
new Poco::FormattingChannel(Formatter, FileChannel));
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, FileChannel));
if(DisableWebSocketLogging) {
if(UseAsync) {
@@ -382,8 +327,7 @@ namespace OpenWifi {
Poco::Logger::root().setChannel(Splitter);
}
}
Poco::Logger::root().information(fmt::format("Enabled file logs: asynch={} websocket={}",
UseAsync, DisableWebSocketLogging));
Poco::Logger::root().information(fmt::format("Enabled file logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging));
}
void DaemonPostInitialization(Poco::Util::Application &self);
@@ -427,9 +371,7 @@ namespace OpenWifi {
ServerApplication::initialize(self);
DaemonPostInitialization(self);
Types::TopicNotifyFunction F = [this](const std::string &Key, const std::string &Payload) {
this->BusMessageReceived(Key, Payload);
};
Types::TopicNotifyFunction F = [this](const std::string &Key,const std::string &Payload) { this->BusMessageReceived(Key, Payload); };
KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F);
}
@@ -450,64 +392,58 @@ namespace OpenWifi {
Poco::Util::Option("help", "", "display help information on command line arguments")
.required(false)
.repeatable(false)
.callback(
Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleHelp)));
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleHelp)));
options.addOption(Poco::Util::Option("file", "", "specify the configuration file")
options.addOption(
Poco::Util::Option("file", "", "specify the configuration file")
.required(false)
.repeatable(false)
.argument("file")
.callback(Poco::Util::OptionCallback<MicroService>(
this, &MicroService::handleConfig)));
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleConfig)));
options.addOption(Poco::Util::Option("debug", "", "to run in debug, set to true")
options.addOption(
Poco::Util::Option("debug", "", "to run in debug, set to true")
.required(false)
.repeatable(false)
.callback(Poco::Util::OptionCallback<MicroService>(
this, &MicroService::handleDebug)));
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleDebug)));
options.addOption(
Poco::Util::Option("logs", "", "specify the log directory and file (i.e. dir/file.log)")
.required(false)
.repeatable(false)
.argument("dir")
.callback(
Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleLogs)));
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleLogs)));
options.addOption(Poco::Util::Option("version", "", "get the version and quit.")
options.addOption(
Poco::Util::Option("version", "", "get the version and quit.")
.required(false)
.repeatable(false)
.callback(Poco::Util::OptionCallback<MicroService>(
this, &MicroService::handleVersion)));
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleVersion)));
}
void MicroService::handleHelp([[maybe_unused]] const std::string &name,
[[maybe_unused]] const std::string &value) {
void MicroService::handleHelp([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) {
HelpRequested_ = true;
displayHelp();
stopOptionsProcessing();
}
void MicroService::handleVersion([[maybe_unused]] const std::string &name,
[[maybe_unused]] const std::string &value) {
void MicroService::handleVersion([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) {
HelpRequested_ = true;
std::cout << Version() << std::endl;
stopOptionsProcessing();
}
void MicroService::handleDebug([[maybe_unused]] const std::string &name,
const std::string &value) {
void MicroService::handleDebug([[maybe_unused]] const std::string &name, const std::string &value) {
if(value == "true")
DebugMode_ = true ;
}
void MicroService::handleLogs([[maybe_unused]] const std::string &name,
const std::string &value) {
void MicroService::handleLogs([[maybe_unused]] const std::string &name, const std::string &value) {
LogDir_ = value;
}
void MicroService::handleConfig([[maybe_unused]] const std::string &name,
const std::string &value) {
void MicroService::handleConfig([[maybe_unused]] const std::string &name, const std::string &value) {
ConfigFileName_ = value;
}
@@ -530,8 +466,7 @@ namespace OpenWifi {
for(auto i:SubSystems_) {
i->Start();
}
EventBusManager_ = std::make_unique<EventBusManager>(Poco::Logger::create(
"EventBusManager", Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel()));
EventBusManager_ = std::make_unique<EventBusManager>(Poco::Logger::create("EventBusManager",Poco::Logger::root().getChannel(),Poco::Logger::root().getLevel()));
EventBusManager_->Start();
}
@@ -575,8 +510,7 @@ namespace OpenWifi {
return ss.str();
}
bool MicroService::SetSubsystemLogLevel(const std::string &SubSystem,
const std::string &Level) {
bool MicroService::SetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) {
try {
auto P = Poco::Logger::parseLevel(Level);
auto Sub = Poco::toLower(SubSystem);
@@ -627,8 +561,7 @@ namespace OpenWifi {
}
const Types::StringVec & MicroService::GetLogLevelNames() {
static Types::StringVec LevelNames{"none", "fatal", "critical", "error", "warning",
"notice", "information", "debug", "trace"};
static Types::StringVec LevelNames{"none", "fatal", "critical", "error", "warning", "notice", "information", "debug", "trace" };
return LevelNames;
}
@@ -636,13 +569,17 @@ namespace OpenWifi {
return (uint64_t) config().getInt64(Key,Default);
}
uint64_t MicroService::ConfigGetInt(const std::string &Key) { return config().getInt(Key); }
uint64_t MicroService::ConfigGetInt(const std::string &Key) {
return config().getInt(Key);
}
uint64_t MicroService::ConfigGetBool(const std::string &Key,bool Default) {
return config().getBool(Key,Default);
}
uint64_t MicroService::ConfigGetBool(const std::string &Key) { return config().getBool(Key); }
uint64_t MicroService::ConfigGetBool(const std::string &Key) {
return config().getBool(Key);
}
std::string MicroService::ConfigGetString(const std::string &Key,const std::string & Default) {
return config().getString(Key, Default);
@@ -666,16 +603,14 @@ namespace OpenWifi {
if(NoBuiltInCrypto_) {
return S;
}
return Cipher_->encryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);
;
return Cipher_->encryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);;
}
std::string MicroService::Decrypt(const std::string &S) {
if(NoBuiltInCrypto_) {
return S;
}
return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);
;
return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);;
}
std::string MicroService::MakeSystemEventMessage( const std::string & Type ) const {
@@ -705,11 +640,11 @@ namespace OpenWifi {
void MicroService::SavePID() {
try {
std::ofstream O;
O.open(MicroService::instance().DataDir() + "/pidfile",
std::ios::binary | std::ios::trunc);
O.open(MicroService::instance().DataDir() + "/pidfile",std::ios::binary | std::ios::trunc);
O << Poco::Process::id();
O.close();
} catch (...) {
} catch (...)
{
std::cout << "Could not save system ID" << std::endl;
}
}
@@ -752,6 +687,7 @@ namespace OpenWifi {
std::time_t now = std::chrono::system_clock::to_time_t(t);
of << Activity << " at " << std::ctime(&now) ;
} catch (...) {
}
}
}
@@ -771,7 +707,8 @@ namespace OpenWifi {
if(F.exists())
F.remove();
} catch (...) {
}
}
} // namespace OpenWifi
}

View File

@@ -9,11 +9,12 @@
#pragma once
#include <array>
#include <ctime>
#include <fstream>
#include <iostream>
#include <random>
#include <vector>
#include <fstream>
#include <random>
#include <ctime>
// This must be defined for poco_debug and poco_trace macros to function.
@@ -23,37 +24,37 @@
namespace OpenWifi {
inline uint64_t Now() { return std::time(nullptr); };
} // namespace OpenWifi
}
#include "Poco/AutoPtr.h"
#include "Poco/Crypto/Cipher.h"
#include "Poco/Crypto/CipherFactory.h"
#include "Poco/Crypto/RSAKey.h"
#include "Poco/Environment.h"
#include "Poco/JSON/Object.h"
#include "Poco/JWT/Signer.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Process.h"
#include "Poco/Util/Application.h"
#include "Poco/Util/HelpFormatter.h"
#include "Poco/Util/ServerApplication.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Crypto/RSAKey.h"
#include "Poco/Crypto/CipherFactory.h"
#include "Poco/Crypto/Cipher.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Process.h"
#include "Poco/Util/HelpFormatter.h"
#include "Poco/JSON/Object.h"
#include "Poco/AutoPtr.h"
#include "Poco/Util/PropertyFileConfiguration.h"
#include "Poco/Util/ServerApplication.h"
#include "Poco/JWT/Signer.h"
#include "Poco/Environment.h"
#include "framework/OpenWifiTypes.h"
#include "framework/EventBusManager.h"
#include "framework/SubSystemServer.h"
#include "framework/ow_constants.h"
#include "framework/utils.h"
#include "framework/SubSystemServer.h"
#include "framework/EventBusManager.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#include "cppkafka/cppkafka.h"
#include "fmt/core.h"
#include "nlohmann/json.hpp"
#include "ow_version.h"
#include "fmt/core.h"
#define _OWDEBUG_ std::cout<< __FILE__ <<":" << __LINE__ << std::endl;
// #define _OWDEBUG_ Logger().debug(Poco::format("%s: %lu",__FILE__,__LINE__));
@@ -62,12 +63,19 @@ namespace OpenWifi {
class MicroService : public Poco::Util::ServerApplication {
public:
explicit MicroService(std::string PropFile, std::string RootEnv, std::string ConfigVar,
std::string AppName, uint64_t BusTimer, SubSystemVec Subsystems)
: DAEMON_PROPERTIES_FILENAME(std::move(PropFile)),
DAEMON_ROOT_ENV_VAR(std::move(RootEnv)), DAEMON_CONFIG_ENV_VAR(std::move(ConfigVar)),
DAEMON_APP_NAME(std::move(AppName)), DAEMON_BUS_TIMER(BusTimer),
SubSystems_(std::move(Subsystems)), Logger_(Poco::Logger::get("FRAMEWORK")) {
explicit MicroService( std::string PropFile,
std::string RootEnv,
std::string ConfigVar,
std::string AppName,
uint64_t BusTimer,
SubSystemVec Subsystems) :
DAEMON_PROPERTIES_FILENAME(std::move(PropFile)),
DAEMON_ROOT_ENV_VAR(std::move(RootEnv)),
DAEMON_CONFIG_ENV_VAR(std::move(ConfigVar)),
DAEMON_APP_NAME(std::move(AppName)),
DAEMON_BUS_TIMER(BusTimer),
SubSystems_(std::move(Subsystems)),
Logger_(Poco::Logger::get("FRAMEWORK")) {
instance_ = this;
RandomEngine_.seed(std::chrono::steady_clock::now().time_since_epoch().count());
// Logger_ = Poco::Logger::root().get("BASE-SVC");
@@ -92,13 +100,9 @@ namespace OpenWifi {
inline uint64_t DaemonBusTimer() const { return DAEMON_BUS_TIMER; };
[[nodiscard]] const std::string & AppName() { return DAEMON_APP_NAME; }
static inline uint64_t GetPID() { return Poco::Process::id(); };
[[nodiscard]] inline const std::string GetPublicAPIEndPoint() {
return MyPublicEndPoint_ + "/api/v1";
};
[[nodiscard]] inline const std::string GetPublicAPIEndPoint() { return MyPublicEndPoint_ + "/api/v1"; };
[[nodiscard]] inline const std::string & GetUIURI() const { return UIURI_;};
[[nodiscard]] inline uint64_t Random(uint64_t ceiling) {
return (RandomEngine_() % ceiling);
}
[[nodiscard]] inline uint64_t Random(uint64_t ceiling) { return (RandomEngine_() % ceiling); }
[[nodiscard]] inline uint64_t Random(uint64_t min, uint64_t max) {
return ((RandomEngine_() % (max-min)) + min);
}
@@ -154,17 +158,11 @@ namespace OpenWifi {
[[nodiscard]] std::string Sign(Poco::JWT::Token &T, const std::string &Algo);
void AddActivity(const std::string &Activity);
static void SetConsoleLogs(bool UseAsync, bool AllowWebSocket,
const std::string &FormatterPattern);
static void SetColorConsoleLogs(bool UseAsync, bool AllowWebSocket,
const std::string &FormatterPattern);
static void SetSQLLogs(bool UseAsync, bool AllowWebSocket,
const std::string &FormatterPattern);
static void SetSyslogLogs(bool UseAsync, bool AllowWebSocket,
const std::string &FormatterPattern);
static void SetFileLogs(bool UseAsync, bool AllowWebSocket,
const std::string &FormatterPattern,
const std::string &root_env_var);
static void SetConsoleLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
static void SetColorConsoleLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
static void SetSQLLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
static void SetSyslogLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
static void SetFileLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern, const std::string & root_env_var);
inline bool AllowExternalMicroServices() const { return AllowExternalMicroServices_; }
private:
@@ -184,8 +182,7 @@ namespace OpenWifi {
std::string MyPrivateEndPoint_;
std::string MyPublicEndPoint_;
std::string UIURI_;
std::string Version_{OW_VERSION::VERSION + "(" + OW_VERSION::BUILD + ")" + " - " +
OW_VERSION::HASH};
std::string Version_{ OW_VERSION::VERSION + "("+ OW_VERSION::BUILD + ")" + " - " + OW_VERSION::HASH };
std::recursive_mutex InfraMutex_;
std::default_random_engine RandomEngine_;
Poco::Util::PropertyFileConfiguration * PropConfigurationFile_ = nullptr;
@@ -206,4 +203,4 @@ namespace OpenWifi {
inline MicroService * MicroService::instance_ = nullptr;
} // namespace OpenWifi
}

View File

@@ -4,20 +4,21 @@
#pragma once
#include "fmt/format.h"
#include "Poco/Util/Application.h"
#include "Poco/ErrorHandler.h"
#include "Poco/JSON/JSONException.h"
#include "Poco/JSON/Template.h"
#include "Poco/Net/NetException.h"
#include "Poco/Net/SSLException.h"
#include "Poco/JSON/Template.h"
#include "Poco/JSON/JSONException.h"
#include "Poco/Thread.h"
#include "Poco/Util/Application.h"
#include "fmt/format.h"
namespace OpenWifi {
class MicroServiceErrorHandler : public Poco::ErrorHandler {
public:
explicit MicroServiceErrorHandler(Poco::Util::Application &App) : App_(App) {}
explicit MicroServiceErrorHandler(Poco::Util::Application &App) : App_(App) {
}
inline void exception(const Poco::Exception & Base) override {
try {
@@ -33,134 +34,146 @@ namespace OpenWifi {
Base.rethrow();
} catch (const Poco::Net::InvalidCertificateException &E) {
poco_error(App_.logger(),
fmt::format("Poco::Net::InvalidCertificateException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
poco_error(App_.logger(), fmt::format("Poco::Net::InvalidCertificateException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::Net::InvalidSocketException &E) {
poco_error(App_.logger(),
fmt::format("Poco::Net::InvalidSocketException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
poco_error(App_.logger(), fmt::format("Poco::Net::InvalidSocketException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::Net::WebSocketException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::WebSocketException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
poco_error(App_.logger(), fmt::format("Poco::Net::WebSocketException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::Net::ConnectionResetException &E) {
poco_error(App_.logger(),
fmt::format("Poco::Net::ConnectionResetException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
poco_error(App_.logger(), fmt::format("Poco::Net::ConnectionResetException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::Net::CertificateValidationException &E) {
poco_error(App_.logger(),
fmt::format("Poco::Net::CertificateValidationException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
poco_error(App_.logger(), fmt::format("Poco::Net::CertificateValidationException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) {
poco_error(App_.logger(),
fmt::format("Poco::Net::SSLConnectionUnexpectedlyClosedException "
"thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
poco_error(App_.logger(), fmt::format("Poco::Net::SSLConnectionUnexpectedlyClosedException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::Net::SSLContextException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::SSLContextException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
poco_error(App_.logger(), fmt::format("Poco::Net::SSLContextException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::Net::SSLException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::SSLException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
poco_error(App_.logger(), fmt::format("Poco::Net::SSLException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::Net::InvalidAddressException &E) {
poco_error(App_.logger(),
fmt::format("Poco::Net::InvalidAddressException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
poco_error(App_.logger(), fmt::format("Poco::Net::InvalidAddressException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::Net::NetException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::NetException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
poco_error(App_.logger(), fmt::format("Poco::Net::NetException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::IOException &E) {
poco_error(
App_.logger(),
fmt::format(
"Poco::IOException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(), E.what()));
poco_error(App_.logger(), fmt::format("Poco::IOException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::TimeoutException &E) {
poco_error(App_.logger(), fmt::format("Poco::TimeoutException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
poco_error(App_.logger(), fmt::format("Poco::TimeoutException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::NoThreadAvailableException &E) {
poco_error(App_.logger(),
fmt::format("Poco::NoThreadAvailableException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
poco_error(App_.logger(), fmt::format("Poco::NoThreadAvailableException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::OutOfMemoryException &E) {
poco_error(App_.logger(), fmt::format("Poco::OutOfMemoryException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
poco_error(App_.logger(), fmt::format("Poco::OutOfMemoryException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::BadCastException &E) {
poco_error(App_.logger(), fmt::format("Poco::BadCastException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
poco_error(App_.logger(), fmt::format("Poco::BadCastException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::DataException &E) {
poco_error(
App_.logger(),
fmt::format(
"Poco::DataException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(), E.what()));
poco_error(App_.logger(), fmt::format("Poco::DataException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::PoolOverflowException &E) {
poco_error(App_.logger(), fmt::format("Poco::PoolOverflowException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
poco_error(App_.logger(), fmt::format("Poco::PoolOverflowException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::SystemException &E) {
poco_error(App_.logger(), fmt::format("Poco::SystemException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
poco_error(App_.logger(), fmt::format("Poco::SystemException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::RuntimeException &E) {
poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::JSON::JSONTemplateException &E) {
poco_error(App_.logger(),
fmt::format("Poco::JSON::JSONTemplateException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
poco_error(App_.logger(), fmt::format("Poco::JSON::JSONTemplateException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::JSON::JSONException &E) {
poco_error(App_.logger(), fmt::format("Poco::JSON::JSONException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
poco_error(App_.logger(), fmt::format("Poco::JSON::JSONException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::ApplicationException &E) {
poco_error(App_.logger(), fmt::format("Poco::ApplicationException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
poco_error(App_.logger(), fmt::format("Poco::ApplicationException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::Exception &E) {
poco_error(
App_.logger(),
fmt::format(
"Poco::Exception thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(), E.what()));
poco_error(App_.logger(), fmt::format("Poco::Exception thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (...) {
poco_error(App_.logger(), fmt::format("Poco:Generic thr_name={}",t_name, t_id));
}
@@ -174,8 +187,9 @@ namespace OpenWifi {
t_name = "startup_code";
t_id = 0;
}
poco_warning(App_.logger(),
fmt::format("std::exception in {}: {} thr_id={}", t_name, E.what(), t_id));
poco_warning(App_.logger(), fmt::format("std::exception in {}: {} thr_id={}",
t_name,E.what(),
t_id));
}
inline void exception() override {
@@ -186,14 +200,13 @@ namespace OpenWifi {
t_name = "startup_code";
t_id = 0;
}
poco_warning(App_.logger(),
fmt::format("generic exception in {} thr_id={}", t_name, t_id));
poco_warning(App_.logger(), fmt::format("generic exception in {} thr_id={}",
t_name, t_id));
}
private:
Poco::Util::Application &App_;
std::string t_name;
int t_id=0;
};
} // namespace OpenWifi
}

View File

@@ -4,8 +4,8 @@
#pragma once
#include <map>
#include <string>
#include <map>
#include "Poco/BasicEvent.h"
#include "Poco/ExpireLRUCache.h"
@@ -13,26 +13,27 @@
namespace OpenWifi {
class ConfigurationEntry {
public:
template <typename T> explicit ConfigurationEntry(T def) : Default_(def), Current_(def) {}
template <typename T> explicit ConfigurationEntry(T def) :
Default_(def),
Current_(def){
}
template <typename T>
explicit ConfigurationEntry(T def, T cur, const std::string &Hint = "")
: Default_(def), Current_(cur), Hint_(Hint) {}
template <typename T> explicit ConfigurationEntry(T def, T cur, const std::string &Hint="") :
Default_(def),
Current_(cur),
Hint_(Hint){
}
inline ConfigurationEntry()=default;
inline ~ConfigurationEntry()=default;
template <typename T> explicit operator T () const { return std::get<T>(Current_); }
inline ConfigurationEntry &operator=(const char *v) {
Current_ = std::string(v);
return *this;
}
template <typename T> ConfigurationEntry &operator=(T v) {
Current_ = (T)v;
return *this;
}
inline ConfigurationEntry & operator=(const char *v) { Current_ = std::string(v); return *this;}
template <typename T> ConfigurationEntry & operator=(T v) { Current_ = (T) v; return *this;}
void reset() { Current_ = Default_; }
void reset() {
Current_ = Default_;
}
private:
std::variant<bool,uint64_t,std::string> Default_, Current_;
@@ -44,9 +45,14 @@ namespace OpenWifi {
template <typename T> class FIFO {
public:
explicit FIFO(uint32_t Size) : Size_(Size) { Buffer_ = new T[Size_]; }
explicit FIFO(uint32_t Size) :
Size_(Size) {
Buffer_ = new T [Size_];
}
~FIFO() { delete[] Buffer_; }
~FIFO() {
delete [] Buffer_;
}
mutable Poco::BasicEvent<bool> Writable_;
mutable Poco::BasicEvent<bool> Readable_;
@@ -102,17 +108,25 @@ namespace OpenWifi {
T * Buffer_ = nullptr;
};
template <class Record, typename KeyType = std::string, int Size = 256, int Expiry = 60000>
class RecordCache {
template <class Record, typename KeyType = std::string, int Size=256, int Expiry=60000> class RecordCache {
public:
explicit RecordCache(KeyType Record::*Q) : MemberOffset(Q){};
inline auto update(const Record &R) { return Cache_.update(R.*MemberOffset, R); }
inline auto get(const KeyType &K) { return Cache_.get(K); }
inline auto remove(const KeyType &K) { return Cache_.remove(K); }
inline auto remove(const Record &R) { return Cache_.remove(R.*MemberOffset); }
explicit RecordCache( KeyType Record::* Q) :
MemberOffset(Q){
};
inline auto update(const Record &R) {
return Cache_.update(R.*MemberOffset, R);
}
inline auto get(const KeyType &K) {
return Cache_.get(K);
}
inline auto remove(const KeyType &K) {
return Cache_.remove(K);
}
inline auto remove(const Record &R) {
return Cache_.remove(R.*MemberOffset);
}
private:
KeyType Record::* MemberOffset;
Poco::ExpireLRUCache<KeyType,Record> Cache_{Size,Expiry};
};
} // namespace OpenWifi
}

View File

@@ -2,10 +2,8 @@
// Created by stephane bourque on 2022-10-25.
//
#include "framework/MicroServiceFuncs.h"
#include "framework/MicroService.h"
#include "framework/ALBserver.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
const std::string &MicroServiceDataDirectory() { return MicroService::instance().DataDir(); }
@@ -20,8 +18,7 @@ namespace OpenWifi {
std::string MicroServicePublicEndPoint() { return MicroService::instance().PublicEndPoint(); }
std::string MicroServiceConfigGetString(const std::string &Key,
const std::string &DefaultValue) {
std::string MicroServiceConfigGetString(const std::string &Key, const std::string &DefaultValue) {
return MicroService::instance().ConfigGetString(Key, DefaultValue);
}
@@ -49,17 +46,15 @@ namespace OpenWifi {
void MicroServiceReload(const std::string &Type) { MicroService::instance().Reload(Type); }
Types::StringVec MicroServiceGetLogLevelNames() {
const Types::StringVec MicroServiceGetLogLevelNames() {
return MicroService::instance().GetLogLevelNames();
}
Types::StringVec MicroServiceGetSubSystems() {
const Types::StringVec MicroServiceGetSubSystems() {
return MicroService::instance().GetSubSystems();
}
Types::StringPairVec MicroServiceGetLogLevels() {
return MicroService::instance().GetLogLevels();
}
Types::StringPairVec MicroServiceGetLogLevels() { return MicroService::instance().GetLogLevels(); }
bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) {
return MicroService::instance().SetSubsystemLogLevel(SubSystem, Level);
@@ -81,7 +76,7 @@ namespace OpenWifi {
std::string MicroServiceGetUIURI() { return MicroService::instance().GetUIURI(); }
SubSystemVec MicroServiceGetFullSubSystems() {
const SubSystemVec MicroServiceGetFullSubSystems() {
return MicroService::instance().GetFullSubSystems();
}
@@ -89,17 +84,20 @@ namespace OpenWifi {
std::uint64_t MicroServiceDaemonBusTimer() { return MicroService::instance().DaemonBusTimer(); }
std::string MicroServiceMakeSystemEventMessage(const char *Type) {
std::string MicroServiceMakeSystemEventMessage(const std::string &Type) {
return MicroService::instance().MakeSystemEventMessage(Type);
}
Poco::ThreadPool &MicroServiceTimerPool() { return MicroService::instance().TimerPool(); }
std::string MicroServiceConfigPath(const std::string &Key, const std::string &DefaultValue) {
std::string MicroServiceConfigPath(const std::string &Key,
const std::string &DefaultValue) {
return MicroService::instance().ConfigPath(Key, DefaultValue);
}
std::string MicroServiceWWWAssetsDir() { return MicroService::instance().WWWAssetsDir(); }
std::string MicroServiceWWWAssetsDir() {
return MicroService::instance().WWWAssetsDir();
}
std::uint64_t MicroServiceRandom(std::uint64_t Start,std::uint64_t End) {
return MicroService::instance().Random(Start, End);
@@ -125,8 +123,4 @@ namespace OpenWifi {
return MicroService::instance().AllowExternalMicroServices();
}
void MicroServiceALBCallback( std::string Callback()) {
return ALBHealthCheckServer()->RegisterExtendedHealthMessage(Callback);
}
} // namespace OpenWifi

View File

@@ -8,10 +8,11 @@
#include "framework/OpenWifiTypes.h"
#include "Poco/JSON/Object.h"
#include "Poco/JWT/Token.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/JSON/Object.h"
#include "Poco/ThreadPool.h"
#include "Poco/JWT/Token.h"
namespace OpenWifi {
class SubSystemServer;
@@ -20,8 +21,7 @@ namespace OpenWifi {
Types::MicroServiceMetaVec MicroServiceGetServices(const std::string & Type);
Types::MicroServiceMetaVec MicroServiceGetServices();
std::string MicroServicePublicEndPoint();
std::string MicroServiceConfigGetString(const std::string &Key,
const std::string &DefaultValue);
std::string MicroServiceConfigGetString(const std::string &Key, const std::string &DefaultValue);
bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue);
std::uint64_t MicroServiceConfigGetInt(const std::string &Key, std::uint64_t DefaultValue);
std::string MicroServicePrivateEndPoint();
@@ -31,8 +31,8 @@ namespace OpenWifi {
void MicroServiceLoadConfigurationFile();
void MicroServiceReload();
void MicroServiceReload(const std::string &Type);
Types::StringVec MicroServiceGetLogLevelNames();
Types::StringVec MicroServiceGetSubSystems();
const Types::StringVec MicroServiceGetLogLevelNames();
const Types::StringVec MicroServiceGetSubSystems();
Types::StringPairVec MicroServiceGetLogLevels();
bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level);
void MicroServiceGetExtraConfiguration(Poco::JSON::Object &Answer);
@@ -40,12 +40,13 @@ namespace OpenWifi {
std::uint64_t MicroServiceUptimeTotalSeconds();
std::uint64_t MicroServiceStartTimeEpochTime();
std::string MicroServiceGetUIURI();
SubSystemVec MicroServiceGetFullSubSystems();
const SubSystemVec MicroServiceGetFullSubSystems();
std::string MicroServiceCreateUUID();
std::uint64_t MicroServiceDaemonBusTimer();
std::string MicroServiceMakeSystemEventMessage(const char *Type);
std::string MicroServiceMakeSystemEventMessage( const std::string & Type );
Poco::ThreadPool & MicroServiceTimerPool();
std::string MicroServiceConfigPath(const std::string &Key, const std::string &DefaultValue);
std::string MicroServiceConfigPath(const std::string &Key,
const std::string &DefaultValue);
std::string MicroServiceWWWAssetsDir();
std::uint64_t MicroServiceRandom(std::uint64_t Start,std::uint64_t End);
std::uint64_t MicroServiceRandom(std::uint64_t Range);
@@ -53,5 +54,4 @@ namespace OpenWifi {
std::string MicroServiceGetPublicAPIEndPoint();
void MicroServiceDeleteOverrideConfiguration();
bool AllowExternalMicroServices();
void MicroServiceALBCallback( std::string Callback());
} // namespace OpenWifi
}

View File

@@ -19,4 +19,4 @@ namespace OpenWifi {
static const std::string uSERVICE_ANALYTICS{ "owanalytics"};
static const std::string uSERVICE_OWRRM{ "owrrm"};
} // namespace OpenWifi
}

View File

@@ -4,19 +4,18 @@
#include "OpenAPIRequests.h"
#include "Poco/JSON/Parser.h"
#include "Poco/Logger.h"
#include "Poco/URI.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/URI.h"
#include "Poco/JSON/Parser.h"
#include "fmt/format.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
Poco::Net::HTTPServerResponse::HTTPStatus
OpenAPIRequestGet::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string &BearerToken) {
Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestGet::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken) {
try {
auto Services = MicroServiceGetServices(Type_);
@@ -30,11 +29,11 @@ namespace OpenWifi {
URI.addQueryParameter(qp.first, qp.second);
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET, Path,
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET,
Path,
Poco::Net::HTTPMessage::HTTP_1_1);
poco_debug(Poco::Logger::get("REST-CALLER-GET"),
fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_));
poco_debug(Poco::Logger::get("REST-CALLER-GET"), fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
if(BearerToken.empty()) {
Request.add("X-API-KEY", Svc.AccessKey);
@@ -72,14 +71,15 @@ namespace OpenWifi {
return Response.getStatus();
}
}
} catch (const Poco::Exception &E) {
}
catch (const Poco::Exception &E)
{
Poco::Logger::get("REST-CALLER-GET").log(E);
}
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
}
Poco::Net::HTTPServerResponse::HTTPStatus
OpenAPIRequestPut::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string &BearerToken) {
Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestPut::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken) {
try {
auto Services = MicroServiceGetServices(Type_);
for(auto const &Svc:Services) {
@@ -91,12 +91,12 @@ namespace OpenWifi {
for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second);
poco_debug(Poco::Logger::get("REST-CALLER-PUT"),
fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_));
poco_debug(Poco::Logger::get("REST-CALLER-PUT"), fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_PUT, Path,
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_PUT,
Path,
Poco::Net::HTTPMessage::HTTP_1_1);
std::ostringstream obody;
Poco::JSON::Stringifier::stringify(Body_,obody);
@@ -148,33 +148,34 @@ namespace OpenWifi {
return Response.getStatus();
}
}
} catch (const Poco::Exception &E) {
}
catch (const Poco::Exception &E)
{
Poco::Logger::get("REST-CALLER-PUT").log(E);
}
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
}
Poco::Net::HTTPServerResponse::HTTPStatus
OpenAPIRequestPost::Do(Poco::JSON::Object::Ptr &ResponseObject,
const std::string &BearerToken) {
Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestPost::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken) {
try {
auto Services = MicroServiceGetServices(Type_);
for(auto const &Svc:Services) {
Poco::URI URI(Svc.PrivateEndPoint);
auto Secure = (URI.getScheme() == "https");
URI.setPath(EndPoint_);
for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second);
poco_debug(Poco::Logger::get("REST-CALLER-POST"),
fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_));
poco_debug(Poco::Logger::get("REST-CALLER-POST"),fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST, Path,
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST,
Path,
Poco::Net::HTTPMessage::HTTP_1_1);
std::ostringstream obody;
Poco::JSON::Stringifier::stringify(Body_,obody);
@@ -224,14 +225,15 @@ namespace OpenWifi {
return Response.getStatus();
}
}
} catch (const Poco::Exception &E) {
}
catch (const Poco::Exception &E)
{
Poco::Logger::get("REST-CALLER-POST").log(E);
}
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
}
Poco::Net::HTTPServerResponse::HTTPStatus
OpenAPIRequestDelete::Do(const std::string &BearerToken) {
Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestDelete::Do(const std::string & BearerToken) {
try {
auto Services = MicroServiceGetServices(Type_);
@@ -244,12 +246,12 @@ namespace OpenWifi {
for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second);
poco_debug(Poco::Logger::get("REST-CALLER-DELETE"),
fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_));
poco_debug(Poco::Logger::get("REST-CALLER-DELETE"),fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_DELETE, Path,
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_DELETE,
Path,
Poco::Net::HTTPMessage::HTTP_1_1);
if(BearerToken.empty()) {
Request.add("X-API-KEY", Svc.AccessKey);
@@ -275,10 +277,13 @@ namespace OpenWifi {
return Response.getStatus();
}
}
} catch (const Poco::Exception &E) {
}
catch (const Poco::Exception &E)
{
Poco::Logger::get("REST-CALLER-DELETE").log(E);
}
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
}
} // namespace OpenWifi

View File

@@ -15,14 +15,17 @@ namespace OpenWifi {
class OpenAPIRequestGet {
public:
explicit OpenAPIRequestGet(const std::string &Type, const std::string &EndPoint,
const Types::StringPairVec &QueryData, uint64_t msTimeout,
const std::string &LoggingStr = "")
: Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout),
explicit OpenAPIRequestGet( const std::string & Type,
const std::string & EndPoint,
const Types::StringPairVec & QueryData,
uint64_t msTimeout,
const std::string &LoggingStr=""):
Type_(Type),
EndPoint_(EndPoint),
QueryData_(QueryData),
msTimeout_(msTimeout),
LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject,
const std::string &BearerToken = "");
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
private:
std::string Type_;
std::string EndPoint_;
@@ -33,15 +36,20 @@ namespace OpenWifi {
class OpenAPIRequestPut {
public:
explicit OpenAPIRequestPut(const std::string &Type, const std::string &EndPoint,
explicit OpenAPIRequestPut( const std::string & Type,
const std::string & EndPoint,
const Types::StringPairVec & QueryData,
const Poco::JSON::Object &Body, uint64_t msTimeout,
const std::string &LoggingStr = "")
: Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout),
Body_(Body), LoggingStr_(LoggingStr){};
const Poco::JSON::Object & Body,
uint64_t msTimeout,
const std::string &LoggingStr=""):
Type_(Type),
EndPoint_(EndPoint),
QueryData_(QueryData),
msTimeout_(msTimeout),
Body_(Body),
LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject,
const std::string &BearerToken = "");
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
private:
std::string Type_;
@@ -54,15 +62,19 @@ namespace OpenWifi {
class OpenAPIRequestPost {
public:
explicit OpenAPIRequestPost(const std::string &Type, const std::string &EndPoint,
explicit OpenAPIRequestPost( const std::string & Type,
const std::string & EndPoint,
const Types::StringPairVec & QueryData,
const Poco::JSON::Object &Body, uint64_t msTimeout,
const std::string &LoggingStr = "")
: Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout),
Body_(Body), LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject,
const std::string &BearerToken = "");
const Poco::JSON::Object & Body,
uint64_t msTimeout,
const std::string &LoggingStr=""):
Type_(Type),
EndPoint_(EndPoint),
QueryData_(QueryData),
msTimeout_(msTimeout),
Body_(Body),
LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
private:
std::string Type_;
std::string EndPoint_;
@@ -74,10 +86,15 @@ namespace OpenWifi {
class OpenAPIRequestDelete {
public:
explicit OpenAPIRequestDelete(const std::string &Type, const std::string &EndPoint,
const Types::StringPairVec &QueryData, uint64_t msTimeout,
const std::string &LoggingStr = "")
: Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout),
explicit OpenAPIRequestDelete( const std::string & Type,
const std::string & EndPoint,
const Types::StringPairVec & QueryData,
uint64_t msTimeout,
const std::string &LoggingStr=""):
Type_(Type),
EndPoint_(EndPoint),
QueryData_(QueryData),
msTimeout_(msTimeout),
LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(const std::string & BearerToken = "");

View File

@@ -4,14 +4,14 @@
#pragma once
#include <functional>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include <functional>
#include <string>
#include <queue>
#include <list>
#include <set>
namespace OpenWifi::Types {
typedef std::pair<std::string,std::string> StringPair;
@@ -28,9 +28,6 @@ namespace OpenWifi::Types {
typedef std::string UUID_t;
typedef std::vector<UUID_t> UUIDvec_t;
typedef std::map<std::string,std::map<uint32_t,uint64_t>> Counted3DMapSII;
typedef std::vector<int64_t> IntList;
typedef std::vector<uint64_t> UIntList;
typedef std::vector<double> DoubleList;
struct MicroServiceMeta {
uint64_t Id=0;
@@ -44,12 +41,11 @@ namespace OpenWifi::Types {
typedef std::map<std::string, MicroServiceMeta> MicroServiceMetaMap;
typedef std::vector<MicroServiceMeta> MicroServiceMetaVec;
} // namespace OpenWifi::Types
}
namespace OpenWifi {
inline void UpdateCountedMap(OpenWifi::Types::CountedMap &M, const std::string &S,
uint64_t Increment = 1) {
inline void UpdateCountedMap(OpenWifi::Types::CountedMap &M, const std::string &S, uint64_t Increment=1) {
auto it = M.find(S);
if(it==M.end())
M[S] = Increment;
@@ -57,14 +53,14 @@ namespace OpenWifi {
it->second += Increment;
}
inline void UpdateCountedMap(OpenWifi::Types::Counted3DMapSII &M, const std::string &S,
uint32_t Index, uint64_t Increment = 1) {
inline void UpdateCountedMap(OpenWifi::Types::Counted3DMapSII &M, const std::string &S, uint32_t Index, uint64_t Increment=1) {
auto it = M.find(S);
if(it==M.end()) {
std::map<uint32_t,uint64_t> E;
E[Index] = Increment;
M[S] = E;
} else {
}
else {
std::map<uint32_t,uint64_t> & IndexMap = it->second;
auto it_index = IndexMap.find(Index);
if(it_index == IndexMap.end()) {
@@ -74,4 +70,4 @@ namespace OpenWifi {
}
}
}
} // namespace OpenWifi
}

View File

@@ -6,23 +6,22 @@
namespace OpenWifi {
Poco::Net::HTTPRequestHandler *
ExtRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &Request) {
Poco::Net::HTTPRequestHandler *ExtRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &Request) {
try {
Poco::URI uri(Request.getURI());
auto TID = NextTransactionId_++;
Utils::SetThreadName(fmt::format("x-rest:{}",TID).c_str());
return RESTAPI_ExtServer()->CallServer(uri.getPath(), TID);
} catch (...) {
}
return nullptr;
}
Poco::Net::HTTPRequestHandler *RESTAPI_ExtServer::CallServer(const std::string &Path,
uint64_t Id) {
Poco::Net::HTTPRequestHandler *RESTAPI_ExtServer::CallServer(const std::string &Path, uint64_t Id) {
RESTAPIHandler::BindingMap Bindings;
Utils::SetThreadName(fmt::format("x-rest:{}",Id).c_str());
return RESTAPI_ExtRouter(Path, Bindings, Logger(), Server_, Id);
}
} // namespace OpenWifi
}

View File

@@ -6,21 +6,18 @@
#include "Poco/Net/HTTPServer.h"
#include "framework/RESTAPI_Handler.h"
#include "framework/SubSystemServer.h"
#include "framework/RESTAPI_Handler.h"
namespace OpenWifi {
Poco::Net::HTTPRequestHandler *
RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServerAccounting & S, uint64_t Id);
class ExtRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
public:
ExtRequestHandlerFactory() = default;
Poco::Net::HTTPRequestHandler *
createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override;
Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override;
private:
static inline std::atomic_uint64_t NextTransactionId_ = 1;
};
@@ -39,15 +36,10 @@ namespace OpenWifi {
for(const auto & Svr: ConfigServersList_) {
if(MicroServiceNoAPISecurity()) {
poco_information(
Logger(),
fmt::format("Starting: {}:{}. Security has been disabled for APIs.",
Svr.Address(), Svr.Port()));
poco_information(Logger(),fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port()));
} else {
poco_information(Logger(),
fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}",
Svr.Address(), Svr.Port(), Svr.KeyFile(),
Svr.CertFile()));
poco_information(Logger(),fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(),
Svr.KeyFile(),Svr.CertFile()));
Svr.LogCert(Logger());
if (!Svr.RootCA().empty())
Svr.LogCas(Logger());
@@ -60,12 +52,10 @@ namespace OpenWifi {
std::unique_ptr<Poco::Net::HTTPServer> NewServer;
if(MicroServiceNoAPISecurity()) {
auto Sock{Svr.CreateSocket(Logger())};
NewServer = std::make_unique<Poco::Net::HTTPServer>(
new ExtRequestHandlerFactory, Pool_, Sock, Params);
NewServer = std::make_unique<Poco::Net::HTTPServer>(new ExtRequestHandlerFactory, Pool_, Sock, Params);
} else {
auto Sock{Svr.CreateSecureSocket(Logger())};
NewServer = std::make_unique<Poco::Net::HTTPServer>(
new ExtRequestHandlerFactory, Pool_, Sock, Params);
NewServer = std::make_unique<Poco::Net::HTTPServer>(new ExtRequestHandlerFactory, Pool_, Sock, Params);
};
NewServer->start();
RESTServers_.push_back(std::move(NewServer));
@@ -98,10 +88,12 @@ namespace OpenWifi {
Poco::ThreadPool Pool_{"x-rest",8,128};
RESTAPI_GenericServerAccounting Server_;
RESTAPI_ExtServer() noexcept
: SubSystemServer("RESTAPI_ExtServer", "REST-XSRV", "openwifi.restapi") {}
RESTAPI_ExtServer() noexcept:
SubSystemServer("RESTAPI_ExtServer", "REST-XSRV", "openwifi.restapi")
{
}
};
inline auto RESTAPI_ExtServer() { return RESTAPI_ExtServer::instance(); };
} // namespace OpenWifi
}

View File

@@ -4,19 +4,25 @@
#pragma once
#include <array>
#include <string>
#include <array>
#include "Poco/Net/HTTPRequest.h"
#include "Poco/String.h"
#include "Poco/StringTokenizer.h"
#include "Poco/String.h"
#include "Poco/Net/HTTPRequest.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
class RESTAPI_GenericServerAccounting {
public:
enum { LOG_GET = 0, LOG_DELETE, LOG_PUT, LOG_POST };
enum {
LOG_GET=0,
LOG_DELETE,
LOG_PUT,
LOG_POST
};
void inline SetFlags(bool External, const std::string &Methods) {
Poco::StringTokenizer Tokens(Methods,",");
@@ -34,18 +40,14 @@ namespace OpenWifi {
}
inline void InitLogging() {
std::string Public =
MicroServiceConfigGetString("apilogging.public.methods", "PUT,POST,DELETE");
std::string Public = MicroServiceConfigGetString("apilogging.public.methods","PUT,POST,DELETE");
SetFlags(true, Public);
std::string Private =
MicroServiceConfigGetString("apilogging.private.methods", "PUT,POST,DELETE");
std::string Private = MicroServiceConfigGetString("apilogging.private.methods","PUT,POST,DELETE");
SetFlags(false, Private);
std::string PublicBadTokens =
MicroServiceConfigGetString("apilogging.public.badtokens.methods", "");
std::string PublicBadTokens = MicroServiceConfigGetString("apilogging.public.badtokens.methods","");
LogBadTokens_[0] = (Poco::icompare(PublicBadTokens,"true")==0);
std::string PrivateBadTokens =
MicroServiceConfigGetString("apilogging.private.badtokens.methods", "");
std::string PrivateBadTokens = MicroServiceConfigGetString("apilogging.private.badtokens.methods","");
LogBadTokens_[1] = (Poco::icompare(PrivateBadTokens,"true")==0);
}
@@ -70,4 +72,4 @@ namespace OpenWifi {
std::array<bool,8> LogFlags_{false};
std::array<bool,2> LogBadTokens_{false};
};
} // namespace OpenWifi
}

View File

@@ -4,4 +4,5 @@
#include "RESTAPI_Handler.h"
namespace OpenWifi {} // namespace OpenWifi
namespace OpenWifi {
} // namespace OpenWifi

View File

@@ -4,27 +4,27 @@
#pragma once
#include <map>
#include <string>
#include <vector>
#include <map>
#include "Poco/DeflatingStream.h"
#include "Poco/Net/HTTPRequestHandler.h"
#include "Poco/Logger.h"
#include "Poco/JSON/Object.h"
#include "Poco/JSON/Parser.h"
#include "Poco/Logger.h"
#include "Poco/Net/HTTPRequestHandler.h"
#include "Poco/Net/HTTPResponse.h"
#include "Poco/Net/HTTPServerResponse.h"
#include "Poco/Net/OAuth20Credentials.h"
#include "Poco/DeflatingStream.h"
#include "Poco/TemporaryFile.h"
#include "Poco/Net/OAuth20Credentials.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#include "framework/AuthClient.h"
#include "framework/ow_constants.h"
#include "framework/RESTAPI_GenericServerAccounting.h"
#include "framework/RESTAPI_RateLimiter.h"
#include "framework/RESTAPI_utils.h"
#include "framework/ow_constants.h"
#include "framework/utils.h"
#include "framework/RESTAPI_utils.h"
#include "framework/AuthClient.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#if defined(TIP_SECURITY_SERVICE)
#include "AuthService.h"
@@ -40,8 +40,7 @@ namespace OpenWifi {
uint64_t StartDate = 0 , EndDate = 0 , Offset = 0 , Limit = 0, LogType = 0 ;
std::string SerialNumber, Filter;
std::vector<std::string> Select;
bool Lifetime = false, LastOnly = false, Newest = false, CountOnly = false,
AdditionalInfo = false;
bool Lifetime=false, LastOnly=false, Newest=false, CountOnly=false, AdditionalInfo=false;
};
typedef std::map<std::string, std::string> BindingMap;
@@ -50,19 +49,30 @@ namespace OpenWifi {
int64_t MaxCalls=10;
};
RESTAPIHandler(BindingMap map, Poco::Logger &l, std::vector<std::string> Methods,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal, bool AlwaysAuthorize = true, bool RateLimited = false,
RESTAPIHandler( BindingMap map,
Poco::Logger &l,
std::vector<std::string> Methods,
RESTAPI_GenericServerAccounting & Server,
uint64_t TransactionId,
bool Internal,
bool AlwaysAuthorize=true,
bool RateLimited=false,
const RateLimit & Profile = RateLimit{.Interval=1000,.MaxCalls=100},
bool SubscriberOnly=false)
: Bindings_(std::move(map)), Logger_(l), Methods_(std::move(Methods)),
Internal_(Internal), RateLimited_(RateLimited), SubOnlyService_(SubscriberOnly),
AlwaysAuthorize_(AlwaysAuthorize), Server_(Server), MyRates_(Profile),
TransactionId_(TransactionId) {}
: Bindings_(std::move(map)),
Logger_(l),
Methods_(std::move(Methods)),
Internal_(Internal),
RateLimited_(RateLimited),
SubOnlyService_(SubscriberOnly),
AlwaysAuthorize_(AlwaysAuthorize),
Server_(Server),
MyRates_(Profile),
TransactionId_(TransactionId)
{
}
inline bool RoleIsAuthorized([[maybe_unused]] const std::string &Path,
[[maybe_unused]] const std::string &Method,
[[maybe_unused]] std::string &Reason) {
inline bool RoleIsAuthorized([[maybe_unused]] const std::string & Path, [[maybe_unused]] const std::string & Method, [[maybe_unused]] std::string & Reason) {
return true;
}
@@ -77,13 +87,11 @@ namespace OpenWifi {
if(Request->getContentLength()>0) {
if(Request->getContentType().find("application/json")!=std::string::npos) {
ParsedBody_ = IncomingParser_.parse(Request->stream())
.extract<Poco::JSON::Object::Ptr>();
ParsedBody_ = IncomingParser_.parse(Request->stream()).extract<Poco::JSON::Object::Ptr>();
}
}
if (RateLimited_ && RESTAPI_RateLimiter()->IsRateLimited(
RequestIn, MyRates_.Interval, MyRates_.MaxCalls)) {
if(RateLimited_ && RESTAPI_RateLimiter()->IsRateLimited(RequestIn,MyRates_.Interval, MyRates_.MaxCalls)) {
return UnAuthorized(RESTAPI::Errors::RATE_LIMIT_EXCEEDED);
}
@@ -122,13 +130,9 @@ namespace OpenWifi {
}
[[nodiscard]] inline bool NeedAdditionalInfo() const { return QB_.AdditionalInfo; }
[[nodiscard]] inline const std::vector<std::string> &SelectedRecords() const {
return QB_.Select;
}
[[nodiscard]] inline const std::vector<std::string> & SelectedRecords() const { return QB_.Select; }
inline static bool ParseBindings(const std::string &Request,
const std::list<std::string> &EndPoints,
BindingMap &bindings) {
inline static bool ParseBindings(const std::string & Request, const std::list<std::string> & EndPoints, BindingMap &bindings) {
bindings.clear();
auto PathItems = Poco::StringTokenizer(Request, "/");
@@ -176,39 +180,29 @@ namespace OpenWifi {
return false;
}
[[nodiscard]] inline uint64_t GetParameter(const std::string &Name,
const uint64_t Default) {
auto Hint = std::find_if(
Parameters_.begin(), Parameters_.end(),
[&](const std::pair<std::string, std::string> &S) { return S.first == Name; });
[[nodiscard]] inline uint64_t GetParameter(const std::string &Name, const uint64_t Default) {
auto Hint = std::find_if(Parameters_.begin(),Parameters_.end(),[&](const std::pair<std::string,std::string> &S){ return S.first==Name; });
if(Hint==Parameters_.end() || !is_number(Hint->second))
return Default;
return std::stoull(Hint->second);
}
[[nodiscard]] inline bool GetBoolParameter(const std::string &Name, bool Default=false) {
auto Hint = std::find_if(
begin(Parameters_), end(Parameters_),
[&](const std::pair<std::string, std::string> &S) { return S.first == Name; });
auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[&](const std::pair<std::string,std::string> &S){ return S.first==Name; });
if(Hint==end(Parameters_) || !is_bool(Hint->second))
return Default;
return Hint->second=="true";
}
[[nodiscard]] inline std::string GetParameter(const std::string &Name,
const std::string &Default = "") {
auto Hint = std::find_if(
begin(Parameters_), end(Parameters_),
[&](const std::pair<std::string, std::string> &S) { return S.first == Name; });
[[nodiscard]] inline std::string GetParameter(const std::string &Name, const std::string &Default="") {
auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[&](const std::pair<std::string,std::string> &S){ return S.first==Name; });
if(Hint==end(Parameters_))
return Default;
return Hint->second;
}
[[nodiscard]] inline bool HasParameter(const std::string &Name, std::string &Value) {
auto Hint = std::find_if(
begin(Parameters_), end(Parameters_),
[&](const std::pair<std::string, std::string> &S) { return S.first == Name; });
auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[&](const std::pair<std::string,std::string> &S){ return S.first==Name; });
if(Hint==end(Parameters_))
return false;
Value = Hint->second;
@@ -216,17 +210,14 @@ namespace OpenWifi {
}
[[nodiscard]] inline bool HasParameter(const std::string &Name, uint64_t & Value) {
auto Hint = std::find_if(
begin(Parameters_), end(Parameters_),
[&](const std::pair<std::string, std::string> &S) { return S.first == Name; });
auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[&](const std::pair<std::string,std::string> &S){ return S.first==Name; });
if(Hint==end(Parameters_))
return false;
Value = std::stoull(Hint->second);
return true;
}
[[nodiscard]] inline const std::string &GetBinding(const std::string &Name,
const std::string &Default = "") {
[[nodiscard]] inline const std::string & GetBinding(const std::string &Name, const std::string &Default="") {
auto E = Bindings_.find(Poco::toLower(Name));
if (E == Bindings_.end())
return Default;
@@ -245,8 +236,7 @@ namespace OpenWifi {
return Return;
}
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
const std::string &Field, Types::UUIDvec_t &Value) {
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, Types::UUIDvec_t & Value) {
if(O->has(Field) && O->isArray(Field)) {
auto Arr = O->getArray(Field);
for(const auto &i:*Arr)
@@ -256,8 +246,7 @@ namespace OpenWifi {
return false;
}
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
const std::string &Field, std::string &Value) {
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, std::string &Value) {
if(O->has(Field)) {
Value = O->get(Field).toString();
return true;
@@ -265,8 +254,7 @@ namespace OpenWifi {
return false;
}
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
const std::string &Field, uint64_t &Value) {
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, uint64_t &Value) {
if(O->has(Field)) {
Value = O->get(Field);
return true;
@@ -274,8 +262,7 @@ namespace OpenWifi {
return false;
}
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
const std::string &Field, bool &Value) {
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, bool &Value) {
if(O->has(Field)) {
Value = O->get(Field).toString()=="true";
return true;
@@ -283,8 +270,7 @@ namespace OpenWifi {
return false;
}
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
const std::string &Field, double &Value) {
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, double &Value) {
if(O->has(Field)) {
Value = (double) O->get(Field);
return true;
@@ -292,8 +278,7 @@ namespace OpenWifi {
return false;
}
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
const std::string &Field, Poco::Data::BLOB &Value) {
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, Poco::Data::BLOB &Value) {
if(O->has(Field)) {
std::string Content = O->get(Field).toString();
auto DecodedBlob = Utils::base64decode(Content);
@@ -303,9 +288,8 @@ namespace OpenWifi {
return false;
}
template <typename T>
bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field,
const T &value, T &assignee) {
template <typename T> bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, const T &value, T & assignee) {
if(O->has(Field)) {
assignee = value;
return true;
@@ -358,15 +342,13 @@ namespace OpenWifi {
Response->send();
}
inline void PrepareResponse(
Poco::Net::HTTPResponse::HTTPStatus Status = Poco::Net::HTTPResponse::HTTP_OK,
inline void PrepareResponse(Poco::Net::HTTPResponse::HTTPStatus Status = Poco::Net::HTTPResponse::HTTP_OK,
bool CloseConnection = false) {
Response->setStatus(Status);
SetCommonHeaders(CloseConnection);
}
inline void BadRequest(const OpenWifi::RESTAPI::Errors::msg &E,
const std::string &Extra = "") {
inline void BadRequest(const OpenWifi::RESTAPI::Errors::msg &E, const std::string & Extra="") {
PrepareResponse(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
Poco::JSON::Object ErrorObject;
ErrorObject.set("ErrorCode",400);
@@ -374,8 +356,7 @@ namespace OpenWifi {
if(Extra.empty())
ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ;
else
ErrorObject.set("ErrorDescription",
fmt::format("{}: {} ({})", E.err_num, E.err_txt, Extra));
ErrorObject.set("ErrorDescription",fmt::format("{}: {} ({})",E.err_num,E.err_txt, Extra)) ;
std::ostream &Answer = Response->send();
Poco::JSON::Stringifier::stringify(ErrorObject, Answer);
@@ -410,10 +391,11 @@ namespace OpenWifi {
ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ;
std::ostream &Answer = Response->send();
Poco::JSON::Stringifier::stringify(ErrorObject, Answer);
poco_debug(Logger_,
fmt::format("RES-NOTFOUND: User='{}@{}' Method='{}' Path='{}", Requester(),
poco_debug(Logger_,fmt::format("RES-NOTFOUND: User='{}@{}' Method='{}' Path='{}",
Requester(),
Utils::FormatIPv6(Request->clientAddress().toString()),
Request->getMethod(), Request->getURI()));
Request->getMethod(),
Request->getURI()));
}
inline void OK() {
@@ -474,8 +456,7 @@ namespace OpenWifi {
Response->sendFile(File.path(),MT.ContentType);
}
inline void SendFile(Poco::TemporaryFile &TempAvatar,
[[maybe_unused]] const std::string &Type, const std::string &Name) {
inline void SendFile(Poco::TemporaryFile &TempAvatar, [[maybe_unused]] const std::string &Type, const std::string & Name) {
Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK);
SetCommonHeaders();
auto MT = Utils::FindMediaType(Name);
@@ -483,7 +464,6 @@ namespace OpenWifi {
Response->set("Content-Transfer-Encoding","binary");
Response->set("Accept-Ranges", "bytes");
}
Response->set("Access-Control-Expose-Headers", "Content-Disposition");
Response->set("Content-Disposition", "attachment; filename=" + Name );
Response->set("Accept-Ranges", "bytes");
Response->set("Cache-Control", "no-store");
@@ -492,8 +472,7 @@ namespace OpenWifi {
Response->sendFile(TempAvatar.path(),MT.ContentType);
}
inline void SendFileContent(const std::string &Content, [[maybe_unused]] const std::string &Type,
const std::string &Name) {
inline void SendFileContent(const std::string &Content, const std::string &Type, const std::string & Name) {
Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK);
SetCommonHeaders();
auto MT = Utils::FindMediaType(Name);
@@ -501,18 +480,18 @@ namespace OpenWifi {
Response->set("Content-Transfer-Encoding","binary");
Response->set("Accept-Ranges", "bytes");
}
Response->set("Access-Control-Expose-Headers", "Content-Disposition");
Response->set("Content-Disposition", "attachment; filename=" + Name );
Response->set("Accept-Ranges", "bytes");
Response->set("Cache-Control", "no-store");
Response->set("Expires", "Mon, 26 Jul 2027 05:00:00 GMT");
Response->setContentLength(Content.size());
Response->setContentType(MT.ContentType);
Response->setContentType(Type );
auto & OutputStream = Response->send();
OutputStream << Content ;
}
inline void SendHTMLFileBack(Poco::File &File, const Types::StringPairVec &FormVars) {
inline void SendHTMLFileBack(Poco::File & File,
const Types::StringPairVec & FormVars) {
Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK);
SetCommonHeaders();
Response->set("Pragma", "private");
@@ -526,8 +505,7 @@ namespace OpenWifi {
ostr << FormContent;
}
inline void ReturnStatus(Poco::Net::HTTPResponse::HTTPStatus Status,
bool CloseConnection = false) {
inline void ReturnStatus(Poco::Net::HTTPResponse::HTTPStatus Status, bool CloseConnection=false) {
PrepareResponse(Status, CloseConnection);
if(Status == Poco::Net::HTTPResponse::HTTP_NO_CONTENT) {
Response->setContentLength(0);
@@ -541,8 +519,7 @@ namespace OpenWifi {
if (Request->getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS) {
ProcessOptions();
return false;
} else if (std::find(Methods_.begin(), Methods_.end(), Request->getMethod()) ==
Methods_.end()) {
} else if (std::find(Methods_.begin(), Methods_.end(), Request->getMethod()) == Methods_.end()) {
BadRequest(RESTAPI::Errors::UnsupportedHTTPMethod);
return false;
}
@@ -562,8 +539,7 @@ namespace OpenWifi {
AcceptedEncoding->second.find("compress")!=std::string::npos) {
Response->set("Content-Encoding", "gzip");
std::ostream &Answer = Response->send();
Poco::DeflatingOutputStream deflater(Answer,
Poco::DeflatingStreamBuf::STREAM_GZIP);
Poco::DeflatingOutputStream deflater(Answer, Poco::DeflatingStreamBuf::STREAM_GZIP);
Poco::JSON::Stringifier::stringify(Object, deflater);
deflater.close();
return;
@@ -584,8 +560,7 @@ namespace OpenWifi {
AcceptedEncoding->second.find("compress")!=std::string::npos) {
Response->set("Content-Encoding", "gzip");
std::ostream &Answer = Response->send();
Poco::DeflatingOutputStream deflater(Answer,
Poco::DeflatingStreamBuf::STREAM_GZIP);
Poco::DeflatingOutputStream deflater(Answer, Poco::DeflatingStreamBuf::STREAM_GZIP);
deflater << json_doc;
deflater.close();
return;
@@ -630,23 +605,19 @@ namespace OpenWifi {
return true;
}
[[nodiscard]] inline uint64_t Get(const char *Parameter, const Poco::JSON::Object::Ptr &Obj,
uint64_t Default = 0) {
[[nodiscard]] inline uint64_t Get(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, uint64_t Default=0){
if(Obj->has(Parameter))
return Obj->get(Parameter);
return Default;
}
[[nodiscard]] inline std::string GetS(const char *Parameter,
const Poco::JSON::Object::Ptr &Obj,
const std::string &Default = "") {
[[nodiscard]] inline std::string GetS(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, const std::string & Default=""){
if(Obj->has(Parameter))
return Obj->get(Parameter).toString();
return Default;
}
[[nodiscard]] inline bool GetB(const char *Parameter, const Poco::JSON::Object::Ptr &Obj,
bool Default = false) {
[[nodiscard]] inline bool GetB(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, bool Default=false){
if(Obj->has(Parameter))
return Obj->get(Parameter).toString()=="true";
return Default;
@@ -686,7 +657,6 @@ namespace OpenWifi {
SecurityObjects::UserInfoAndPolicy UserInfo_;
QueryBlock QB_;
const std::string & Requester() const { return REST_Requester_; }
protected:
BindingMap Bindings_;
Poco::URI::QueryParameters Parameters_;
@@ -707,33 +677,29 @@ namespace OpenWifi {
};
#ifdef TIP_SECURITY_SERVICE
[[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest &Request,
std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo,
std::uint64_t TID, bool &Expired, bool Sub);
[[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired , bool Sub );
#endif
inline bool RESTAPIHandler::IsAuthorized(bool &Expired, [[maybe_unused]] bool &Contacted,
bool Sub) {
inline bool RESTAPIHandler::IsAuthorized( bool & Expired , [[maybe_unused]] bool & Contacted , bool Sub ) {
if(Internal_ && Request->has("X-INTERNAL-NAME")) {
auto Allowed = MicroServiceIsValidAPIKEY(*Request);
Contacted = true;
if(!Allowed) {
if(Server_.LogBadTokens(false)) {
poco_debug(Logger_,
fmt::format("I-REQ-DENIED({}): TID={} Method={} Path={}",
poco_debug(Logger_,fmt::format("I-REQ-DENIED({}): TID={} Method={} Path={}",
Utils::FormatIPv6(Request->clientAddress().toString()),
TransactionId_, Request->getMethod(),
Request->getURI()));
TransactionId_,
Request->getMethod(), Request->getURI()));
}
} else {
auto Id = Request->get("X-INTERNAL-NAME", "unknown");
REST_Requester_ = Id;
if(Server_.LogIt(Request->getMethod(),true)) {
poco_debug(Logger_,
fmt::format("I-REQ-ALLOWED({}): TID={} User='{}' Method={} Path={}",
poco_debug(Logger_,fmt::format("I-REQ-ALLOWED({}): TID={} User='{}' Method={} Path={}",
Utils::FormatIPv6(Request->clientAddress().toString()),
TransactionId_, Id, Request->getMethod(),
Request->getURI()));
TransactionId_,
Id,
Request->getMethod(), Request->getURI()));
}
}
return Allowed;
@@ -742,29 +708,27 @@ namespace OpenWifi {
bool suspended=false;
#ifdef TIP_SECURITY_SERVICE
std::uint64_t expiresOn;
if (AuthService()->IsValidApiKey(SessionToken_, UserInfo_.webtoken, UserInfo_.userinfo,
Expired, expiresOn, suspended)) {
if (AuthService()->IsValidApiKey(SessionToken_, UserInfo_.webtoken, UserInfo_.userinfo, Expired, expiresOn, suspended)) {
#else
if (AuthClient()->IsValidApiKey(SessionToken_, UserInfo_, TransactionId_, Expired,
Contacted, suspended)) {
if (AuthClient()->IsValidApiKey( SessionToken_, UserInfo_, TransactionId_, Expired, Contacted, suspended)) {
#endif
REST_Requester_ = UserInfo_.userinfo.email;
if(Server_.LogIt(Request->getMethod(),true)) {
poco_debug(Logger_,
fmt::format("X-REQ-ALLOWED({}): APIKEY-ACCESS TID={} User='{}@{}' "
"Method={} Path={}",
UserInfo_.userinfo.email, TransactionId_,
poco_debug(Logger_,fmt::format("X-REQ-ALLOWED({}): APIKEY-ACCESS TID={} User='{}@{}' Method={} Path={}",
UserInfo_.userinfo.email,
TransactionId_,
Utils::FormatIPv6(Request->clientAddress().toString()),
Request->clientAddress().toString(),
Request->getMethod(), Request->getURI()));
Request->getMethod(),
Request->getURI()));
}
return true;
} else {
if(Server_.LogBadTokens(true)) {
poco_debug(Logger_,
fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}",
poco_debug(Logger_,fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}",
Utils::FormatIPv6(Request->clientAddress().toString()),
TransactionId_, Request->getMethod(),
TransactionId_,
Request->getMethod(),
Request->getURI()));
}
}
@@ -781,29 +745,27 @@ namespace OpenWifi {
}
}
#ifdef TIP_SECURITY_SERVICE
if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_, TransactionId_, Expired,
Sub)) {
if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_, TransactionId_, Expired, Sub)) {
#else
if (AuthClient()->IsAuthorized(SessionToken_, UserInfo_, TransactionId_, Expired,
Contacted, Sub)) {
if (AuthClient()->IsAuthorized( SessionToken_, UserInfo_, TransactionId_, Expired, Contacted, Sub)) {
#endif
REST_Requester_ = UserInfo_.userinfo.email;
if(Server_.LogIt(Request->getMethod(),true)) {
poco_debug(
Logger_,
fmt::format("X-REQ-ALLOWED({}): TID={} User='{}@{}' Method={} Path={}",
UserInfo_.userinfo.email, TransactionId_,
poco_debug(Logger_,fmt::format("X-REQ-ALLOWED({}): TID={} User='{}@{}' Method={} Path={}",
UserInfo_.userinfo.email,
TransactionId_,
Utils::FormatIPv6(Request->clientAddress().toString()),
Request->clientAddress().toString(), Request->getMethod(),
Request->clientAddress().toString(),
Request->getMethod(),
Request->getURI()));
}
return true;
} else {
if(Server_.LogBadTokens(true)) {
poco_debug(Logger_,
fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}",
poco_debug(Logger_,fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}",
Utils::FormatIPv6(Request->clientAddress().toString()),
TransactionId_, Request->getMethod(),
TransactionId_,
Request->getMethod(),
Request->getURI()));
}
}
@@ -813,11 +775,8 @@ namespace OpenWifi {
class RESTAPI_UnknownRequestHandler : public RESTAPIHandler {
public:
RESTAPI_UnknownRequestHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server,
uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L, std::vector<std::string>{}, Server, TransactionId,
Internal) {}
RESTAPI_UnknownRequestHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L, std::vector<std::string>{}, Server, TransactionId, Internal) {}
inline void DoGet() override {};
inline void DoPost() override {};
inline void DoPut() override {};
@@ -825,37 +784,35 @@ namespace OpenWifi {
};
template<class T>
constexpr auto test_has_PathName_method(T *) -> decltype(T::PathName(), std::true_type{}) {
constexpr auto test_has_PathName_method(T*)
-> decltype( T::PathName() , std::true_type{} )
{
return std::true_type{};
}
constexpr auto test_has_PathName_method(...) -> std::false_type { return std::false_type{}; }
constexpr auto test_has_PathName_method(...) -> std::false_type
{
return std::false_type{};
}
template<typename T, typename... Args>
RESTAPIHandler *RESTAPI_Router(const std::string &RequestedPath,
RESTAPIHandler::BindingMap &Bindings, Poco::Logger &Logger,
RESTAPI_GenericServerAccounting &Server,
uint64_t TransactionId) {
static_assert(test_has_PathName_method((T *)nullptr),
"Class must have a static PathName() method.");
RESTAPIHandler * RESTAPI_Router(const std::string & RequestedPath, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & Logger, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId) {
static_assert(test_has_PathName_method((T*)nullptr), "Class must have a static PathName() method.");
if(RESTAPIHandler::ParseBindings(RequestedPath,T::PathName(),Bindings)) {
return new T(Bindings, Logger, Server, TransactionId, false);
}
if constexpr (sizeof...(Args) == 0) {
return new RESTAPI_UnknownRequestHandler(Bindings, Logger, Server, TransactionId,
false);
return new RESTAPI_UnknownRequestHandler(Bindings,Logger, Server, TransactionId, false);
} else {
return RESTAPI_Router<Args...>(RequestedPath, Bindings, Logger, Server, TransactionId);
}
}
template<typename T, typename... Args>
RESTAPIHandler *RESTAPI_Router_I(const std::string &RequestedPath,
RESTAPIHandler::BindingMap &Bindings, Poco::Logger &Logger,
RESTAPI_GenericServerAccounting &Server,
uint64_t TransactionId) {
static_assert(test_has_PathName_method((T *)nullptr),
"Class must have a static PathName() method.");
RESTAPIHandler * RESTAPI_Router_I(const std::string & RequestedPath, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & Logger, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId) {
static_assert(test_has_PathName_method((T*)nullptr), "Class must have a static PathName() method.");
if(RESTAPIHandler::ParseBindings(RequestedPath,T::PathName(),Bindings)) {
return new T(Bindings, Logger, Server, TransactionId, true );
}
@@ -863,8 +820,7 @@ namespace OpenWifi {
if constexpr (sizeof...(Args) == 0) {
return new RESTAPI_UnknownRequestHandler(Bindings,Logger, Server, TransactionId, true);
} else {
return RESTAPI_Router_I<Args...>(RequestedPath, Bindings, Logger, Server,
TransactionId);
return RESTAPI_Router_I<Args...>(RequestedPath, Bindings, Logger, Server, TransactionId);
}
}

View File

@@ -6,21 +6,18 @@
#include "Poco/Net/HTTPServer.h"
#include "framework/RESTAPI_Handler.h"
#include "framework/SubSystemServer.h"
#include "framework/RESTAPI_Handler.h"
namespace OpenWifi {
Poco::Net::HTTPRequestHandler *
RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServerAccounting & S, uint64_t Id);
class IntRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
public:
inline IntRequestHandlerFactory() = default;
Poco::Net::HTTPRequestHandler *
createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override;
Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override;
private:
static inline std::atomic_uint64_t NextTransactionId_ = 1;
};
@@ -39,15 +36,10 @@ namespace OpenWifi {
for(const auto & Svr: ConfigServersList_) {
if(MicroServiceNoAPISecurity()) {
poco_information(
Logger(),
fmt::format("Starting: {}:{}. Security has been disabled for APIs.",
Svr.Address(), Svr.Port()));
poco_information(Logger(),fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port()));
} else {
poco_information(Logger(),
fmt::format("Starting: {}:{}. Keyfile:{} CertFile: {}",
Svr.Address(), Svr.Port(), Svr.KeyFile(),
Svr.CertFile()));
poco_information(Logger(),fmt::format("Starting: {}:{}. Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(),
Svr.KeyFile(),Svr.CertFile()));
Svr.LogCert(Logger());
if (!Svr.RootCA().empty())
Svr.LogCas(Logger());
@@ -60,12 +52,10 @@ namespace OpenWifi {
std::unique_ptr<Poco::Net::HTTPServer> NewServer;
if(MicroServiceNoAPISecurity()) {
auto Sock{Svr.CreateSocket(Logger())};
NewServer = std::make_unique<Poco::Net::HTTPServer>(
new IntRequestHandlerFactory, Pool_, Sock, Params);
NewServer = std::make_unique<Poco::Net::HTTPServer>(new IntRequestHandlerFactory, Pool_, Sock, Params);
} else {
auto Sock{Svr.CreateSecureSocket(Logger())};
NewServer = std::make_unique<Poco::Net::HTTPServer>(
new IntRequestHandlerFactory, Pool_, Sock, Params);
NewServer = std::make_unique<Poco::Net::HTTPServer>(new IntRequestHandlerFactory, Pool_, Sock, Params);
};
NewServer->start();
RESTServers_.push_back(std::move(NewServer));
@@ -96,16 +86,19 @@ namespace OpenWifi {
return RESTAPI_IntRouter(Path, Bindings, Logger(), Server_, Id);
}
const Poco::ThreadPool & Pool() { return Pool_; }
private:
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> RESTServers_;
Poco::ThreadPool Pool_{"i-rest",4,64};
RESTAPI_GenericServerAccounting Server_;
RESTAPI_IntServer() noexcept
: SubSystemServer("RESTAPI_IntServer", "REST-ISRV", "openwifi.internal.restapi") {}
RESTAPI_IntServer() noexcept:
SubSystemServer("RESTAPI_IntServer", "REST-ISRV", "openwifi.internal.restapi")
{
}
};
inline auto RESTAPI_IntServer() { return RESTAPI_IntServer::instance(); };
} // namespace OpenWifi

View File

@@ -4,26 +4,29 @@
#pragma once
#include "Poco/CountingStream.h"
#include "Poco/Net/MessageHeader.h"
#include <string>
#include "Poco/Net/PartHandler.h"
#include "Poco/Net/MessageHeader.h"
#include "Poco/CountingStream.h"
#include "Poco/NullStream.h"
#include "Poco/StreamCopier.h"
#include <string>
namespace OpenWifi {
class RESTAPI_PartHandler: public Poco::Net::PartHandler {
public:
RESTAPI_PartHandler() : _length(0) {}
RESTAPI_PartHandler():
_length(0)
{
}
inline void handlePart(const Poco::Net::MessageHeader &header,
std::istream &stream) override {
inline void handlePart(const Poco::Net::MessageHeader& header, std::istream& stream) override
{
_type = header.get("Content-Type", "(unspecified)");
if (header.has("Content-Disposition")) {
if (header.has("Content-Disposition"))
{
std::string disp;
Poco::Net::NameValueCollection params;
Poco::Net::MessageHeader::splitParameters(header["Content-Disposition"], disp,
params);
Poco::Net::MessageHeader::splitParameters(header["Content-Disposition"], disp, params);
_name = params.get("name", "(unnamed)");
_fileName = params.get("filename", "(unnamed)");
}
@@ -34,13 +37,25 @@ namespace OpenWifi {
_length = (int)istr.chars();
}
[[nodiscard]] inline int length() const { return _length; }
[[nodiscard]] inline int length() const
{
return _length;
}
[[nodiscard]] inline const std::string &name() const { return _name; }
[[nodiscard]] inline const std::string& name() const
{
return _name;
}
[[nodiscard]] inline const std::string &fileName() const { return _fileName; }
[[nodiscard]] inline const std::string& fileName() const
{
return _fileName;
}
[[nodiscard]] inline const std::string &contentType() const { return _type; }
[[nodiscard]] inline const std::string& contentType() const
{
return _type;
}
private:
int _length;
@@ -48,4 +63,4 @@ namespace OpenWifi {
std::string _name;
std::string _fileName;
};
} // namespace OpenWifi
}

View File

@@ -6,9 +6,9 @@
#include "framework/SubSystemServer.h"
#include "Poco/ExpireLRUCache.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/URI.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/ExpireLRUCache.h"
#include "fmt/format.h"
@@ -16,6 +16,7 @@ namespace OpenWifi {
class RESTAPI_RateLimiter : public SubSystemServer {
public:
struct ClientCacheEntry {
int64_t Start=0;
int Count=0;
@@ -29,14 +30,11 @@ namespace OpenWifi {
inline int Start() final { return 0;};
inline void Stop() final { };
inline bool IsRateLimited(const Poco::Net::HTTPServerRequest &R, int64_t Period,
int64_t MaxCalls) {
inline bool IsRateLimited(const Poco::Net::HTTPServerRequest &R, int64_t Period, int64_t MaxCalls) {
Poco::URI uri(R.getURI());
auto H = str_hash(uri.getPath() + R.clientAddress().host().toString());
auto E = Cache_.get(H);
auto Now = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
auto Now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
if(E.isNull()) {
Cache_.add(H,ClientCacheEntry{.Start=Now, .Count=1});
return false;
@@ -45,8 +43,7 @@ namespace OpenWifi {
E->Count++;
Cache_.update(H,E);
if(E->Count > MaxCalls) {
poco_warning(Logger(), fmt::format("RATE-LIMIT-EXCEEDED: from '{}'",
R.clientAddress().toString()));
poco_warning(Logger(),fmt::format("RATE-LIMIT-EXCEEDED: from '{}'", R.clientAddress().toString()));
return true;
}
return false;
@@ -57,16 +54,22 @@ namespace OpenWifi {
return false;
}
inline void Clear() { Cache_.clear(); }
inline void Clear() {
Cache_.clear();
}
private:
Poco::ExpireLRUCache<uint64_t,ClientCacheEntry> Cache_{2048};
std::hash<std::string> str_hash;
RESTAPI_RateLimiter() noexcept
: SubSystemServer("RateLimiter", "RATE-LIMITER", "rate.limiter") {}
RESTAPI_RateLimiter() noexcept:
SubSystemServer("RateLimiter", "RATE-LIMITER", "rate.limiter")
{
}
};
inline auto RESTAPI_RateLimiter() { return RESTAPI_RateLimiter::instance(); }
} // namespace OpenWifi
}

View File

@@ -14,20 +14,19 @@ namespace OpenWifi {
class RESTAPI_system_command : public RESTAPIHandler {
public:
RESTAPI_system_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
RESTAPI_system_command(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_POST,
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
Server,
TransactionId,
Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/system"};}
inline void DoGet() final {
inline void DoGet() {
std::string Arg;
if (HasParameter("command", Arg)) {
if (Arg == "info") {
if(HasParameter("command",Arg) && Arg=="info") {
Poco::JSON::Object Answer;
Answer.set(RESTAPI::Protocol::VERSION, MicroServiceVersion());
Answer.set(RESTAPI::Protocol::UPTIME, MicroServiceUptimeTotalSeconds());
@@ -65,23 +64,11 @@ namespace OpenWifi {
Answer.set("certificates", Certificates);
return ReturnObject(Answer);
}
if (Arg == "extraConfiguration") {
if(GetBoolParameter("extraConfiguration")) {
Poco::JSON::Object Answer;
MicroServiceGetExtraConfiguration(Answer);
return ReturnObject(Answer);
}
if (Arg == "resources") {
Poco::JSON::Object Answer;
Answer.set("numberOfFileDescriptors", Utils::get_open_fds());
std::uint64_t currRealMem, peakRealMem, currVirtMem, peakVirtMem;
Utils::getMemory(currRealMem, peakRealMem, currVirtMem, peakVirtMem);
Answer.set("currRealMem", currRealMem);
Answer.set("peakRealMem", peakRealMem);
Answer.set("currVirtMem", currVirtMem);
Answer.set("peakVirtMem", peakVirtMem);
return ReturnObject(Answer);
}
}
BadRequest(RESTAPI::Errors::InvalidCommand);
}
@@ -101,8 +88,7 @@ namespace OpenWifi {
auto Name = GetS(RESTAPI::Protocol::TAG, InnerObj);
auto Value = GetS(RESTAPI::Protocol::VALUE, InnerObj);
MicroServiceSetSubsystemLogLevel(Name, Value);
poco_information(
Logger_,
poco_information(Logger_,
fmt::format("Setting log level for {} at {}", Name, Value));
}
}
@@ -168,4 +154,4 @@ namespace OpenWifi {
void DoDelete() final {};
};
} // namespace OpenWifi
}

View File

@@ -4,33 +4,32 @@
#pragma once
#include "Poco/Net/WebSocket.h"
#include "framework/RESTAPI_Handler.h"
#include "Poco/Net/WebSocket.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/UI_WebSocketClientServer.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
class RESTAPI_webSocketServer : public RESTAPIHandler {
public:
inline RESTAPI_webSocketServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server,
uint64_t TransactionId, bool Internal)
inline RESTAPI_webSocketServer(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_OPTIONS},
Server, TransactionId, Internal,false) {}
static auto PathName() { return std::list<std::string>{"/api/v1/ws"};}
void DoGet() final {
try {
if (Request->find("Upgrade") != Request->end() &&
Poco::icompare((*Request)["Upgrade"], "websocket") == 0) {
try {
try
{
if(Request->find("Upgrade") != Request->end() && Poco::icompare((*Request)["Upgrade"], "websocket") == 0) {
try
{
Poco::Net::WebSocket WS(*Request, *Response);
auto Id = MicroServiceCreateUUID();
UI_WebSocketClientServer()->NewClient(WS, Id, UserInfo_.userinfo.email,
TransactionId_);
} catch (...) {
UI_WebSocketClientServer()->NewClient(WS,Id,UserInfo_.userinfo.email, TransactionId_);
}
catch (...) {
std::cout << "Cannot create websocket client..." << std::endl;
}
}
@@ -41,7 +40,6 @@ namespace OpenWifi {
void DoDelete() final {};
void DoPost() final {};
void DoPut() final {};
private:
};
} // namespace OpenWifi
}

View File

@@ -6,25 +6,17 @@
#include <string>
#include "Poco/Data/LOB.h"
#include "Poco/JSON/Object.h"
#include "Poco/JSON/Parser.h"
#include "Poco/Data/LOB.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "framework/OpenWifiTypes.h"
#include "framework/utils.h"
#include <RESTObjects/RESTAPI_SecurityObjects.h>
namespace OpenWifi::RESTAPI_utils {
inline bool IsRootOrAdmin(const SecurityObjects::UserInfo &UI) {
return UI.userRole==SecurityObjects::ROOT ||
UI.userRole==SecurityObjects::ADMIN;
}
inline void EmbedDocument(const std::string &ObjName, Poco::JSON::Object &Obj,
const std::string &ObjStr) {
inline void EmbedDocument(const std::string & ObjName, Poco::JSON::Object & Obj, const std::string &ObjStr) {
std::string D = ObjStr.empty() ? "{}" : ObjStr;
Poco::JSON::Parser P;
Poco::Dynamic::Var result = P.parse(D);
@@ -76,14 +68,12 @@ namespace OpenWifi::RESTAPI_utils {
Obj.set(Field,Value);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
const Poco::Data::BLOB &Value) {
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Poco::Data::BLOB &Value) {
auto Result = Utils::base64encode((const unsigned char *)Value.rawContent(),Value.size());
Obj.set(Field,Result);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
const Types::StringPairVec &S) {
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::StringPairVec & S) {
Poco::JSON::Array Array;
for(const auto &i:S) {
Poco::JSON::Object O;
@@ -94,22 +84,7 @@ namespace OpenWifi::RESTAPI_utils {
Obj.set(Field,Array);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
const Types::StringVec &V) {
Poco::JSON::Array A;
for (const auto &i : V)
A.add(i);
Obj.set(Field, A);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::DoubleList &V) {
Poco::JSON::Array A;
for (const auto &i : V)
A.add(i);
Obj.set(Field, A);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::IntList &V) {
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::StringVec &V) {
Poco::JSON::Array A;
for(const auto &i:V)
A.add(i);
@@ -123,8 +98,7 @@ namespace OpenWifi::RESTAPI_utils {
Obj.set(Field,A);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
const Types::CountedMap &M) {
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::CountedMap &M) {
Poco::JSON::Array A;
for(const auto &[Key,Value]:M) {
Poco::JSON::Object O;
@@ -135,8 +109,7 @@ namespace OpenWifi::RESTAPI_utils {
Obj.set(Field,A);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
const Types::Counted3DMapSII &M) {
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::Counted3DMapSII &M) {
Poco::JSON::Array A;
for(const auto &[OrgName,MonthlyNumberMap]:M) {
Poco::JSON::Object OrgObject;
@@ -154,14 +127,14 @@ namespace OpenWifi::RESTAPI_utils {
Obj.set(Field, A);
}
template <typename T>
void field_to_json(Poco::JSON::Object &Obj, const char *Field, const T &V,
template<typename T> void field_to_json(Poco::JSON::Object &Obj,
const char *Field,
const T &V,
std::function<std::string(const T &)> F) {
Obj.set(Field, F(V));
}
template <class T>
void field_to_json(Poco::JSON::Object &Obj, const char *Field, const std::vector<T> &Value) {
template<class T> void field_to_json(Poco::JSON::Object &Obj, const char *Field, const std::vector<T> &Value) {
Poco::JSON::Array Arr;
for(const auto &i:Value) {
Poco::JSON::Object AO;
@@ -171,8 +144,7 @@ namespace OpenWifi::RESTAPI_utils {
Obj.set(Field, Arr);
}
template <class T>
void field_to_json(Poco::JSON::Object &Obj, const char *Field, const T &Value) {
template<class T> void field_to_json(Poco::JSON::Object &Obj, const char *Field, const T &Value) {
Poco::JSON::Object Answer;
Value.to_json(Answer);
Obj.set(Field, Answer);
@@ -183,84 +155,71 @@ namespace OpenWifi::RESTAPI_utils {
///////////////////////////
///////////////////////////
template <typename T>
bool field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T &V,
template<typename T> bool field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T & V,
std::function<T(const std::string &)> F) {
if(Obj->has(Field) && !Obj->isNull(Field))
V = F(Obj->get(Field).toString());
return true;
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
std::string &S) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, std::string &S) {
if(Obj->has(Field) && !Obj->isNull(Field))
S = Obj->get(Field).toString();
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
double &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, double & Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
Value = (double)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
float &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, float & Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
Value = (float)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
bool &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, bool &Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
Value = (Obj->get(Field).toString() == "true");
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
int16_t &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, int16_t &Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
Value = (int16_t)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
int32_t &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, int32_t &Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
Value = (int32_t) Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
int64_t &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, int64_t &Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
Value = (int64_t)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
uint16_t &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, uint16_t &Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
Value = (uint16_t)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
uint32_t &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, uint32_t &Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
Value = (uint32_t)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
uint64_t &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, uint64_t &Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
Value = (uint64_t)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
Poco::Data::BLOB &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Poco::Data::BLOB &Value) {
if(Obj->has(Field) && !Obj->isNull(Field)) {
auto Result = Utils::base64decode(Obj->get(Field).toString());
Value.assignRaw((const unsigned char *)&Result[0],Result.size());
}
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
Types::StringPairVec &Vec) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::StringPairVec &Vec) {
if(Obj->isArray(Field) && !Obj->isNull(Field)) {
auto O = Obj->getArray(Field);
for(const auto &i:*O) {
@@ -276,8 +235,7 @@ namespace OpenWifi::RESTAPI_utils {
}
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
Types::StringVec &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::StringVec &Value) {
if(Obj->isArray(Field) && !Obj->isNull(Field)) {
Value.clear();
Poco::JSON::Array::Ptr A = Obj->getArray(Field);
@@ -287,8 +245,7 @@ namespace OpenWifi::RESTAPI_utils {
}
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
Types::TagList &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::TagList &Value) {
if(Obj->isArray(Field) && !Obj->isNull(Field)) {
Value.clear();
Poco::JSON::Array::Ptr A = Obj->getArray(Field);
@@ -298,31 +255,7 @@ namespace OpenWifi::RESTAPI_utils {
}
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
Types::DoubleList &Value) {
if (Obj->isArray(Field) && !Obj->isNull(Field)) {
Value.clear();
Poco::JSON::Array::Ptr A = Obj->getArray(Field);
for (const auto &i : *A) {
Value.push_back(i);
}
}
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
Types::IntList &Value) {
if (Obj->isArray(Field) && !Obj->isNull(Field)) {
Value.clear();
Poco::JSON::Array::Ptr A = Obj->getArray(Field);
for (const auto &i : *A) {
Value.push_back(i);
}
}
}
template <class T>
void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
std::vector<T> &Value) {
template<class T> void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, std::vector<T> &Value) {
if(Obj->isArray(Field) && !Obj->isNull(Field)) {
Poco::JSON::Array::Ptr Arr = Obj->getArray(Field);
for(auto &i:*Arr) {
@@ -334,8 +267,7 @@ namespace OpenWifi::RESTAPI_utils {
}
}
template <class T>
void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T &Value) {
template<class T> void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T &Value) {
if(Obj->isObject(Field) && !Obj->isNull(Field)) {
Poco::JSON::Object::Ptr A = Obj->getObject(Field);
Value.from_json(A);
@@ -404,8 +336,7 @@ namespace OpenWifi::RESTAPI_utils {
for(auto const &j:i) {
if constexpr(std::is_integral<T>::value) {
InnerArr.add(j);
}
if constexpr (std::is_same_v<T, std::string>) {
} if constexpr(std::is_same_v<T,std::string>) {
InnerArr.add(j);
} else {
InnerArr.add(j);
@@ -442,6 +373,7 @@ namespace OpenWifi::RESTAPI_utils {
Result.push_back(i.toString());
}
} catch (...) {
}
return Result;
}
@@ -458,6 +390,7 @@ namespace OpenWifi::RESTAPI_utils {
Result.push_back(i);
}
} catch (...) {
}
return Result;
}
@@ -478,6 +411,7 @@ namespace OpenWifi::RESTAPI_utils {
}
}
} catch (...) {
}
return R;
@@ -498,12 +432,12 @@ namespace OpenWifi::RESTAPI_utils {
Result.push_back(Obj);
}
} catch (...) {
}
return Result;
}
template <class T>
std::vector<std::vector<T>> to_array_of_array_of_object(const std::string &ObjectString) {
template<class T> std::vector<std::vector<T>> to_array_of_array_of_object(const std::string & ObjectString) {
std::vector<std::vector<T>> Result;
if(ObjectString.empty())
return Result;
@@ -523,6 +457,7 @@ namespace OpenWifi::RESTAPI_utils {
Result.push_back(InnerVector);
}
} catch (...) {
}
return Result;
}
@@ -546,4 +481,4 @@ namespace OpenWifi::RESTAPI_utils {
Obj.from_json(RawObject);
return true;
}
} // namespace OpenWifi::RESTAPI_utils
}

View File

@@ -4,26 +4,34 @@
#pragma once
#include "Poco/Data/SQLite/Connector.h"
#include "Poco/Data/Session.h"
#include "Poco/Data/SessionPool.h"
#include "Poco/Data/SQLite/Connector.h"
#include "Poco/JSON/Object.h"
#ifndef SMALL_BUILD
#include "Poco/Data/MySQL/Connector.h"
#include "Poco/Data/PostgreSQL/Connector.h"
#include "Poco/Data/MySQL/Connector.h"
#endif
#include "framework/MicroServiceFuncs.h"
#include "framework/SubSystemServer.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
enum DBType { sqlite, pgsql, mysql };
enum DBType {
sqlite,
pgsql,
mysql
};
class StorageClass : public SubSystemServer {
public:
StorageClass() noexcept:
SubSystemServer("StorageClass", "STORAGE-SVR", "storage")
{
}
inline int Start() override {
int Start() override {
std::lock_guard Guard(Mutex_);
Logger().notice("Starting.");
@@ -39,22 +47,18 @@ namespace OpenWifi {
return 0;
}
inline void Stop() override { Pool_->shutdown(); }
DBType Type() const { return dbType_; };
StorageClass() noexcept : SubSystemServer("StorageClass", "STORAGE-SVR", "storage") {
void Stop() override {
Pool_->shutdown();
}
DBType Type() const { return dbType_; };
private:
inline int Setup_SQLite();
inline int Setup_MySQL();
inline int Setup_PostgreSQL();
protected:
std::shared_ptr<Poco::Data::SessionPool> Pool_;
std::unique_ptr<Poco::Data::SessionPool> Pool_;
Poco::Data::SQLite::Connector SQLiteConn_;
Poco::Data::PostgreSQL::Connector PostgresConn_;
Poco::Data::MySQL::Connector MySQLConn_;
@@ -62,30 +66,21 @@ namespace OpenWifi {
};
#ifdef SMALL_BUILD
int Service::Setup_MySQL() {
Daemon()->exit(Poco::Util::Application::EXIT_CONFIG);
return 0;
}
int Service::Setup_PostgreSQL() {
Daemon()->exit(Poco::Util::Application::EXIT_CONFIG);
return 0;
}
int Service::Setup_MySQL() { Daemon()->exit(Poco::Util::Application::EXIT_CONFIG); return 0; }
int Service::Setup_PostgreSQL() { Daemon()->exit(Poco::Util::Application::EXIT_CONFIG); return 0; }
#else
inline int StorageClass::Setup_SQLite() {
Logger().notice("SQLite StorageClass enabled.");
dbType_ = sqlite;
auto DBName = MicroServiceDataDirectory() + "/" +
MicroServiceConfigGetString("storage.type.sqlite.db", "");
auto DBName = MicroServiceDataDirectory() + "/" + MicroServiceConfigGetString("storage.type.sqlite.db","");
int NumSessions = (int) MicroServiceConfigGetInt("storage.type.sqlite.maxsessions", 64);
int IdleTime = (int) MicroServiceConfigGetInt("storage.type.sqlite.idletime", 60);
Poco::Data::SQLite::Connector::registerConnector();
// Pool_ = std::make_unique<Poco::Data::SessionPool>(new
// Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 8,
// (int)NumSessions,
// (int)IdleTime));
Pool_ = std::make_shared<Poco::Data::SessionPool>(SQLiteConn_.name(), DBName, 8,
// Pool_ = std::make_unique<Poco::Data::SessionPool>(new Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 8,
// (int)NumSessions, (int)IdleTime));
Pool_ = std::make_unique<Poco::Data::SessionPool>(SQLiteConn_.name(), DBName, 8,
(int)NumSessions, (int)IdleTime);
return 0;
}
@@ -101,13 +96,16 @@ namespace OpenWifi {
auto Database = MicroServiceConfigGetString("storage.type.mysql.database","");
auto Port = MicroServiceConfigGetString("storage.type.mysql.port","");
std::string ConnectionStr = "host=" + Host + ";user=" + Username + ";password=" + Password +
";db=" + Database + ";port=" + Port +
std::string ConnectionStr =
"host=" + Host +
";user=" + Username +
";password=" + Password +
";db=" + Database +
";port=" + Port +
";compress=true;auto-reconnect=true";
Poco::Data::MySQL::Connector::registerConnector();
Pool_ = std::make_shared<Poco::Data::SessionPool>(MySQLConn_.name(), ConnectionStr, 8,
NumSessions, IdleTime);
Pool_ = std::make_unique<Poco::Data::SessionPool>(MySQLConn_.name(), ConnectionStr, 8, NumSessions, IdleTime);
return 0;
}
@@ -122,19 +120,21 @@ namespace OpenWifi {
auto Password = MicroServiceConfigGetString("storage.type.postgresql.password", "");
auto Database = MicroServiceConfigGetString("storage.type.postgresql.database", "");
auto Port = MicroServiceConfigGetString("storage.type.postgresql.port", "");
auto ConnectionTimeout =
MicroServiceConfigGetString("storage.type.postgresql.connectiontimeout", "");
auto ConnectionTimeout = MicroServiceConfigGetString("storage.type.postgresql.connectiontimeout", "");
std::string ConnectionStr = "host=" + Host + " user=" + Username + " password=" + Password +
" dbname=" + Database + " port=" + Port +
std::string ConnectionStr =
"host=" + Host +
" user=" + Username +
" password=" + Password +
" dbname=" + Database +
" port=" + Port +
" connect_timeout=" + ConnectionTimeout;
Poco::Data::PostgreSQL::Connector::registerConnector();
Pool_ = std::make_shared<Poco::Data::SessionPool>(PostgresConn_.name(), ConnectionStr, 8,
NumSessions, IdleTime);
Pool_ = std::make_unique<Poco::Data::SessionPool>(PostgresConn_.name(), ConnectionStr, 8, NumSessions, IdleTime);
return 0;
}
#endif
} // namespace OpenWifi
}

View File

@@ -6,29 +6,36 @@
#include "framework/SubSystemServer.h"
#include "Poco/DateTimeFormat.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/Net/SSLManager.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/DateTimeFormat.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
PropertiesFileServerEntry::PropertiesFileServerEntry(
std::string Address, uint32_t port, std::string Key_file, std::string Cert_file,
std::string RootCa, std::string Issuer, std::string ClientCas, std::string Cas,
std::string Key_file_password, std::string Name, Poco::Net::Context::VerificationMode M,
PropertiesFileServerEntry::PropertiesFileServerEntry(std::string Address, uint32_t port, std::string Key_file,
std::string Cert_file, std::string RootCa, std::string Issuer,
std::string ClientCas, std::string Cas,
std::string Key_file_password, std::string Name,
Poco::Net::Context::VerificationMode M,
int backlog)
: address_(std::move(Address)), port_(port), cert_file_(std::move(Cert_file)),
key_file_(std::move(Key_file)), root_ca_(std::move(RootCa)),
key_file_password_(std::move(Key_file_password)), issuer_cert_file_(std::move(Issuer)),
client_cas_(std::move(ClientCas)), cas_(std::move(Cas)), name_(std::move(Name)),
backlog_(backlog), level_(M){
: address_(std::move(Address)),
port_(port),
cert_file_(std::move(Cert_file)),
key_file_(std::move(Key_file)),
root_ca_(std::move(RootCa)),
key_file_password_(std::move(Key_file_password)),
issuer_cert_file_(std::move(Issuer)),
client_cas_(std::move(ClientCas)),
cas_(std::move(Cas)),
name_(std::move(Name)),
backlog_(backlog),
level_(M) {
};
[[nodiscard]] Poco::Net::SecureServerSocket
PropertiesFileServerEntry::CreateSecureSocket(Poco::Logger &L) const {
[[nodiscard]] Poco::Net::SecureServerSocket PropertiesFileServerEntry::CreateSecureSocket(Poco::Logger &L) const {
Poco::Net::Context::Params P;
P.verificationMode = level_;
@@ -38,12 +45,10 @@ namespace OpenWifi {
P.dhUse2048Bits = true;
P.caLocation = cas_;
auto Context = Poco::AutoPtr<Poco::Net::Context>(
new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
auto Context = Poco::AutoPtr<Poco::Net::Context>(new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
if(!key_file_password_.empty()) {
auto PassphraseHandler = Poco::SharedPtr<MyPrivateKeyPassphraseHandler>(
new MyPrivateKeyPassphraseHandler(key_file_password_, L));
auto PassphraseHandler = Poco::SharedPtr<MyPrivateKeyPassphraseHandler>( new MyPrivateKeyPassphraseHandler(key_file_password_,L));
Poco::Net::SSLManager::instance().initializeServer(PassphraseHandler, nullptr,Context);
}
@@ -106,8 +111,7 @@ namespace OpenWifi {
}
}
[[nodiscard]] Poco::Net::ServerSocket
PropertiesFileServerEntry::CreateSocket([[maybe_unused]] Poco::Logger &L) const {
[[nodiscard]] Poco::Net::ServerSocket PropertiesFileServerEntry::CreateSocket([[maybe_unused]] Poco::Logger &L) const {
Poco::Net::Context::Params P;
if (address_ == "*") {
@@ -123,24 +127,19 @@ namespace OpenWifi {
}
}
void PropertiesFileServerEntry::LogCertInfo(Poco::Logger &L,
const Poco::Crypto::X509Certificate &C) const {
L.information("============================================================================"
"=================");
void PropertiesFileServerEntry::LogCertInfo(Poco::Logger &L, const Poco::Crypto::X509Certificate &C) const {
L.information("=============================================================================================");
L.information(fmt::format("> Issuer: {}", C.issuerName()));
L.information("----------------------------------------------------------------------------"
"-----------------");
L.information("---------------------------------------------------------------------------------------------");
L.information(fmt::format("> Common Name: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_COMMON_NAME)));
L.information(fmt::format("> Country: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_COUNTRY)));
L.information(fmt::format("> Locality: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_LOCALITY_NAME)));
L.information(
fmt::format("> State/Prov: {}",
L.information(fmt::format("> State/Prov: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_STATE_OR_PROVINCE)));
L.information(
fmt::format("> Org name: {}",
L.information(fmt::format("> Org name: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_ORGANIZATION_NAME)));
L.information(
fmt::format("> Org unit: {}",
@@ -150,11 +149,9 @@ namespace OpenWifi {
C.issuerName(Poco::Crypto::X509Certificate::NID_PKCS9_EMAIL_ADDRESS)));
L.information(fmt::format("> Serial#: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_SERIAL_NUMBER)));
L.information("----------------------------------------------------------------------------"
"-----------------");
L.information("---------------------------------------------------------------------------------------------");
L.information(fmt::format("> Subject: {}", C.subjectName()));
L.information("----------------------------------------------------------------------------"
"-----------------");
L.information("---------------------------------------------------------------------------------------------");
L.information(fmt::format("> Common Name: {}",
C.subjectName(Poco::Crypto::X509Certificate::NID_COMMON_NAME)));
L.information(fmt::format("> Country: {}",
@@ -175,66 +172,52 @@ namespace OpenWifi {
C.subjectName(Poco::Crypto::X509Certificate::NID_PKCS9_EMAIL_ADDRESS)));
L.information(fmt::format("> Serial#: {}",
C.subjectName(Poco::Crypto::X509Certificate::NID_SERIAL_NUMBER)));
L.information("----------------------------------------------------------------------------"
"-----------------");
L.information("---------------------------------------------------------------------------------------------");
L.information(fmt::format("> Signature Algo: {}", C.signatureAlgorithm()));
auto From =
Poco::DateTimeFormatter::format(C.validFrom(), Poco::DateTimeFormat::HTTP_FORMAT);
auto From = Poco::DateTimeFormatter::format(C.validFrom(), Poco::DateTimeFormat::HTTP_FORMAT);
L.information(fmt::format("> Valid from: {}", From));
auto Expires =
Poco::DateTimeFormatter::format(C.expiresOn(), Poco::DateTimeFormat::HTTP_FORMAT);
L.information(fmt::format("> Expires on: {}", Expires));
L.information(fmt::format("> Version: {}", (int)C.version()));
L.information(fmt::format("> Serial #: {}", C.serialNumber()));
L.information("============================================================================"
"=================");
L.information("=============================================================================================");
}
void PropertiesFileServerEntry::LogCert(Poco::Logger &L) const {
try {
Poco::Crypto::X509Certificate C(cert_file_);
L.information("========================================================================"
"=====================");
L.information("========================================================================"
"=====================");
L.information("=============================================================================================");
L.information("=============================================================================================");
L.information(fmt::format("Certificate Filename: {}", cert_file_));
LogCertInfo(L, C);
L.information("========================================================================"
"=====================");
L.information("=============================================================================================");
if (!issuer_cert_file_.empty()) {
Poco::Crypto::X509Certificate C1(issuer_cert_file_);
L.information("===================================================================="
"=========================");
L.information("===================================================================="
"=========================");
L.information("=============================================================================================");
L.information("=============================================================================================");
L.information(fmt::format("Issues Certificate Filename: {}", issuer_cert_file_));
LogCertInfo(L, C1);
L.information("===================================================================="
"=========================");
L.information("=============================================================================================");
}
if (!client_cas_.empty()) {
std::vector<Poco::Crypto::X509Certificate> Certs =
Poco::Net::X509Certificate::readPEM(client_cas_);
L.information("===================================================================="
"=========================");
L.information("===================================================================="
"=========================");
L.information("=============================================================================================");
L.information("=============================================================================================");
L.information(fmt::format("Client CAs Filename: {}", client_cas_));
L.information("===================================================================="
"=========================");
L.information("=============================================================================================");
auto i = 1;
for (const auto &C3 : Certs) {
L.information(fmt::format(" Index: {}", i));
L.information("================================================================"
"=============================");
L.information("=============================================================================================");
LogCertInfo(L, C3);
i++;
}
L.information("===================================================================="
"=========================");
L.information("=============================================================================================");
}
} catch (const Poco::Exception &E) {
@@ -247,31 +230,28 @@ namespace OpenWifi {
std::vector<Poco::Crypto::X509Certificate> Certs =
Poco::Net::X509Certificate::readPEM(root_ca_);
L.information("========================================================================"
"=====================");
L.information("========================================================================"
"=====================");
L.information("=============================================================================================");
L.information("=============================================================================================");
L.information(fmt::format("CA Filename: {}", root_ca_));
L.information("========================================================================"
"=====================");
L.information("=============================================================================================");
auto i = 1;
for (const auto &C : Certs) {
L.information(fmt::format(" Index: {}", i));
L.information("===================================================================="
"=========================");
L.information("=============================================================================================");
LogCertInfo(L, C);
i++;
}
L.information("========================================================================"
"=====================");
L.information("=============================================================================================");
} catch (const Poco::Exception &E) {
L.log(E);
}
}
SubSystemServer::SubSystemServer(const std::string &Name, const std::string &LoggingPrefix,
const std::string &SubSystemConfigPrefix)
: Name_(Name), LoggerPrefix_(LoggingPrefix), SubSystemConfigPrefix_(SubSystemConfigPrefix) {
const std::string &SubSystemConfigPrefix):
Name_(Name),
LoggerPrefix_(LoggingPrefix),
SubSystemConfigPrefix_(SubSystemConfigPrefix) {
}
void SubSystemServer::initialize([[maybe_unused]] Poco::Util::Application &self) {
@@ -280,12 +260,9 @@ namespace OpenWifi {
auto NewLevel = MicroServiceConfigGetString("logging.level." + Name_, "");
if(NewLevel.empty())
Logger_ = std::make_unique<LoggerWrapper>(Poco::Logger::create(
LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel()));
Logger_ = std::make_unique<LoggerWrapper>(Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel()));
else
Logger_ = std::make_unique<LoggerWrapper>(
Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(),
Poco::Logger::parseLevel(NewLevel)));
Logger_ = std::make_unique<LoggerWrapper>(Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::parseLevel(NewLevel)));
ConfigServersList_.clear();
while (good) {
@@ -320,11 +297,14 @@ namespace OpenWifi {
} else if (L == "once")
M = Poco::Net::Context::VERIFY_ONCE;
PropertiesFileServerEntry entry(
MicroServiceConfigGetString(address, ""), MicroServiceConfigGetInt(port, 0),
MicroServiceConfigPath(key, ""), MicroServiceConfigPath(cert, ""),
MicroServiceConfigPath(rootca, ""), MicroServiceConfigPath(issuer, ""),
MicroServiceConfigPath(clientcas, ""), MicroServiceConfigPath(cas, ""),
PropertiesFileServerEntry entry(MicroServiceConfigGetString(address, ""),
MicroServiceConfigGetInt(port, 0),
MicroServiceConfigPath(key, ""),
MicroServiceConfigPath(cert, ""),
MicroServiceConfigPath(rootca, ""),
MicroServiceConfigPath(issuer, ""),
MicroServiceConfigPath(clientcas, ""),
MicroServiceConfigPath(cas, ""),
MicroServiceConfigGetString(key_password, ""),
MicroServiceConfigGetString(name, ""), M,
(int)MicroServiceConfigGetInt(backlog, 64));
@@ -334,4 +314,7 @@ namespace OpenWifi {
}
}
} // namespace OpenWifi

View File

@@ -4,27 +4,29 @@
#pragma once
#include <mutex>
#include <string>
#include <mutex>
#include "Poco/Net/Context.h"
#include "Poco/Net/PrivateKeyPassphraseHandler.h"
#include "Poco/Net/SecureServerSocket.h"
#include "Poco/Util/Application.h"
#include "Poco/Net/Context.h"
#include "Poco/Net/SecureServerSocket.h"
#include "Poco/Net/PrivateKeyPassphraseHandler.h"
namespace OpenWifi {
class MyPrivateKeyPassphraseHandler : public Poco::Net::PrivateKeyPassphraseHandler {
public:
explicit MyPrivateKeyPassphraseHandler(const std::string &Password, Poco::Logger &Logger)
: PrivateKeyPassphraseHandler(true), Password_(Password), Logger_(Logger) {}
explicit MyPrivateKeyPassphraseHandler(const std::string &Password, Poco::Logger & Logger):
PrivateKeyPassphraseHandler(true),
Password_(Password),
Logger_(Logger) {
}
void onPrivateKeyRequested([[maybe_unused]] const void * pSender,std::string & privateKey) {
poco_information(Logger_,"Returning key passphrase.");
privateKey = Password_;
};
inline Poco::Logger & Logger() { return Logger_; }
private:
std::string Password_;
Poco::Logger & Logger_;
@@ -78,17 +80,17 @@ namespace OpenWifi {
const std::string & SubSystemConfigPrefix);
void initialize(Poco::Util::Application &self) override;
inline void uninitialize() override {}
inline void uninitialize() override {
}
inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override {
poco_information(Logger_->L_,"Reloading of this subsystem is not supported.");
}
inline void defineOptions([[maybe_unused]] Poco::Util::OptionSet &options) override {}
inline void defineOptions([[maybe_unused]] Poco::Util::OptionSet &options) override {
}
inline const std::string & Name() const { return Name_; };
inline const char * name() const override { return Name_.c_str(); }
inline const PropertiesFileServerEntry &Host(uint64_t index) {
return ConfigServersList_[index];
};
inline const PropertiesFileServerEntry & Host(uint64_t index) { return ConfigServersList_[index]; };
inline uint64_t HostSize() const { return ConfigServersList_.size(); }
inline Poco::Logger & Logger() const { return Logger_->L_; }
inline void SetLoggingLevel(const std::string & levelName) {
@@ -101,7 +103,9 @@ namespace OpenWifi {
struct LoggerWrapper {
Poco::Logger & L_;
LoggerWrapper(Poco::Logger &L) : L_(L) {}
LoggerWrapper(Poco::Logger &L) :
L_(L) {
}
};
protected:

View File

@@ -5,4 +5,7 @@
#include "framework/UI_WebSocketClientNotifications.h"
#include "framework/UI_WebSocketClientServer.h"
namespace OpenWifi {}
namespace OpenWifi {
}

View File

@@ -37,7 +37,9 @@ namespace OpenWifi {
RESTAPI_utils::field_from_json(Obj, "content", content);
return true;
} catch (...) {
}
return false;
}
} // namespace OpenWifi
}

View File

@@ -4,14 +4,14 @@
#include <mutex>
#include "Poco/NObserver.h"
#include "Poco/JSON/JSONException.h"
#include "Poco/JSON/Parser.h"
#include "Poco/Logger.h"
#include "Poco/NObserver.h"
#include "framework/UI_WebSocketClientServer.h"
#include "framework/AuthClient.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/UI_WebSocketClientServer.h"
#include "fmt/format.h"
@@ -19,13 +19,11 @@
#include "AuthService.h"
#endif
#define DBG \
{ std::cout << __LINE__ << std::endl; }
#define DBG { std::cout << __LINE__ << std::endl; }
namespace OpenWifi {
void UI_WebSocketClientServer::NewClient(Poco::Net::WebSocket &WS, const std::string &Id,
const std::string &UserName, std::uint64_t TID) {
void UI_WebSocketClientServer::NewClient(Poco::Net::WebSocket & WS, const std::string &Id, const std::string &UserName, std::uint64_t TID ) {
std::lock_guard G(LocalMutex_);
auto Client = std::make_unique<UI_WebSocketClientInfo>(WS,Id, UserName);
@@ -34,26 +32,28 @@ namespace OpenWifi {
Client->WS_->setNoDelay(true);
Client->WS_->setKeepAlive(true);
Client->WS_->setBlocking(false);
Reactor_.addEventHandler(
*Client->WS_,
Reactor_.addEventHandler(*Client->WS_,
Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ReadableNotification>(
*this, &UI_WebSocketClientServer::OnSocketReadable));
Reactor_.addEventHandler(
*Client->WS_,
Reactor_.addEventHandler(*Client->WS_,
Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ShutdownNotification>(
*this, &UI_WebSocketClientServer::OnSocketShutdown));
Reactor_.addEventHandler(
*Client->WS_, Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ErrorNotification>(
Reactor_.addEventHandler(*Client->WS_,
Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ErrorNotification>(
*this, &UI_WebSocketClientServer::OnSocketError));
Client->SocketRegistered_ = true;
Clients_[ClientSocket] = std::move(Client);
UsersConnected_ = Clients_.size();
}
void UI_WebSocketClientServer::SetProcessor(UI_WebSocketClientProcessor *F) { Processor_ = F; }
void UI_WebSocketClientServer::SetProcessor( UI_WebSocketClientProcessor * F) {
Processor_ = F;
}
UI_WebSocketClientServer::UI_WebSocketClientServer() noexcept
: SubSystemServer("WebSocketClientServer", "UI-WSCLNT-SVR", "websocketclients") {}
UI_WebSocketClientServer::UI_WebSocketClientServer() noexcept:
SubSystemServer("WebSocketClientServer", "UI-WSCLNT-SVR", "websocketclients")
{
}
void UI_WebSocketClientServer::run() {
Running_ = true;
@@ -71,23 +71,21 @@ namespace OpenWifi {
ToBeRemoved_.clear();
UsersConnected_ = Clients_.size();
}
}
void UI_WebSocketClientServer::EndConnection(ClientList::iterator Client) {
if(Client->second->SocketRegistered_) {
Client->second->SocketRegistered_ = false;
Reactor_.removeEventHandler(
*Client->second->WS_,
Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ReadableNotification>(
*this, &UI_WebSocketClientServer::OnSocketReadable));
Reactor_.removeEventHandler(
*Client->second->WS_,
Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ShutdownNotification>(
*this, &UI_WebSocketClientServer::OnSocketShutdown));
Reactor_.removeEventHandler(
*Client->second->WS_,
Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ErrorNotification>(
*this, &UI_WebSocketClientServer::OnSocketError));
Reactor_.removeEventHandler(*Client->second->WS_,
Poco::NObserver<UI_WebSocketClientServer,
Poco::Net::ReadableNotification>(*this,&UI_WebSocketClientServer::OnSocketReadable));
Reactor_.removeEventHandler(*Client->second->WS_,
Poco::NObserver<UI_WebSocketClientServer,
Poco::Net::ShutdownNotification>(*this,&UI_WebSocketClientServer::OnSocketShutdown));
Reactor_.removeEventHandler(*Client->second->WS_,
Poco::NObserver<UI_WebSocketClientServer,
Poco::Net::ErrorNotification>(*this,&UI_WebSocketClientServer::OnSocketError));
}
ToBeRemoved_.push_back(Client);
}
@@ -116,13 +114,11 @@ namespace OpenWifi {
}
};
bool UI_WebSocketClientServer::IsFiltered(std::uint64_t id,
const OpenWifi::UI_WebSocketClientInfo &Client) {
bool UI_WebSocketClientServer::IsFiltered(std::uint64_t id, const OpenWifi::UI_WebSocketClientInfo &Client) {
return std::find(Client.Filter_.begin(), Client.Filter_.end(),id)!=end(Client.Filter_);
}
bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, std::uint64_t id,
const std::string &Payload) {
bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, std::uint64_t id, const std::string &Payload) {
std::lock_guard G(LocalMutex_);
for(const auto &Client:Clients_) {
@@ -150,20 +146,19 @@ namespace OpenWifi {
if(!IsFiltered(id,*Client.second) && Client.second->Authenticated_)
Client.second->WS_->sendFrame(Payload.c_str(),(int)Payload.size());
} catch (...) {
}
}
}
UI_WebSocketClientServer::ClientList::iterator UI_WebSocketClientServer::FindWSClient(
[[maybe_unused]] std::lock_guard<std::recursive_mutex> &G, int ClientSocket) {
UI_WebSocketClientServer::ClientList::iterator UI_WebSocketClientServer::FindWSClient( [[maybe_unused]] std::lock_guard<std::recursive_mutex> &G, int ClientSocket) {
return Clients_.find(ClientSocket);
}
void UI_WebSocketClientServer::SortNotifications() {
struct {
bool operator()(const NotificationEntry &A, const NotificationEntry & B) const {
return A.id < B.id;
};
return A.id < B.id; };
} CompareNotifications;
std::sort(NotificationTypes_.begin(), NotificationTypes_.end(), CompareNotifications);
@@ -178,15 +173,12 @@ namespace OpenWifi {
NotificationTypesJSON_.set("notificationTypes", AllNotifications);
}
void UI_WebSocketClientServer::RegisterNotifications(
const OpenWifi::UI_WebSocketClientServer::NotificationTypeIdVec &Notifications) {
std::copy(Notifications.begin(), Notifications.end(),
std::back_inserter(NotificationTypes_));
void UI_WebSocketClientServer::RegisterNotifications(const OpenWifi::UI_WebSocketClientServer::NotificationTypeIdVec &Notifications) {
std::copy(Notifications.begin(), Notifications.end(), std::back_inserter(NotificationTypes_));
SortNotifications();
}
void UI_WebSocketClientServer::OnSocketError(
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
void UI_WebSocketClientServer::OnSocketError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
std::lock_guard G(LocalMutex_);
auto Client = Clients_.find(pNf->socket().impl()->sockfd());
if(Client==end(Clients_))
@@ -194,8 +186,7 @@ namespace OpenWifi {
EndConnection(Client);
}
void UI_WebSocketClientServer::OnSocketReadable(
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
void UI_WebSocketClientServer::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
UI_WebSocketClientServer::ClientList::iterator Client;
std::lock_guard G(LocalMutex_);
@@ -213,9 +204,7 @@ namespace OpenWifi {
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
if (n == 0) {
poco_debug(Logger(),
fmt::format("CLOSE({}): {} UI Client is closing WS connection.",
Client->second->Id_, Client->second->UserName_));
poco_debug(Logger(),fmt::format("CLOSE({}): {} UI Client is closing WS connection.", Client->second->Id_, Client->second->UserName_));
return EndConnection(Client);
}
@@ -228,9 +217,7 @@ namespace OpenWifi {
case Poco::Net::WebSocket::FRAME_OP_PONG: {
} break;
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
poco_debug(Logger(),
fmt::format("CLOSE({}): {} UI Client is closing WS connection.",
Client->second->Id_, Client->second->UserName_));
poco_debug(Logger(),fmt::format("CLOSE({}): {} UI Client is closing WS connection.", Client->second->Id_, Client->second->UserName_));
return EndConnection(Client);
} break;
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
@@ -245,17 +232,13 @@ namespace OpenWifi {
#endif
if (Tokens.size() == 2 &&
#if defined(TIP_SECURITY_SERVICE)
AuthService()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_,
Expired)) {
AuthService()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_, Expired)) {
#else
AuthClient()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_,
Expired, Contacted)) {
AuthClient()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_, Expired, Contacted)) {
#endif
Client->second->Authenticated_ = true;
Client->second->UserName_ = Client->second->UserInfo_.userinfo.email;
poco_debug(Logger(),
fmt::format("START({}): {} UI Client is starting WS connection.",
Client->second->Id_, Client->second->UserName_));
poco_debug(Logger(),fmt::format("START({}): {} UI Client is starting WS connection.", Client->second->Id_, Client->second->UserName_));
auto WelcomeMessage = NotificationTypesJSON_;
WelcomeMessage.set("success", "Welcome! Bienvenue! Bienvenidos!");
std::ostringstream OS;
@@ -272,7 +255,8 @@ namespace OpenWifi {
}
} else {
Poco::JSON::Parser P;
auto Obj = P.parse(IncomingFrame.begin()).extract<Poco::JSON::Object::Ptr>();
auto Obj =
P.parse(IncomingFrame.begin()).extract<Poco::JSON::Object::Ptr>();
if(Obj->has(DropMessagesCommand) && Obj->isArray(DropMessagesCommand)) {
auto Filters = Obj->getArray(DropMessagesCommand);
@@ -287,8 +271,7 @@ namespace OpenWifi {
std::string Answer;
bool CloseConnection=false;
if (Processor_ != nullptr) {
Processor_->Processor(Obj, Answer, CloseConnection,
Client->second->UserInfo_.userinfo);
Processor_->Processor(Obj, Answer, CloseConnection,Client->second->UserInfo_.userinfo);
}
if (!Answer.empty())
Client->second->WS_->sendFrame(Answer.c_str(), (int)Answer.size());
@@ -309,8 +292,7 @@ namespace OpenWifi {
}
}
void UI_WebSocketClientServer::OnSocketShutdown(
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
void UI_WebSocketClientServer::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
try {
std::lock_guard G(LocalMutex_);
auto Client = Clients_.find(pNf->socket().impl()->sockfd());
@@ -318,6 +300,7 @@ namespace OpenWifi {
return;
EndConnection(Client);
} catch (...) {
}
}

View File

@@ -7,11 +7,11 @@
#include <map>
#include <string>
#include "Poco/JSON/Object.h"
#include "Poco/Net/SocketNotification.h"
#include "Poco/Runnable.h"
#include "Poco/Net/SocketReactor.h"
#include "Poco/Net/WebSocket.h"
#include "Poco/Runnable.h"
#include "Poco/JSON/Object.h"
#include "Poco/Net/SocketNotification.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#include "framework/SubSystemServer.h"
@@ -21,9 +21,7 @@ namespace OpenWifi {
class UI_WebSocketClientProcessor {
public:
virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done,
const SecurityObjects::UserInfo &UserInfo) = 0;
virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done , const SecurityObjects::UserInfo & UserInfo) = 0;
private:
};
@@ -36,8 +34,7 @@ namespace OpenWifi {
std::vector<std::uint64_t> Filter_;
SecurityObjects::UserInfoAndPolicy UserInfo_;
UI_WebSocketClientInfo(Poco::Net::WebSocket &WS, const std::string &Id,
const std::string &username) {
UI_WebSocketClientInfo(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &username) {
WS_ = std::make_unique<Poco::Net::WebSocket>(WS);
Id_ = Id;
UserName_ = username;
@@ -52,21 +49,21 @@ namespace OpenWifi {
return instance_;
}
bool IsAnyoneConnected() { return UsersConnected_; }
bool IsAnyoneConnected() {
return UsersConnected_;
}
int Start() override;
void Stop() override;
void run() override;
Poco::Net::SocketReactor & Reactor() { return Reactor_; }
void NewClient(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &UserName,
std::uint64_t TID);
void NewClient(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &UserName, std::uint64_t TID);
void SetProcessor(UI_WebSocketClientProcessor *F);
[[nodiscard]] inline bool GeoCodeEnabled() const { return GeoCodeEnabled_; }
[[nodiscard]] inline std::string GoogleApiKey() const { return GoogleApiKey_; }
template <typename T>
bool SendUserNotification(const std::string &userName,
const WebSocketNotification<T> &Notification) {
template <typename T> bool
SendUserNotification(const std::string &userName, const WebSocketNotification<T> &Notification) {
Poco::JSON::Object Payload;
Notification.to_json(Payload);
@@ -88,8 +85,7 @@ namespace OpenWifi {
SendToAll(Notification.type_id, OO.str());
}
[[nodiscard]] bool SendToUser(const std::string &userName, std::uint64_t id,
const std::string &Payload);
[[nodiscard]] bool SendToUser(const std::string &userName, std::uint64_t id, const std::string &Payload);
void SendToAll(std::uint64_t id, const std::string &Payload);
struct NotificationEntry {
@@ -126,12 +122,12 @@ namespace OpenWifi {
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf);
void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf);
ClientList::iterator FindWSClient(std::lock_guard<std::recursive_mutex> &G,
int ClientSocket);
ClientList::iterator FindWSClient( std::lock_guard<std::recursive_mutex> &G, int ClientSocket);
void SortNotifications();
};
inline auto UI_WebSocketClientServer() { return UI_WebSocketClientServer::instance(); }
}; // namespace OpenWifi
};

View File

@@ -5,46 +5,43 @@
#pragma once
#include "framework/SubSystemServer.h"
#include "framework/UI_WebSocketClientNotifications.h"
#include "framework/UI_WebSocketClientServer.h"
#include "framework/UI_WebSocketClientNotifications.h"
namespace OpenWifi {
class WebSocketLogger : public Poco::Channel {
public:
WebSocketLogger() {}
~WebSocketLogger() {}
WebSocketLogger() {
}
~WebSocketLogger() {
}
std::string getProperty( [[maybe_unused]] const std::string &p ) const {
std::cout << "WS getProperty" << std::endl;
return "";
}
void close() final {}
void close() final {
}
void open() final {}
void open() final {
}
static std::string to_string(Poco::Message::Priority p) {
switch(p) {
case Poco::Message::PRIO_INFORMATION:
return "information";
case Poco::Message::PRIO_CRITICAL:
return "critical";
case Poco::Message::PRIO_DEBUG:
return "debug";
case Poco::Message::PRIO_ERROR:
return "error";
case Poco::Message::PRIO_FATAL:
return "fatal";
case Poco::Message::PRIO_NOTICE:
return "notice";
case Poco::Message::PRIO_TRACE:
return "trace";
case Poco::Message::PRIO_WARNING:
return "warning";
default:
return "none";
case Poco::Message::PRIO_INFORMATION: return "information";
case Poco::Message::PRIO_CRITICAL: return "critical";
case Poco::Message::PRIO_DEBUG: return "debug";
case Poco::Message::PRIO_ERROR: return "error";
case Poco::Message::PRIO_FATAL: return "fatal";
case Poco::Message::PRIO_NOTICE: return "notice";
case Poco::Message::PRIO_TRACE: return "trace";
case Poco::Message::PRIO_WARNING: return "warning";
default: return "none";
}
}
@@ -75,13 +72,13 @@ namespace OpenWifi {
RESTAPI_utils::field_from_json(Obj, "thread_id", thread_id);
return true;
} catch(...) {
}
return false;
}
};
typedef WebSocketNotification<NotificationLogMessage>
WebSocketClientNotificationLogMessage_t;
typedef WebSocketNotification<NotificationLogMessage> WebSocketClientNotificationLogMessage_t;
void log(const Poco::Message &m) final {
if(UI_WebSocketClientServer()->IsAnyoneConnected()) {
@@ -97,8 +94,7 @@ namespace OpenWifi {
}
}
void setProperty([[maybe_unused]] const std::string &name,
[[maybe_unused]] const std::string &value) {
void setProperty([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) {
std::cout << "WS setProperty" << std::endl;
}
@@ -108,4 +104,4 @@ namespace OpenWifi {
// inline auto WebSocketLogger() { return WebSocketLogger::instance(); }
} // namespace OpenWifi
}

View File

@@ -1,63 +0,0 @@
//
// Created by stephane bourque on 2023-04-19.
//
#pragma once
#include <vector>
#include <string>
namespace OpenWifi {
inline const std::vector<std::pair<std::string, std::string>> DefaultDeviceTypeList{
{"actiontec_web7200", "AP"},
{"cig_wf186w", "AP"},
{"cig_wf188n", "AP"},
{"cig_wf194c4", "AP"},
{"cig_wf196", "AP"},
{"cig_wf196-ca", "AP"},
{"cig_wf196-ca-ath12", "AP"},
{"cig_wf196-us", "AP"},
{"cig_wf610d", "AP"},
{"cig_wf660a", "AP"},
{"cig_wf808", "AP"},
{"cybertan_eww622-a1", "AP"},
{"edgecore_eap101", "AP"},
{"edgecore_eap101-ath12", "AP"},
{"edgecore_eap102", "AP"},
{"edgecore_eap104", "AP"},
{"edgecore_eap104-ath12", "AP"},
{"edgecore_ecs4100-12ph", "AP"},
{"edgecore_ecw5211", "AP"},
{"edgecore_ecw5410", "AP"},
{"edgecore_oap100", "AP"},
{"edgecore_spw2ac1200", "SWITCH"},
{"edgecore_spw2ac1200-lan-poe", "SWITCH"},
{"edgecore_ssw2ac2600", "SWITCH"},
{"hfcl_ion4", "AP"},
{"hfcl_ion4x", "AP"},
{"hfcl_ion4x_2", "AP"},
{"hfcl_ion4xe", "AP"},
{"hfcl_ion4xi", "AP"},
{"indio_um-305ac", "AP"},
{"indio_um-305ax", "AP"},
{"indio_um-310ax-v1", "AP"},
{"indio_um-325ac", "AP"},
{"indio_um-510ac-v3", "AP"},
{"indio_um-510axm-v1", "AP"},
{"indio_um-510axp-v1", "AP"},
{"indio_um-550ac", "AP"},
{"linksys_e8450-ubi", "AP"},
{"linksys_ea6350-v4", "AP"},
{"linksys_ea8300", "AP"},
{"liteon_wpx8324", "AP"},
{"meshpp_s618_cp01", "AP"},
{"meshpp_s618_cp03", "AP"},
{"udaya_a5-id2", "AP"},
{"wallys_dr40x9", "AP"},
{"wallys_dr6018", "AP"},
{"wallys_dr6018_v4", "AP"},
{"x64_vm", "AP"},
{"yuncore_ax840", "AP"},
{"yuncore_fap640", "AP"},
{"yuncore_fap650", "AP"}};
}

View File

@@ -8,30 +8,41 @@
#pragma once
#include <array>
#include <fstream>
#include <iostream>
#include <map>
#include <memory>
#include <string>
#include <memory>
#include <iostream>
#include <fstream>
#include <map>
#include <vector>
#include <array>
#include "Poco/Data/RecordSet.h"
#include "Poco/Data/SQLite/Connector.h"
#include "Poco/Tuple.h"
#include "Poco/Data/SessionPool.h"
#include "Poco/Data/Statement.h"
#include "Poco/Data/RecordSet.h"
#include "Poco/Data/SQLite/Connector.h"
#include "Poco/Logger.h"
#include "Poco/StringTokenizer.h"
#include "Poco/Tuple.h"
#include "StorageClass.h"
#include "fmt/format.h"
namespace ORM {
enum FieldType { FT_INT, FT_BIGINT, FT_TEXT, FT_VARCHAR, FT_BLOB, FT_BOOLEAN, FT_REAL };
enum FieldType {
FT_INT,
FT_BIGINT,
FT_TEXT,
FT_VARCHAR,
FT_BLOB,
FT_BOOLEAN,
FT_REAL
};
enum Indextype { ASC, DESC };
enum Indextype {
ASC,
DESC
};
struct Field {
std::string Name;
@@ -39,19 +50,31 @@ namespace ORM {
int Size=0;
bool Index=false;
Field(std::string N, FieldType T, int S = 0, bool Index = false)
: Name(std::move(N)), Type(T), Size(S), Index(Index) {}
explicit Field(std::string N) : Name(std::move(N)) { Type = FT_TEXT; }
Field(std::string N, FieldType T, int S=0, bool Index=false) :
Name(std::move(N)),
Type(T),
Size(S),
Index(Index) {}
Field(std::string N, int S) : Name(std::move(N)), Size(S) {
explicit Field(std::string N) :
Name(std::move(N))
{
Type = FT_TEXT;
}
Field(std::string N, int S) :
Name(std::move(N)), Size(S)
{
if(Size>0 && Size<255)
Type = FT_VARCHAR;
else
Type = FT_TEXT;
}
Field(std::string N, int S, bool I) : Name(std::move(N)), Size(S), Index(I) {
Field(std::string N, int S, bool I):
Name(std::move(N)), Size(S), Index(I)
{
if(Size>0 && Size<255)
Type = FT_VARCHAR;
else
@@ -74,14 +97,10 @@ namespace ORM {
inline std::string FieldTypeToChar(OpenWifi::DBType Type, FieldType T, int Size=0) {
switch(T) {
case FT_INT:
return "INT";
case FT_BIGINT:
return "BIGINT";
case FT_TEXT:
return "TEXT";
case FT_BOOLEAN:
return "BOOLEAN";
case FT_INT: return "INT";
case FT_BIGINT: return "BIGINT";
case FT_TEXT: return "TEXT";
case FT_BOOLEAN: return "BOOLEAN";
case FT_VARCHAR:
if(Size)
return std::string("VARCHAR(") + std::to_string(Size) + std::string(")");
@@ -98,6 +117,7 @@ namespace ORM {
return "REAL";
default:
assert(false);
}
assert(false);
return "";
@@ -115,12 +135,13 @@ namespace ORM {
return R;
}
inline std::string WHERE_AND_(std::string Result) { return Result; }
inline std::string WHERE_AND_(std::string Result) {
return Result;
}
template <typename T, typename... Args>
std::string WHERE_AND_(std::string Result, const char *fieldName, const T &Value,
Args... args) {
if constexpr (std::is_same_v<T, std::string>) {
template <typename T, typename... Args> std::string WHERE_AND_(std::string Result, const char *fieldName, const T & Value, Args... args) {
if constexpr(std::is_same_v<T,std::string>)
{
if(!Value.empty()) {
if(!Result.empty())
Result += " and ";
@@ -173,13 +194,21 @@ namespace ORM {
static const std::vector<std::string> BOPS{" and ", " or "};
static const std::vector<std::string> SQLCOMPS{"=","!=","<","<=",">",">="};
inline std::string to_string(uint64_t V) { return std::to_string(V); }
inline std::string to_string(uint64_t V) {
return std::to_string(V);
}
inline std::string to_string(int V) { return std::to_string(V); }
inline std::string to_string(int V) {
return std::to_string(V);
}
inline std::string to_string(bool V) { return std::to_string(V); }
inline std::string to_string(bool V) {
return std::to_string(V);
}
inline std::string to_string(const std::string &S) { return S; }
inline std::string to_string(const std::string &S) {
return S;
}
inline std::string to_string(const Poco::Data::BLOB &blob) {
std::string result;
@@ -187,17 +216,22 @@ namespace ORM {
return result;
}
inline std::string to_string(const char *S) { return S; }
inline std::string to_string(const char * S) {
return S;
}
template <typename RecordType> class DBCache {
public:
DBCache(unsigned Size, unsigned Timeout) : Size_(Size), Timeout_(Timeout) {}
DBCache(unsigned Size, unsigned Timeout) :
Size_(Size),
Timeout_(Timeout)
{
}
virtual void Create(const RecordType &R)=0;
virtual bool GetFromCache(const std::string &FieldName, const std::string &Value,
RecordType &R) = 0;
virtual bool GetFromCache(const std::string &FieldName, const std::string &Value, RecordType &R)=0;
virtual void UpdateCache(const RecordType &R)=0;
virtual void Delete(const std::string &FieldName, const std::string &Value)=0;
private:
size_t Size_=0;
uint64_t Timeout_=0;
@@ -205,13 +239,24 @@ namespace ORM {
template <typename RecordTuple, typename RecordType> class DB {
public:
typedef const char * field_name_t;
DB(OpenWifi::DBType dbtype, const char *TableName, const FieldVec &Fields,
const IndexVec &Indexes, Poco::Data::SessionPool &Pool, Poco::Logger &L,
const char *Prefix, DBCache<RecordType> *Cache = nullptr)
: TableName_(TableName), Type_(dbtype), Pool_(Pool), Logger_(L), Prefix_(Prefix),
Cache_(Cache) {
DB( OpenWifi::DBType dbtype,
const char *TableName,
const FieldVec & Fields,
const IndexVec & Indexes,
Poco::Data::SessionPool & Pool,
Poco::Logger &L,
const char *Prefix,
DBCache<RecordType> * Cache=nullptr):
TableName_(TableName),
Type_(dbtype),
Pool_(Pool),
Logger_(L),
Prefix_(Prefix),
Cache_(Cache)
{
assert(RecordTuple::length == Fields.size());
bool first = true;
@@ -229,8 +274,7 @@ namespace ORM {
SelectList_ += "(";
}
CreateFields_ += FieldName + " " + FieldTypeToChar(Type_, i.Type, i.Size) +
(i.Index ? " unique primary key" : "");
CreateFields_ += FieldName + " " + FieldTypeToChar(Type_, i.Type,i.Size) + (i.Index ? " unique primary key" : "");
SelectFields_ += FieldName ;
UpdateFields_ += FieldName + "=?";
SelectList_ += "?";
@@ -244,8 +288,7 @@ namespace ORM {
for(const auto &j:Indexes) {
std::string IndexLine;
IndexLine = std::string("CREATE INDEX IF NOT EXISTS ") + j.Name +
std::string(" ON ") + TableName_ + " (";
IndexLine = std::string("CREATE INDEX IF NOT EXISTS ") + j.Name + std::string(" ON ") + TableName_+ " (";
bool first_entry=true;
for(const auto &k:j.Entries) {
auto IndexFieldName = Poco::toLower(k.FieldName);
@@ -254,8 +297,7 @@ namespace ORM {
IndexLine += " , ";
}
first_entry = false;
IndexLine += IndexFieldName + std::string(" ") +
std::string(k.Type == Indextype::ASC ? "ASC" : "DESC");
IndexLine += IndexFieldName + std::string(" ") + std::string(k.Type == Indextype::ASC ? "ASC" : "DESC") ;
}
IndexLine += " )";
IndexCreation_.template emplace_back(IndexLine);
@@ -276,8 +318,7 @@ namespace ORM {
IndexLine += " ,";
}
first_entry = false;
IndexLine += IndexFieldName +
std::string(k.Type == Indextype::ASC ? " ASC" : " DESC");
IndexLine += IndexFieldName + std::string(k.Type == Indextype::ASC ? " ASC" : " DESC");
}
IndexLine += " ) ";
}
@@ -320,20 +361,15 @@ namespace ORM {
return std::string("(")+P1 + BOPS[BOP] + P2 +")";
}
std::string OP([[maybe_unused]] bool Paran, const std::string &P1, SqlBinaryOp BOP,
const std::string &P2) {
std::string OP( [[maybe_unused]] bool Paran, const std::string &P1, SqlBinaryOp BOP , const std::string &P2) {
return P1 + BOPS[BOP] + P2 +")";
}
template <typename... Others>
std::string OP(bool ParanOpen, const std::string &P1, SqlBinaryOp BOP,
const std::string &P2, Others... More) {
template <typename... Others> std::string OP( bool ParanOpen, const std::string &P1, SqlBinaryOp BOP , const std::string &P2, Others... More) {
return P1 + BOPS[BOP] + OP(ParanOpen, P2, More...) + ")";
}
template <typename... Others>
std::string OP(const std::string &P1, SqlBinaryOp BOP, const std::string &P2,
Others... More) {
template <typename... Others> std::string OP( const std::string &P1, SqlBinaryOp BOP , const std::string &P2, Others... More) {
return std::string{"("} + P1 + BOPS[BOP] + OP(true, P2, More...);
}
@@ -347,24 +383,20 @@ namespace ORM {
case OpenWifi::DBType::mysql: {
try {
Poco::Data::Session Session = Pool_.get();
std::string Statement = IndexCreation_.empty()
? "create table if not exists " + TableName_ +
" ( " + CreateFields_ + " )"
: "create table if not exists " + TableName_ +
" ( " + CreateFields_ + " ), " +
IndexCreation_[0] + " )";
std::string Statement = IndexCreation_.empty() ? "create table if not exists " + TableName_ +" ( " + CreateFields_ + " )" :
"create table if not exists " + TableName_ +" ( " + CreateFields_ + " ), " + IndexCreation_[0] + " )";
Session << Statement , Poco::Data::Keywords::now;
} catch (const Poco::Exception &E) {
Logger_.error("Failure to create MySQL DB resources.");
Logger_.log(E);
}
} break;
}
break;
case OpenWifi::DBType::sqlite: {
try {
Poco::Data::Session Session = Pool_.get();
std::string Statement =
"create table if not exists " + TableName_ + " ( " + CreateFields_ + " )";
std::string Statement = "create table if not exists " + TableName_ + " ( " + CreateFields_ + " )";
Session << Statement , Poco::Data::Keywords::now;
for(const auto &i:IndexCreation_) {
Session << i , Poco::Data::Keywords::now;
@@ -373,13 +405,13 @@ namespace ORM {
Logger_.error("Failure to create SQLITE DB resources.");
Logger_.log(E);
}
} break;
}
break;
case OpenWifi::DBType::pgsql: {
try {
Poco::Data::Session Session = Pool_.get();
std::string Statement =
"create table if not exists " + TableName_ + " ( " + CreateFields_ + " )";
std::string Statement = "create table if not exists " + TableName_ + " ( " + CreateFields_ + " )";
Session << Statement , Poco::Data::Keywords::now;
for(const auto &i:IndexCreation_) {
Session << i , Poco::Data::Keywords::now;
@@ -388,7 +420,8 @@ namespace ORM {
Logger_.error("Failure to create POSTGRESQL DB resources.");
Logger_.log(E);
}
} break;
}
break;
}
return Upgrade();
}
@@ -400,7 +433,8 @@ namespace ORM {
std::string R;
R.reserve(S.size()*2+1);
auto Idx=1;
for (auto const &i : S) {
for(auto const & i:S)
{
if(i=='?') {
R += '$';
R.append(std::to_string(Idx++));
@@ -424,9 +458,9 @@ namespace ORM {
RecordTuple RT;
Convert(R, RT);
std::string St = "insert into " + TableName_ + " ( " + SelectFields_ +
" ) values " + SelectList_;
Insert << ConvertParams(St), Poco::Data::Keywords::use(RT);
std::string St = "insert into " + TableName_ + " ( " + SelectFields_ + " ) values " + SelectList_;
Insert << ConvertParams(St) ,
Poco::Data::Keywords::use(RT);
Insert.execute();
if(Cache_)
@@ -439,8 +473,7 @@ namespace ORM {
return false;
}
template <typename T>
bool GetRecord(field_name_t FieldName, const T &Value, RecordType &R) {
template<typename T> bool GetRecord(field_name_t FieldName, const T & Value, RecordType & R) {
try {
assert(ValidFieldName(FieldName));
@@ -453,12 +486,12 @@ namespace ORM {
Poco::Data::Statement Select(Session);
RecordTuple RT;
std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " +
FieldName + "=?" + " limit 1";
std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + FieldName + "=?" + " limit 1";
auto tValue{Value};
Select << ConvertParams(St), Poco::Data::Keywords::into(RT),
Select << ConvertParams(St) ,
Poco::Data::Keywords::into(RT),
Poco::Data::Keywords::use(tValue);
Select.execute();
@@ -480,10 +513,10 @@ namespace ORM {
Poco::Data::Statement Select(Session);
RecordTuple RT;
std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " +
WhereClause + " limit 1";
std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + WhereClause + " limit 1";
Select << ConvertParams(St), Poco::Data::Keywords::into(RT);
Select << ConvertParams(St) ,
Poco::Data::Keywords::into(RT);
Select.execute();
if(Select.execute()==1) {
@@ -500,8 +533,8 @@ namespace ORM {
typedef std::vector<std::string> StringVec;
template <typename T, typename T0, typename T1>
bool GR(field_name_t FieldName, T &R, T0 &V0, T1 &V1) {
template < typename T,
typename T0, typename T1> bool GR(field_name_t FieldName, T & R,T0 &V0, T1 &V1) {
try {
assert( ValidFieldName(FieldName) );
@@ -510,10 +543,12 @@ namespace ORM {
Poco::Data::Statement Select(Session);
RecordTuple RT;
std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " +
FieldName[0] + "=? and " + FieldName[1] + "=?";
Select << ConvertParams(St), Poco::Data::Keywords::into(RT),
Poco::Data::Keywords::use(V0), Poco::Data::Keywords::use(V1);
std::string St = "select " + SelectFields_ + " from " + TableName_
+ " where " + FieldName[0] + "=? and " + FieldName[1] + "=?" ;
Select << ConvertParams(St) ,
Poco::Data::Keywords::into(RT),
Poco::Data::Keywords::use(V0),
Poco::Data::Keywords::use(V1);
if(Select.execute()==1) {
Convert(RT,R);
@@ -531,7 +566,8 @@ namespace ORM {
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session);
Select << statement, Poco::Data::Keywords::into(records);
Select << statement ,
Poco::Data::Keywords::into(records);
Select.execute();
return true;
} catch (const Poco::Exception &E) {
@@ -544,8 +580,7 @@ namespace ORM {
typedef std::vector<RecordType> RecordVec;
typedef RecordType RecordName;
bool GetRecords(uint64_t Offset, uint64_t HowMany, RecordVec &Records,
const std::string &Where = "", const std::string &OrderBy = "") {
bool GetRecords( uint64_t Offset, uint64_t HowMany, RecordVec & Records, const std::string & Where = "", const std::string & OrderBy = "") {
try {
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session);
@@ -554,7 +589,8 @@ namespace ORM {
(Where.empty() ? "" : " where " + Where) + OrderBy +
ComputeRange(Offset, HowMany) ;
Select << St, Poco::Data::Keywords::into(RL);
Select << St ,
Poco::Data::Keywords::into(RL);
Select.execute();
if(Select.rowsExtracted()>0) {
@@ -572,8 +608,7 @@ namespace ORM {
return false;
}
template <typename T>
bool UpdateRecord(field_name_t FieldName, const T &Value, const RecordType &R) {
template <typename T> bool UpdateRecord(field_name_t FieldName, const T & Value, const RecordType & R) {
try {
assert( ValidFieldName(FieldName) );
@@ -586,9 +621,9 @@ namespace ORM {
auto tValue(Value);
std::string St =
"update " + TableName_ + " set " + UpdateFields_ + " where " + FieldName + "=?";
Update << ConvertParams(St), Poco::Data::Keywords::use(RT),
std::string St = "update " + TableName_ + " set " + UpdateFields_ + " where " + FieldName + "=?" ;
Update << ConvertParams(St) ,
Poco::Data::Keywords::use(RT),
Poco::Data::Keywords::use(tValue);
Update.execute();
if(Cache_)
@@ -615,8 +650,7 @@ namespace ORM {
return false;
}
template <typename T>
bool ReplaceRecord(field_name_t FieldName, const T &Value, RecordType &R) {
template <typename T> bool ReplaceRecord(field_name_t FieldName, const T & Value, RecordType & R) {
try {
if(Exists(FieldName, Value)) {
return UpdateRecord(FieldName,Value,R);
@@ -628,20 +662,18 @@ namespace ORM {
return false;
}
template <typename T>
bool GetNameAndDescription(field_name_t FieldName, const T &Value, std::string &Name,
std::string &Description) {
template <typename T> bool GetNameAndDescription(field_name_t FieldName, const T & Value, std::string & Name, std::string & Description ) {
try {
assert( ValidFieldName(FieldName) );
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session);
RecordTuple RT;
std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " +
FieldName + "=?";
std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + FieldName + "=?" ;
RecordType R;
auto tValue{Value};
Select << ConvertParams(St), Poco::Data::Keywords::into(RT),
Select << ConvertParams(St) ,
Poco::Data::Keywords::into(RT),
Poco::Data::Keywords::use(tValue);
if(Select.execute()==1) {
@@ -667,7 +699,8 @@ namespace ORM {
std::string St = "delete from " + TableName_ + " where " + FieldName + "=?" ;
auto tValue{Value};
Delete << ConvertParams(St), Poco::Data::Keywords::use(tValue);
Delete << ConvertParams(St) ,
Poco::Data::Keywords::use(tValue);
Delete.execute();
if(Cache_)
Cache_->Delete(FieldName, Value);
@@ -708,8 +741,7 @@ namespace ORM {
return false;
}
bool Iterate(std::function<bool(const RecordType &R)> F,
const std::string &WhereClause = "") {
bool Iterate( std::function<bool(const RecordType &R)> F, const std::string & WhereClause = "" ) {
try {
uint64_t Offset=0;
@@ -770,10 +802,10 @@ namespace ORM {
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session);
std::string st{"SELECT COUNT(*) FROM " + TableName_ + " " +
(Where.empty() ? "" : (" where " + Where))};
std::string st{"SELECT COUNT(*) FROM " + TableName_ + " " + (Where.empty() ? "" : (" where " + Where)) };
Select << st, Poco::Data::Keywords::into(Cnt);
Select << st ,
Poco::Data::Keywords::into(Cnt);
Select.execute();
return Cnt;
@@ -784,9 +816,7 @@ namespace ORM {
return 0;
}
template <typename X>
bool ManipulateVectorMember(X T, field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID, bool Add) {
template <typename X> bool ManipulateVectorMember( X T, field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID, bool Add) {
try {
assert( ValidFieldName(FieldName) );
@@ -823,9 +853,7 @@ namespace ORM {
Command << i, Poco::Data::Keywords::now;
} catch (const Poco::Exception &E) {
// Logger_.log(E);
// Logger_.error(Poco::format("The following statement '%s' generated an
// exception during a table upgrade. This may or may not be a problem.",
// i));
// Logger_.error(Poco::format("The following statement '%s' generated an exception during a table upgrade. This may or may not be a problem.", i));
if(!IgnoreExceptions) {
return false;
}
@@ -839,137 +867,98 @@ namespace ORM {
return false;
}
virtual uint32_t Version() { return 0; }
virtual uint32_t Version() {
return 0;
}
virtual bool Upgrade(uint32_t from, uint32_t &to) {
to = from;
return true;
}
inline bool AddChild(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID,
true);
inline bool AddChild(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID, true);
}
inline bool DeleteChild(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID,
false);
inline bool DeleteChild(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID, false);
}
inline bool AddLocation(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID,
true);
inline bool AddLocation(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID, true);
}
inline bool DeleteLocation(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID,
false);
inline bool DeleteLocation(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID, false);
}
inline bool AddContact(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID,
true);
inline bool AddContact(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID, true);
}
inline bool DeleteContact(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID,
false);
inline bool DeleteContact(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID, false);
}
inline bool AddVenue(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID,
true);
inline bool AddVenue(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID, true);
}
inline bool DeleteVenue(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID,
false);
inline bool DeleteVenue(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID, false);
}
inline bool AddDevice(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID,
true);
inline bool AddDevice(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID, true);
}
inline bool DeleteDevice(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID,
false);
inline bool DeleteDevice(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID, false);
}
inline bool AddEntity(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID,
true);
inline bool AddEntity(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID, true);
}
inline bool DeleteEntity(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID,
false);
inline bool DeleteEntity(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID, false);
}
inline bool AddUser(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID,
true);
inline bool AddUser(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, true);
}
inline bool DelUser(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID,
false);
inline bool DelUser(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, false);
}
inline bool AddConfiguration(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::deviceConfiguration, FieldName, ParentUUID,
ChildUUID, true);
inline bool AddConfiguration(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::deviceConfiguration, FieldName, ParentUUID, ChildUUID, true);
}
inline bool DelConfiguration(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::deviceConfiguration, FieldName, ParentUUID,
ChildUUID, false);
inline bool DelConfiguration(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::deviceConfiguration, FieldName, ParentUUID, ChildUUID, false);
}
inline bool AddVariable(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::variables, FieldName, ParentUUID, ChildUUID,
true);
inline bool AddVariable(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::variables, FieldName, ParentUUID, ChildUUID, true);
}
inline bool DelVariable(field_name_t FieldName, const std::string &ParentUUID,
const std::string &ChildUUID) {
return ManipulateVectorMember(&RecordType::variables, FieldName, ParentUUID, ChildUUID,
false);
inline bool DelVariable(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::variables, FieldName, ParentUUID, ChildUUID, false);
}
inline bool AddInUse(field_name_t FieldName, const std::string &ParentUUID,
const std::string &Prefix, const std::string &ChildUUID) {
inline bool AddInUse(field_name_t FieldName, const std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
std::string FakeUUID{ Prefix + ":" + ChildUUID};
return ManipulateVectorMember(&RecordType::inUse, FieldName, ParentUUID, FakeUUID,
true);
return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, true);
}
inline bool DeleteInUse(field_name_t FieldName, const std::string &ParentUUID,
const std::string &Prefix, const std::string &ChildUUID) {
inline bool DeleteInUse(field_name_t FieldName, const std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
std::string FakeUUID{ Prefix + ":" + ChildUUID};
return ManipulateVectorMember(&RecordType::inUse, FieldName, ParentUUID, FakeUUID,
false);
return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, false);
}
inline bool GetInUse(field_name_t FieldName, const std::string &UUID,
std::vector<std::string> &UUIDs) {
inline bool GetInUse(field_name_t FieldName, const std::string & UUID, std::vector<std::string> & UUIDs ) {
RecordType R;
if(GetRecord(FieldName,UUID,R)) {
UUIDs = R.inUse;
@@ -988,20 +977,16 @@ namespace ORM {
}
[[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
if (From < 1)
From = 0;
if(From<1) From=0;
switch(Type_) {
case OpenWifi::DBType::sqlite:
return " LIMIT " + std::to_string(From) + ", " + std::to_string(HowMany) + " ";
case OpenWifi::DBType::pgsql:
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) +
" ";
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
case OpenWifi::DBType::mysql:
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) +
" ";
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
default:
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) +
" ";
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
}
}
@@ -1025,7 +1010,6 @@ namespace ORM {
Poco::Logger &Logger_;
std::string Prefix_;
DBCache<RecordType> *Cache_= nullptr;
private:
std::string CreateFields_;
std::string SelectFields_;
@@ -1034,4 +1018,5 @@ namespace ORM {
std::vector<std::string> IndexCreation_;
std::map<std::string,int> FieldNames_;
};
} // namespace ORM
}

View File

@@ -4,8 +4,8 @@
#pragma once
#include <cstring>
#include <string>
#include <cstring>
#include "Poco/String.h"
@@ -41,10 +41,7 @@ namespace OpenWifi {
}
namespace OpenWifi::RESTAPI::Errors {
struct msg {
uint64_t err_num;
std::string err_txt;
};
struct msg { uint64_t err_num; std::string err_txt; };
static const struct msg Error404{404,"Resource does not exist."};
static const struct msg SUCCESS{0,"No error."};
@@ -60,9 +57,7 @@ namespace OpenWifi::RESTAPI::Errors {
static const struct msg RATE_LIMIT_EXCEEDED{10,"Rate limit exceeded."};
static const struct msg BAD_MFA_TRANSACTION{11,"Bad MFA transaction."};
static const struct msg MFA_FAILURE{12,"MFA failure."};
static const struct msg SECURITY_SERVICE_UNREACHABLE {
13, "Security service is unreachable, try again later."
};
static const struct msg SECURITY_SERVICE_UNREACHABLE{13,"Security service is unreachable, try again later."};
static const struct msg CANNOT_REFRESH_TOKEN{14,"Cannot refresh token."};
static const struct msg ACCOUNT_SUSPENDED{15,"Account has been suspended."};
@@ -80,9 +75,7 @@ namespace OpenWifi::RESTAPI::Errors {
static const struct msg RecordNotCreated{1011,"Record could not be created."};
static const struct msg RecordNotUpdated{1012,"Record could not be updated."};
static const struct msg UnknownManagementPolicyUUID{1013,"Unknown management policy UUID."};
static const struct msg CannotDeleteRoot {
1014, "Root Entity cannot be removed, only modified."
};
static const struct msg CannotDeleteRoot{1014,"Root Entity cannot be removed, only modified."};
static const struct msg MustCreateRootFirst{1015,"Root entity must be created first."};
static const struct msg ParentUUIDMustExist{1016,"Parent UUID must exist."};
static const struct msg ConfigurationMustExist{1017,"Configuration must exist."};
@@ -102,76 +95,41 @@ namespace OpenWifi::RESTAPI::Errors {
static const struct msg InvalidCommand{1031,"Invalid command."};
static const struct msg NoRecordsDeleted{1032,"No records deleted."};
static const struct msg DeviceNotConnected{1033,"Device is not currently connected."};
static const struct msg CannotCreateWS {
1034, "Telemetry system could not create WS endpoint. Please try again."
};
static const struct msg BothDeviceTypeRevision {
1035, "Both deviceType and revision must be set."
};
static const struct msg CannotCreateWS{1034,"Telemetry system could not create WS endpoint. Please try again."};
static const struct msg BothDeviceTypeRevision{1035,"Both deviceType and revision must be set."};
static const struct msg IdOrSerialEmpty{1036,"SerialNumber and Id must not be empty."};
static const struct msg MissingUserID{1037,"Missing user ID."};
static const struct msg IdMustBe0{1038,"To create a user, you must set the ID to 0"};
static const struct msg InvalidUserRole{1039,"Invalid userRole."};
static const struct msg InvalidEmailAddress{1040,"Invalid email address."};
static const struct msg PasswordRejected {
1041, "Password was rejected. This maybe an old password."
};
static const struct msg PasswordRejected{1041,"Password was rejected. This maybe an old password."};
static const struct msg InvalidIPRanges{1042,"Invalid IP range specifications."};
static const struct msg InvalidLOrderBy{1043,"Invalid orderBy specification."};
static const struct msg NeedMobileNumber {
1044, "You must provide at least one validated phone number."
};
static const struct msg NeedMobileNumber{1044,"You must provide at least one validated phone number."};
static const struct msg BadMFAMethod{1045,"MFA only supports sms or email."};
static const struct msg InvalidCredentials{1046,"Invalid credentials (username/password)."};
static const struct msg InvalidPassword {
1047, "Password does not conform to basic password rules."
};
static const struct msg UserPendingVerification {
1048, "User access denied pending email verification."
};
static const struct msg InvalidPassword{1047,"Password does not conform to basic password rules."};
static const struct msg UserPendingVerification{1048,"User access denied pending email verification."};
static const struct msg PasswordMustBeChanged{1049,"Password must be changed."};
static const struct msg UnrecognizedRequest {
1050, "Ill-formed request. Please consult documentation."
};
static const struct msg MissingAuthenticationInformation {
1051, "Missing authentication information."
};
static const struct msg InsufficientAccessRights {
1052, "Insufficient access rights to complete the operation."
};
static const struct msg UnrecognizedRequest{1050,"Ill-formed request. Please consult documentation."};
static const struct msg MissingAuthenticationInformation{1051,"Missing authentication information."};
static const struct msg InsufficientAccessRights{1052,"Insufficient access rights to complete the operation."};
static const struct msg ExpiredToken{1053,"Token has expired, user must login."};
static const struct msg SubscriberMustExist{1054,"Subscriber must exist."};
static const struct msg AuthenticatorVerificationIncomplete {
1055, "Authenticator validation is not complete."
};
static const struct msg SMSCouldNotBeSentRetry {
1056, "SMS could not be sent to validate device, try later or change the phone number."
};
static const struct msg AuthenticatorVerificationIncomplete{1055,"Authenticator validation is not complete."};
static const struct msg SMSCouldNotBeSentRetry{1056,"SMS could not be sent to validate device, try later or change the phone number."};
static const struct msg SMSCouldNotValidate{1057,"Code and number could not be validated"};
static const struct msg InvalidDeviceClass {
1058, "Invalid device class. Must be: any, venue, entity, or subscriber"
};
static const struct msg SerialNumberAlreadyProvisioned {
1059, "This device has already been provisioned to a subscriber."
};
static const struct msg SerialNumberNotTheProperClass {
1060, "Device is not available to subscribers. It ahs been assigned to another class of "
"devices."
};
static const struct msg InvalidDeviceClass{1058,"Invalid device class. Must be: any, venue, entity, or subscriber"};
static const struct msg SerialNumberAlreadyProvisioned{1059,"This device has already been provisioned to a subscriber."};
static const struct msg SerialNumberNotTheProperClass{1060,"Device is not available to subscribers. It ahs been assigned to another class of devices."};
static const struct msg UserAlreadyExists{1061,"Username already exists."};
static const struct msg NotImplemented{1062,"Function not implemented."};
static const struct msg VariableMustExist{1063,"Specified variable does not exist."};
static const struct msg InvalidEntityType{1064,"Invalid entity type."};
static const struct msg CannotDeleteSubEntity {
1065, "Cannot delete the default subscriber entity."
};
static const struct msg CannotDeleteSubEntity{1065,"Cannot delete the default subscriber entity."};
static const struct msg OperatorIdMustExist{1066,"Missing or bad Operator ID"};
static const struct msg CannotDeleteDefaultOperator {
1067, "Cannot delete the default operator."
};
static const struct msg CannotCreateDefaultOperator {
1068, "Cannot create the default operator."
};
static const struct msg CannotDeleteDefaultOperator{1067,"Cannot delete the default operator."};
static const struct msg CannotCreateDefaultOperator{1068,"Cannot create the default operator."};
static const struct msg InvalidRRM{1069,"Invalid RRM value."};
static const struct msg InvalidIPAddresses{1070,"Invalid IP addresses."};
static const struct msg InvalidBillingCode{1071,"Empty of invalid billing code."};
@@ -184,19 +142,11 @@ namespace OpenWifi::RESTAPI::Errors {
static const struct msg InvalidOperatorId{1078,"Invalid operator ID."};
static const struct msg InvalidServiceClassId{1079,"Invalid service class ID."};
static const struct msg InvalidSubscriberDeviceId{1080,"Invalid subscriber device ID."};
static const struct msg InvalidRegistrationOperatorId {
1081, "Invalid registration operator ID."
};
static const struct msg InvalidRegistrationOperatorName {
1082, "Invalid registration operator name."
};
static const struct msg InvalidRegistrationOperatorId{1081,"Invalid registration operator ID."};
static const struct msg InvalidRegistrationOperatorName{1082,"Invalid registration operator name."};
static const struct msg RegistrationNameDuplicate{1083,"Registration name must be unique."};
static const struct msg SMSMFANotEnabled {
1084, "SMS is not enabled in the security service."
};
static const struct msg EMailMFANotEnabled {
1085, "email is not enabled in the security service."
};
static const struct msg SMSMFANotEnabled{1084,"SMS is not enabled in the security service."};
static const struct msg EMailMFANotEnabled{1085,"email is not enabled in the security service."};
static const struct msg TOTInvalidCode{1086,"Invalid code."};
static const struct msg TOTInvalidIndex{1087,"Invalid index."};
@@ -209,9 +159,7 @@ namespace OpenWifi::RESTAPI::Errors {
static const struct msg SignupWaitingForDevice{1093,"Waiting for device."};
static const struct msg SMSMissingPhoneNumber{1094,"Missing phone number"};
static const struct msg SMSTryLater {
1095, "SMS could not be sent. Verify the number or try again later."
};
static const struct msg SMSTryLater{1095,"SMS could not be sent. Verify the number or try again later."};
static const struct msg SMSMissingChallenge{1096,"Missing 'challengeCode'"};
static const struct msg MustHaveConfigElement{1097,"Must have 'configuration' element."};
@@ -221,122 +169,60 @@ namespace OpenWifi::RESTAPI::Errors {
static const struct msg SubNoDeviceActivated{1100,"No devices activated yet."};
static const struct msg SubConfigNotRefreshed{1101,"Configuration could not be refreshed."};
static const struct msg ProvServiceNotAvailable {
1102, "Provisioning service not available yet."
};
static const struct msg SSIDInvalidPassword {
1103, "Invalid password length. Must be 8 characters or greater, and a maximum of 32 "
"characters."
};
static const struct msg InvalidStartingIPAddress {
1104, "Invalid starting/ending IP address."
};
static const struct msg SubnetFormatError {
1105, "Subnet must be in format like 192.168.1.1/24."
};
static const struct msg DeviceModeError {
1106, "Device mode subnet must be of the form 192.168.1.1/24."
};
static const struct msg ProvServiceNotAvailable{1102,"Provisioning service not available yet."};
static const struct msg SSIDInvalidPassword{1103,"Invalid password length. Must be 8 characters or greater, and a maximum of 32 characters."};
static const struct msg InvalidStartingIPAddress{1104,"Invalid starting/ending IP address."};
static const struct msg SubnetFormatError{1105,"Subnet must be in format like 192.168.1.1/24."};
static const struct msg DeviceModeError{1106,"Device mode subnet must be of the form 192.168.1.1/24."};
static const struct msg BadDeviceMode{1107,"Mode must be bridge, nat, or manual."};
static const struct msg DefaultGatewayFormat {
1108, "Default gateway must be in format like 192.168.1.1."
};
static const struct msg PrimaryDNSFormat {
1109, "Primary DNS must be an IP address i.e. 192.168.1.1."
};
static const struct msg DefaultGatewayFormat{1108,"Default gateway must be in format like 192.168.1.1."};
static const struct msg PrimaryDNSFormat{1109,"Primary DNS must be an IP address i.e. 192.168.1.1."};
static const struct msg SecondaryDNSFormat {
1110, "Secondary DNS must be an IP address i.e. 192.168.1.1."
};
static const struct msg BadConnectionType {
1111, "Internet Connection must be automatic, bridge, pppoe, or manual."
};
static const struct msg SecondaryDNSFormat{1110,"Secondary DNS must be an IP address i.e. 192.168.1.1."};
static const struct msg BadConnectionType{1111,"Internet Connection must be automatic, bridge, pppoe, or manual."};
static const struct msg InvalidDeviceID{1112,"Invalid deviceID."};
static const struct msg InvalidVisibilityAttribute{1113,"Invalid visibility attribute."};
static const struct msg UnknownConfigurationSection{1114,"Unknown section."};
static const struct msg CannotValidatePhoneNumber {
1115, "Phone number could not be validated."
};
static const struct msg CannotValidatePhoneNumber{1115,"Phone number could not be validated."};
static const struct msg RootUsersNoOwners{1116,"ROOT users may not have owners."};
static const struct msg PartnerMustHaveEntity {
1118, "Partner user must belong to an entity."
};
static const struct msg PartnerMustHaveEntity{1118,"Partner user must belong to an entity."};
static const struct msg RootCannotModifyUsers{1119,"ROOT may not modify user roles."};
static const struct msg CertificateNotIssued{1120,"Certificate was not issued."};
static const struct msg IncompleteCertificate {
1121, "Incomplete certificate information. Cannot be downloaded. You must delete and "
"recreate."
};
static const struct msg IncompleteCertificate{1121,"Incomplete certificate information. Cannot be downloaded. You must delete and recreate."};
static const struct msg InvalidCertificateType{1122,"Invalid certificate type."};
static const struct msg InvalidDeviceName{1123,"Invalid device name."};
static const struct msg InvalidRedirectorName{1124,"Invalid redirector name"};
static const struct msg CommonNameAlreadyExists {
1125, "A device/server of this name already exists"
};
static const struct msg CertificateAlreadyExists {
1126, "A certificate for this device already exists."
};
static const struct msg CannotCreateCertTryAgain {
1127, "Device certificate could not be created. Please try later."
};
static const struct msg CommonNameAlreadyExists{1125,"A device/server of this name already exists"};
static const struct msg CertificateAlreadyExists{1126,"A certificate for this device already exists."};
static const struct msg CannotCreateCertTryAgain{1127,"Device certificate could not be created. Please try later."};
static const struct msg CouldNotRevoke{1128,"Certificate could not be revoked."};
static const struct msg CouldNotModifyCert {
1129, "Certificate could not me modified. Please verify the information you supplied."
};
static const struct msg BatchCertNoCreated {
1130, "Certificates have not been created for this batch."
};
static const struct msg BatchTooBig {
1131, "Illegal number of MAC Addresses: must be between 1 and 1000."
};
static const struct msg CouldNotModifyCert{1129,"Certificate could not me modified. Please verify the information you supplied."};
static const struct msg BatchCertNoCreated{1130,"Certificates have not been created for this batch."};
static const struct msg BatchTooBig{1131,"Illegal number of MAC Addresses: must be between 1 and 1000."};
static const struct msg OutstandingJobs {
1132, "Batch has running outstanding jobs. Please wait until job is finished."
};
static const struct msg OutstandingJobs{1132,"Batch has running outstanding jobs. Please wait until job is finished."};
static const struct msg InvalidSMSNotificationList{1133,"Invalid SMS Notification list."};
static const struct msg InvalidEMailNotificationList {
1134, "Invalid email Notification list."
};
static const struct msg CannotChangeCommanNames {
1135, "You cannot provide new/modified common names after jobs have been run for a batch."
};
static const struct msg FailedToVerifyDigicert {
1136, "Failed to verify the DigiCert information provided."
};
static const struct msg InvalidEMailNotificationList{1134,"Invalid email Notification list."};
static const struct msg CannotChangeCommanNames{1135,"You cannot provide new/modified common names after jobs have been run for a batch."};
static const struct msg FailedToVerifyDigicert{1136,"Failed to verify the DigiCert information provided."};
static const struct msg CouldNotPerformCommand{1137,"Could not perform command."};
static const struct msg PoolNameInvalid{1138,"Pool name is invalid."};
static const struct msg InvalidRadiusProxyStrategy {
1139, "Strategy name must be: random, round_robin, weighted."
};
static const struct msg InvalidRadiusProxyMonitorMethod {
1140, "monitorMethod must be: none, https, radius."
};
static const struct msg MustHaveAtLeastOneRadiusServer {
1141, "Must have at least one RADIUS server."
};
static const struct msg InvalidRadiusServerEntry {
1142, "RADIUS Server IP address invalid or port missing."
};
static const struct msg InvalidRadiusServerWeigth {
1143, "RADIUS Server IP weight cannot be 0."
};
static const struct msg InvalidRadiusProxyStrategy{1139,"Strategy name must be: random, round_robin, weighted."};
static const struct msg InvalidRadiusProxyMonitorMethod{1140,"monitorMethod must be: none, https, radius."};
static const struct msg MustHaveAtLeastOneRadiusServer{1141,"Must have at least one RADIUS server."};
static const struct msg InvalidRadiusServerEntry{1142,"RADIUS Server IP address invalid or port missing."};
static const struct msg InvalidRadiusServerWeigth{1143,"RADIUS Server IP weight cannot be 0."};
static const struct msg MaximumRTTYSessionsReached {
1144, "Too many RTTY sessions currently active"
};
static const struct msg DeviceIsAlreadyBusy {
1145, "Device is already executing a command. Please try later."
};
static const struct msg MaximumRTTYSessionsReached{1144,"Too many RTTY sessions currently active"};
static const struct msg DeviceIsAlreadyBusy{1145,"Device is already executing a command. Please try later."};
static const struct msg DeviceRequiresSignature {
1146, "Device requires device signature to be provided."
};
static const struct msg DeviceRequiresSignature{1146,"Device requires device signature to be provided."};
static const struct msg ApiKeyNameAlreadyExists{1147,"API Key name must be unique."};
static const struct msg TooManyApiKeys{1148,"Too many API Keys have already been created."};
@@ -344,79 +230,32 @@ namespace OpenWifi::RESTAPI::Errors {
static const struct msg ApiKeyNameDoesNotExist{1150,"API Key name does not exist."};
static const struct msg ApiKeyDoesNotExist{1150,"API Key does not exist."};
static const struct msg DeviceIsRestricted {
1151, "Device is protected by regulation. This function is not allowed."
};
static const struct msg DeviceIsRestricted{1151,"Device is protected by regulation. This function is not allowed."};
static const struct msg InvalidURI{1152,"Invalid URI."};
static const struct msg InvalidScriptSelection {
1153, "Only script or scriptId must be specified. Not both."
};
static const struct msg InvalidScriptSelection{1153,"Only script or scriptId must be specified. Not both."};
static const struct msg NoDeviceStatisticsYet{1154,"Device statistics not available yet."};
static const struct msg AccountSuspended {
1155, "You account was suspended. You can only use this site in read-only mode for now."
};
static const struct msg AccountSuspended{1155,"You account was suspended. You can only use this site in read-only mode for now."};
static const struct msg BatchNameAlreadyExists{1156,"Batch name must be unique."};
static const struct msg RedirectorNameIsInvalid{1157,"Redirector name is invalid."};
static const struct msg CertificateAlreadyBelongsToYou {
1158, "The serial number already belongs to you. Please use the certificate modification "
"API to change the redirector."
};
static const struct msg RelocationDisabledForThisDevice {
1159, "Relocation disabled for this device."
};
static const struct msg CannotModifyServerCertificates {
1160, "Server certificates cannot be modified."
};
static const struct msg CertificateAlreadyBelongsToYou{1158,"The serial number already belongs to you. Please use the certificate modification API to change the redirector."};
static const struct msg RelocationDisabledForThisDevice{1159,"Relocation disabled for this device."};
static const struct msg CannotModifyServerCertificates{1160,"Server certificates cannot be modified."};
static const struct msg TransferNotInDispute {
1161, "The specified transfer is not being disputed."
};
static const struct msg TransferNotInDispute{1161,"The specified transfer is not being disputed."};
static const struct msg MissingComment{1162,"Missing comment."};
static const struct msg EntityNotAllowedToTransfer {
1163, "Entity is not allowed to transfer devices."
};
static const struct msg DailyTransferQuotaExceeded {
1164, "Entity has exceeded its daily quota."
};
static const struct msg CertificateWasNotRevoked {
1165, "Certificate was not revoked, so it may not be re-created."
};
static const struct msg CertificateTransferNoLongerExists {
1166, "The device certificate associated with this transfer no longer seem to exist."
};
static const struct msg CertificateTransferEntityNoLongerExists {
1167, "The entity tied to this transfer no longer seems to exist."
};
static const struct msg CannotRollBackDueToDigiCert {
1168, "The change could not be rolled back at this time. Please try later."
};
static const struct msg CertificateTransferAlreadyRolledBack {
1169, "The certificate has already been rolled back."
};
static const struct msg FirmwareBDInProgress {
1170, "Firmware DB update already in progress."
};
static const struct msg SimulatedDeviceNotSupported {
1171, "Command not supported on simulated device."
};
static const struct msg EntityNotAllowedToTransfer{1163,"Entity is not allowed to transfer devices."};
static const struct msg DailyTransferQuotaExceeded{1164,"Entity has exceeded its daily quota."};
static const struct msg CertificateWasNotRevoked{1165,"Certificate was not revoked, so it may not be re-created."};
static const struct msg CertificateTransferNoLongerExists{1166,"The device certificate associated with this transfer no longer seem to exist."};
static const struct msg CertificateTransferEntityNoLongerExists{1167,"The entity tied to this transfer no longer seems to exist."};
static const struct msg CannotRollBackDueToDigiCert{1168,"The change could not be rolled back at this time. Please try later."};
static const struct msg CertificateTransferAlreadyRolledBack{1169,"The certificate has already been rolled back."};
static const struct msg FirmwareBDInProgress{1170,"Firmware DB update already in progress."};
static const struct msg VenuesNameAlreadyExists {
1172, "The venue name already exists."
};
static const struct msg DefFirmwareNameExists { 1172, "Firmware name already exists." };
static const struct msg SimulationDoesNotExist {
7000, "Simulation Instance ID does not exist."
};
static const struct msg SimulationIsAlreadyRunning {
7001, "There is an instance of this simulation already running.."
};
}
} // namespace OpenWifi::RESTAPI::Errors
namespace OpenWifi::RESTAPI::Protocol {
static const char * CAPABILITIES = "capabilities";
@@ -549,7 +388,7 @@ namespace OpenWifi::RESTAPI::Protocol {
static const char * INTERVAL = "interval";
static const char * UI = "UI";
static const char * BANDWIDTH = "bandwidth";
} // namespace OpenWifi::RESTAPI::Protocol
}
namespace OpenWifi::uCentralProtocol {
@@ -572,7 +411,6 @@ namespace OpenWifi::uCentralProtocol {
static const char *HEALTHCHECK = "healthcheck";
static const char *LOG = "log";
static const char *CRASHLOG = "crashlog";
static const char *REBOOTLOG = "rebootLog";
static const char *PING = "ping";
static const char *CFGPENDING = "cfgpending";
static const char *RECOVERY = "recovery";
@@ -631,8 +469,6 @@ namespace OpenWifi::uCentralProtocol {
static const char *DEVICEUPDATE = "deviceupdate";
static const char *FWSIGNATURE = "FWsignature";
static const char *SIGNATURE = "signature";
static const char *INFO = "info";
static const char *DATE = "date";
static const char *SERIALNUMBER = "serialNumber";
static const char *COMPATIBLE = "compatible";
@@ -654,7 +490,7 @@ namespace OpenWifi::uCentralProtocol {
static const char *RADIUSCOA = "coa";
static const char *RADIUSDST = "dst";
static const char *IES = "ies";
} // namespace OpenWifi::uCentralProtocol
}
namespace OpenWifi::uCentralProtocol::Events {
@@ -663,7 +499,6 @@ namespace OpenWifi::uCentralProtocol::Events {
static const char *HEALTHCHECK = "healthcheck";
static const char *LOG = "log";
static const char *CRASHLOG = "crashlog";
static const char *REBOOTLOG = "rebootLog";
static const char *PING = "ping";
static const char *CFGPENDING = "cfgpending";
static const char *RECOVERY = "recovery";
@@ -687,8 +522,7 @@ namespace OpenWifi::uCentralProtocol::Events {
ET_VENUEBROADCAST,
ET_EVENT,
ET_WIFISCAN,
ET_ALARM,
ET_REBOOTLOG
ET_ALARM
};
inline EVENT_MSG EventFromString(const std::string & Method) {
@@ -719,12 +553,10 @@ namespace OpenWifi::uCentralProtocol::Events {
else if(strcmp(WIFISCAN,Method.c_str())==0)
return ET_WIFISCAN;
else if(strcmp(ALARM,Method.c_str())==0)
return ET_WIFISCAN;
return ET_ALARM;
else if (strcmp(REBOOTLOG, Method.c_str()) == 0)
return ET_REBOOTLOG;
return ET_UNKNOWN;
};
} // namespace OpenWifi::uCentralProtocol::Events
}
namespace OpenWifi::APCommands {
enum class Commands:uint8_t {
@@ -750,17 +582,28 @@ namespace OpenWifi::APCommands {
};
inline static const std::vector<const char *> uCentralAPCommands {
RESTAPI::Protocol::CAPABILITIES, RESTAPI::Protocol::LOGS,
RESTAPI::Protocol::HEALTHCHECKS, RESTAPI::Protocol::STATISTICS,
RESTAPI::Protocol::STATUS, RESTAPI::Protocol::RTTY,
RESTAPI::Protocol::CONFIGURE, RESTAPI::Protocol::UPGRADE,
RESTAPI::Protocol::REBOOT, RESTAPI::Protocol::FACTORY,
RESTAPI::Protocol::LEDS, RESTAPI::Protocol::TRACE,
RESTAPI::Protocol::REQUEST, RESTAPI::Protocol::WIFISCAN,
RESTAPI::Protocol::EVENTQUEUE, RESTAPI::Protocol::TELEMETRY,
RESTAPI::Protocol::PING, RESTAPI::Protocol::SCRIPT};
RESTAPI::Protocol::CAPABILITIES,
RESTAPI::Protocol::LOGS,
RESTAPI::Protocol::HEALTHCHECKS,
RESTAPI::Protocol::STATISTICS,
RESTAPI::Protocol::STATUS,
RESTAPI::Protocol::RTTY,
RESTAPI::Protocol::CONFIGURE,
RESTAPI::Protocol::UPGRADE,
RESTAPI::Protocol::REBOOT,
RESTAPI::Protocol::FACTORY,
RESTAPI::Protocol::LEDS,
RESTAPI::Protocol::TRACE,
RESTAPI::Protocol::REQUEST,
RESTAPI::Protocol::WIFISCAN,
RESTAPI::Protocol::EVENTQUEUE,
RESTAPI::Protocol::TELEMETRY,
RESTAPI::Protocol::PING,
RESTAPI::Protocol::SCRIPT};
inline const char *to_string(Commands Cmd) { return uCentralAPCommands[(uint8_t)Cmd]; }
inline const char * to_string(Commands Cmd) {
return uCentralAPCommands[(uint8_t)Cmd];
}
inline Commands to_apcommand(const char *cmd) {
for(auto i=(uint8_t)Commands::capabilities;i!=(uint8_t)Commands::unknown;++i) {
@@ -770,7 +613,7 @@ namespace OpenWifi::APCommands {
return Commands::unknown;
}
} // namespace OpenWifi::APCommands
}
namespace OpenWifi::Provisioning::DeviceClass {
@@ -784,7 +627,7 @@ namespace OpenWifi::Provisioning::DeviceClass {
return std::find(cbegin(Values), cend(Values), s) != cend(Values);
}
} // namespace OpenWifi::Provisioning::DeviceClass
}
#if defined(__GNUC__ )
#pragma GCC diagnostic pop
@@ -793,3 +636,5 @@ namespace OpenWifi::Provisioning::DeviceClass {
#if defined(__clang__)
#pragma clang diagnostic pop
#endif

View File

@@ -4,8 +4,8 @@
#include "Poco/Path.h"
#include "framework/AppServiceRegistry.h"
#include "framework/utils.h"
#include "framework/AppServiceRegistry.h"
namespace OpenWifi::Utils {
@@ -27,21 +27,11 @@ namespace OpenWifi::Utils {
std::all_of(Serial.begin(),Serial.end(),[](auto i){return std::isxdigit(i);}));
}
[[nodiscard]] bool ValidSerialNumbers(const std::vector<std::string> &numbers) {
return std::all_of(numbers.begin(),numbers.end(),[](auto &number) {return ValidSerialNumber(number);});
}
[[nodiscard]] bool ValidUUID(const std::string &UUID) {
if(UUID.size()>36)
return false;
uint dashes=0;
return (std::all_of(UUID.begin(), UUID.end(),
[&](auto i) {
if (i == '-')
dashes++;
return i == '-' || std::isxdigit(i);
})) &&
(dashes > 0);
return (std::all_of(UUID.begin(),UUID.end(),[&](auto i){ if(i=='-') dashes++; return i=='-' || std::isxdigit(i);})) && (dashes>0);
}
[[nodiscard]] std::vector<std::string> Split(const std::string &List, char Delimiter ) {
@@ -49,20 +39,25 @@ namespace OpenWifi::Utils {
unsigned long P=0;
while (P < List.size()) {
while(P<List.size())
{
unsigned long P2 = List.find_first_of(Delimiter, P);
if(P2==std::string::npos) {
ReturnList.push_back(List.substr(P));
break;
} else
}
else
ReturnList.push_back(List.substr(P,P2-P));
P=P2+1;
}
return ReturnList;
}
[[nodiscard]] std::string FormatIPv6(const std::string &I) {
if (I.substr(0, 8) == "[::ffff:") {
[[nodiscard]] std::string FormatIPv6(const std::string & I )
{
if(I.substr(0,8) == "[::ffff:")
{
unsigned long PClosingBracket = I.find_first_of(']');
std::string ip = I.substr(8, PClosingBracket-8);
@@ -87,24 +82,12 @@ namespace OpenWifi::Utils {
char buf[18];
buf[0] = R[0];
buf[1] = R[1];
buf[2] = ':';
buf[3] = R[2];
buf[4] = R[3];
buf[5] = ':';
buf[6] = R[4];
buf[7] = R[5];
buf[8] = ':';
buf[9] = R[6];
buf[10] = R[7];
buf[11] = ':';
buf[12] = R[8];
buf[13] = R[9];
buf[14] = ':';
buf[15] = R[10];
buf[16] = R[11];
buf[17] = 0;
buf[0] = R[0]; buf[1] = R[1] ; buf[2] = ':' ;
buf[3] = R[2] ; buf[4] = R[3]; buf[5] = ':' ;
buf[6] = R[4]; buf[7] = R[5] ; buf[8] = ':' ;
buf[9] = R[6] ; buf[10]= R[7]; buf[11] = ':';
buf[12] = R[8] ; buf[13]= R[9]; buf[14] = ':';
buf[15] = R[10] ; buf[16]= R[11];buf[17] = 0;
return buf;
}
@@ -127,27 +110,18 @@ namespace OpenWifi::Utils {
}
[[nodiscard]] bool ValidHostname(const std::string &Hostname) {
static std::regex HostNameRegex(
"^(?!-)[A-Za-z0-9-]+([\\-\\.]{1}[a-z0-9]+)*\\.[A-Za-z]{2,6}$");
static std::regex HostNameRegex("^(?!-)[A-Za-z0-9-]+([\\-\\.]{1}[a-z0-9]+)*\\.[A-Za-z]{2,6}$");
return std::regex_match(Hostname,HostNameRegex);
}
[[nodiscard]] bool ValidNumber(const std::string &number, bool isSigned)
{
static std::regex IntRegex("^-?[0-9]\\d*(\\.\\d+)?$");
if(!isSigned) {
IntRegex = "^[0-9]\\d*(\\.\\d+)?$";
}
return std::regex_match(number, IntRegex);
}
[[nodiscard]] std::string ToHex(const std::vector<unsigned char> & B) {
std::string R;
R.reserve(B.size()*2);
static const char hex[] = "0123456789abcdef";
for (const auto &i : B) {
for(const auto &i:B)
{
R += (hex[ (i & 0xf0) >> 4]);
R += (hex[ (i & 0x0f) ]);
}
@@ -155,8 +129,7 @@ namespace OpenWifi::Utils {
return R;
}
inline static const char kEncodeLookup[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
inline static const char kEncodeLookup[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
inline static const char kPadCharacter = '=';
using byte = std::uint8_t;
@@ -198,17 +171,17 @@ namespace OpenWifi::Utils {
return encoded;
}
[[nodiscard]] std::vector<byte> base64decode(const std::string &input) {
[[nodiscard]] std::vector<byte> base64decode(const std::string& input)
{
if(input.length() % 4)
throw std::runtime_error("Invalid base64 length!");
std::size_t padding=0;
if (input.length()) {
if (input[input.length() - 1] == kPadCharacter)
padding++;
if (input[input.length() - 2] == kPadCharacter)
padding++;
if(input.length())
{
if(input[input.length() - 1] == kPadCharacter) padding++;
if(input[input.length() - 2] == kPadCharacter) padding++;
}
std::vector<byte> decoded;
@@ -217,21 +190,20 @@ namespace OpenWifi::Utils {
std::uint32_t temp=0;
auto it = input.begin();
while (it < input.end()) {
for (std::size_t i = 0; i < 4; ++i) {
while(it < input.end())
{
for(std::size_t i = 0; i < 4; ++i)
{
temp <<= 6;
if (*it >= 0x41 && *it <= 0x5A)
temp |= *it - 0x41;
else if (*it >= 0x61 && *it <= 0x7A)
temp |= *it - 0x47;
else if (*it >= 0x30 && *it <= 0x39)
temp |= *it + 0x04;
else if (*it == 0x2B)
temp |= 0x3E;
else if (*it == 0x2F)
temp |= 0x3F;
else if (*it == kPadCharacter) {
switch (input.end() - it) {
if (*it >= 0x41 && *it <= 0x5A) temp |= *it - 0x41;
else if(*it >= 0x61 && *it <= 0x7A) temp |= *it - 0x47;
else if(*it >= 0x30 && *it <= 0x39) temp |= *it + 0x04;
else if(*it == 0x2B) temp |= 0x3E;
else if(*it == 0x2F) temp |= 0x3F;
else if(*it == kPadCharacter)
{
switch(input.end() - it)
{
case 1:
decoded.push_back((temp >> 16) & 0x000000FF);
decoded.push_back((temp >> 8 ) & 0x000000FF);
@@ -242,8 +214,8 @@ namespace OpenWifi::Utils {
default:
throw std::runtime_error("Invalid padding in base64!");
}
} else
throw std::runtime_error("Invalid character in base64!");
}
else throw std::runtime_error("Invalid character in base64!");
++it;
}
@@ -274,6 +246,7 @@ namespace OpenWifi::Utils {
return true;
}
bool ParseDate(const std::string &Time, int & Year, int & Month, int & Day) {
Poco::StringTokenizer DateTokens(Time,"-",Poco::StringTokenizer::TOK_TRIM);
@@ -303,24 +276,15 @@ namespace OpenWifi::Utils {
[[nodiscard]] std::string LogLevelToString(int Level) {
switch(Level) {
case Poco::Message::PRIO_DEBUG:
return "debug";
case Poco::Message::PRIO_INFORMATION:
return "information";
case Poco::Message::PRIO_FATAL:
return "fatal";
case Poco::Message::PRIO_WARNING:
return "warning";
case Poco::Message::PRIO_NOTICE:
return "notice";
case Poco::Message::PRIO_CRITICAL:
return "critical";
case Poco::Message::PRIO_ERROR:
return "error";
case Poco::Message::PRIO_TRACE:
return "trace";
default:
return "none";
case Poco::Message::PRIO_DEBUG: return "debug";
case Poco::Message::PRIO_INFORMATION: return "information";
case Poco::Message::PRIO_FATAL: return "fatal";
case Poco::Message::PRIO_WARNING: return "warning";
case Poco::Message::PRIO_NOTICE: return "notice";
case Poco::Message::PRIO_CRITICAL: return "critical";
case Poco::Message::PRIO_ERROR: return "error";
case Poco::Message::PRIO_TRACE: return "trace";
default: return "none";
}
}
@@ -342,6 +306,7 @@ namespace OpenWifi::Utils {
return b;
}
[[nodiscard]] bool SerialNumberMatch(const std::string &S1, const std::string &S2, int Bits) {
auto S1_i = SerialNumberToInt(S1);
auto S2_i = SerialNumberToInt(S2);
@@ -410,8 +375,8 @@ namespace OpenWifi::Utils {
[[nodiscard]] bool ValidEMailAddress(const std::string &email) {
// define a regular expression
static const std::regex pattern(
"[_a-z0-9-]+(\\.[_a-z0-9-]+)*(\\+[a-z0-9-]+)?@[a-z0-9-]+(\\.[a-z0-9-]+)*");
static const std::regex pattern
("[_a-z0-9-]+(\\.[_a-z0-9-]+)*(\\+[a-z0-9-]+)?@[a-z0-9-]+(\\.[a-z0-9-]+)*");
// try to match the string with the regular expression
return std::regex_match(email, pattern);
}
@@ -424,6 +389,7 @@ namespace OpenWifi::Utils {
Poco::StreamCopier::copyStream(IF, OS);
Result = OS.str();
} catch (...) {
}
return Result;
}
@@ -437,29 +403,28 @@ namespace OpenWifi::Utils {
[[nodiscard]] MediaTypeEncoding FindMediaType(const Poco::File &F) {
const auto E = Poco::Path(F.path()).getExtension();
if(E=="png")
return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "image/png"};
return MediaTypeEncoding{ .Encoding = BINARY,
.ContentType = "image/png" };
if(E=="gif")
return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "image/gif"};
return MediaTypeEncoding{ .Encoding = BINARY,
.ContentType = "image/gif" };
if(E=="jpeg" || E=="jpg")
return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "image/jpeg"};
return MediaTypeEncoding{ .Encoding = BINARY,
.ContentType = "image/jpeg" };
if(E=="svg" || E=="svgz")
return MediaTypeEncoding{.Encoding = PLAIN, .ContentType = "image/svg+xml"};
return MediaTypeEncoding{ .Encoding = PLAIN,
.ContentType = "image/svg+xml" };
if(E=="html")
return MediaTypeEncoding{.Encoding = PLAIN, .ContentType = "text/html"};
return MediaTypeEncoding{ .Encoding = PLAIN,
.ContentType = "text/html" };
if(E=="css")
return MediaTypeEncoding{.Encoding = PLAIN, .ContentType = "text/css"};
return MediaTypeEncoding{ .Encoding = PLAIN,
.ContentType = "text/css" };
if(E=="js")
return MediaTypeEncoding{.Encoding = PLAIN, .ContentType = "application/javascript"};
if (E == "pcap")
return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "application/vnd.tcpdump.pcap"};
if (E == "txt")
return MediaTypeEncoding{.Encoding = PLAIN, .ContentType = "text/plain"};
if (E == "tgz")
return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "application/tar+gzip"};
if (E == "gz" || E=="gzip")
return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "application/gzip"};
return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "application/octet-stream"};
return MediaTypeEncoding{ .Encoding = PLAIN,
.ContentType = "application/javascript" };
return MediaTypeEncoding{ .Encoding = BINARY,
.ContentType = "application/octet-stream" };
}
[[nodiscard]] std::string BinaryFileToHexString(const Poco::File &F) {
@@ -481,6 +446,7 @@ namespace OpenWifi::Utils {
Result += (char) (hex[(C & 0x0f)]);
}
} catch(...) {
}
return Result;
}
@@ -493,8 +459,7 @@ namespace OpenWifi::Utils {
Seconds -= Hours * (60*60);
int Minutes = Seconds / 60;
Seconds -= Minutes * 60;
Result = std::to_string(Days) + " days, " + std::to_string(Hours) + ":" +
std::to_string(Minutes) + ":" + std::to_string(Seconds);
Result = std::to_string(Days) +" days, " + std::to_string(Hours) + ":" + std::to_string(Minutes) + ":" + std::to_string(Seconds);
return Result;
}
@@ -510,8 +475,7 @@ namespace OpenWifi::Utils {
}
// send request
Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, path,
Poco::Net::HTTPMessage::HTTP_1_1);
Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, path, Poco::Net::HTTPMessage::HTTP_1_1);
session.sendRequest(req);
Poco::Net::HTTPResponse res;
@@ -523,6 +487,7 @@ namespace OpenWifi::Utils {
return true;
} catch (...) {
}
return false;
}
@@ -532,17 +497,16 @@ namespace OpenWifi::Utils {
Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort());
// send request
Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri.getPath(),
Poco::Net::HTTPMessage::HTTP_1_1);
Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri.getPath(), Poco::Net::HTTPMessage::HTTP_1_1);
session.sendRequest(req);
Poco::Net::HTTPResponse res;
std::istream &is = session.receiveResponse(res);
std::fstream os(FileName,
std::ios_base::trunc | std::ios_base::binary | std::ios_base::out);
std::fstream os(FileName,std::ios_base::trunc | std::ios_base::binary | std::ios_base::out);
Poco::StreamCopier::copyStream(is,os);
return true;
} catch (...) {
}
return false;
}
@@ -555,8 +519,7 @@ namespace OpenWifi::Utils {
Poco::StreamCopier::copyStream(b64in, ofs);
int factor = 20;
unsigned long MaxSize = compress_sz ? (unsigned long)(compress_sz + 5000)
: (unsigned long)(ofs.str().size() * factor);
unsigned long MaxSize = compress_sz ? (unsigned long) (compress_sz + 5000) : (unsigned long) (ofs.str().size() * factor);
while(true) {
std::vector<uint8_t> UncompressedBuffer(MaxSize);
unsigned long FinalSize = MaxSize;
@@ -597,6 +560,7 @@ namespace OpenWifi::Utils {
Poco::URI u(uri);
return true;
} catch (...) {
}
return false;
}
@@ -608,4 +572,4 @@ namespace OpenWifi::Utils {
return DT.timestamp().epochTime();
}
} // namespace OpenWifi::Utils
}

View File

@@ -4,36 +4,34 @@
#pragma once
#include <string>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <iomanip>
#include <random>
#include <regex>
#include <shared_mutex>
#include <string>
#include <thread>
#include <shared_mutex>
#include <dirent.h>
#include "Poco/Thread.h"
#include "Poco/StringTokenizer.h"
#include "Poco/String.h"
#include "Poco/SHA2Engine.h"
#include "Poco/Message.h"
#include "Poco/StreamCopier.h"
#include "Poco/File.h"
#include "Poco/Net/NetworkInterface.h"
#include "Poco/URI.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPClientSession.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/Net/HTTPResponse.h"
#include "Poco/Base64Decoder.h"
#include "Poco/Base64Encoder.h"
#include "Poco/File.h"
#include "Poco/Message.h"
#include "Poco/Net/HTTPClientSession.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPResponse.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/Net/NetworkInterface.h"
#include "Poco/SHA2Engine.h"
#include "Poco/StreamCopier.h"
#include "Poco/String.h"
#include "Poco/StringTokenizer.h"
#include "Poco/Thread.h"
#include "Poco/URI.h"
#include "Poco/zlib.h"
#include "framework/OpenWifiTypes.h"
#include "framework/ow_constants.h"
#include "framework/OpenWifiTypes.h"
namespace OpenWifi::Utils {
@@ -62,7 +60,11 @@ namespace OpenWifi::Utils {
#endif
}
enum MediaTypeEncodings { PLAIN, BINARY, BASE64 };
enum MediaTypeEncodings {
PLAIN,
BINARY,
BASE64
};
struct MediaTypeEncoding {
MediaTypeEncodings Encoding=PLAIN;
@@ -70,10 +72,8 @@ namespace OpenWifi::Utils {
};
[[nodiscard]] bool ValidSerialNumber(const std::string &Serial);
[[nodiscard]] bool ValidSerialNumbers(const std::vector<std::string> &Serial);
[[nodiscard]] bool ValidUUID(const std::string &UUID);
[[nodiscard]] bool ValidHostname(const std::string &hostname);
[[nodiscard]] bool ValidNumber(const std::string &number, bool isSigned);
template <typename ...Args> std::string ComputeHash(Args&&... args) {
Poco::SHA2Engine E;
@@ -98,16 +98,14 @@ namespace OpenWifi::Utils {
using byte = std::uint8_t;
[[nodiscard]] std::string base64encode(const byte *input, uint32_t size);
[[nodiscard]] std::vector<byte> base64decode(const std::string &input);
;
[[nodiscard]] std::vector<byte> base64decode(const std::string& input);;
bool ParseTime(const std::string &Time, int & Hours, int & Minutes, int & Seconds);
bool ParseDate(const std::string &Time, int & Year, int & Month, int & Day);
bool CompareTime( int H1, int H2, int M1, int M2, int S1, int S2);
[[nodiscard]] std::string LogLevelToString(int Level);
[[nodiscard]] uint64_t SerialNumberToInt(const std::string & S);
[[nodiscard]] std::string IntToSerialNumber(uint64_t S);
[[nodiscard]] bool SerialNumberMatch(const std::string &S1, const std::string &S2,
int Bits = 2);
[[nodiscard]] bool SerialNumberMatch(const std::string &S1, const std::string &S2, int Bits=2);
[[nodiscard]] uint64_t SerialNumberToOUI(const std::string & S);
[[nodiscard]] uint64_t GetDefaultMacAsInt64();
[[nodiscard]] uint64_t InitializeSystemId();
@@ -126,9 +124,12 @@ namespace OpenWifi::Utils {
[[nodiscard]] std::uint64_t ConvertDate(const std::string &d);
template <typename T> std::string int_to_hex(T i) {
template< typename T >
std::string int_to_hex( T i )
{
std::stringstream stream;
stream << std::setfill('0') << std::setw(12) << std::hex << i;
stream << std::setfill ('0') << std::setw(12)
<< std::hex << i;
return stream.str();
}
@@ -150,101 +151,4 @@ namespace OpenWifi::Utils {
bool ExtractBase64CompressedData(const std::string &CompressedData,
std::string &UnCompressedData, uint64_t compress_sz );
inline bool match(const char* first, const char* second)
{
// If we reach at the end of both strings, we are done
if (*first == '\0' && *second == '\0')
return true;
// Make sure to eliminate consecutive '*'
if (*first == '*') {
while (*(first + 1) == '*')
first++;
}
// Make sure that the characters after '*' are present
// in second string. This function assumes that the
// first string will not contain two consecutive '*'
if (*first == '*' && *(first + 1) != '\0'
&& *second == '\0')
return false;
// If the first string contains '?', or current
// characters of both strings match
if (*first == '?' || *first == *second)
return match(first + 1, second + 1);
// If there is *, then there are two possibilities
// a) We consider current character of second string
// b) We ignore current character of second string.
if (*first == '*')
return match(first + 1, second)
|| match(first, second + 1);
return false;
}
static inline std::uint64_t GetValue(FILE *file) {
unsigned long v=0;
char factor[32];
if(fscanf(file, " %lu %31s", &v, factor)==2) {
switch (factor[0]) {
case 'k':
return v * 1000;
case 'M':
return v * 1000000;
case 'G':
return v * 1000000000;
}
}
return v;
}
inline bool getMemory(
std::uint64_t &currRealMem, std::uint64_t &peakRealMem,
std::uint64_t &currVirtMem, std::uint64_t &peakVirtMem) {
// stores each word in status file
char buffer[1024] = "";
currRealMem = peakRealMem = currVirtMem = peakVirtMem = 0;
// linux file contains this-process info
FILE * file = std::fopen("/proc/self/status", "r");
if (file == nullptr) {
return false;
}
// read the entire file, recording mems in kB
while (fscanf(file, " %1023s", buffer) == 1) {
if (strcmp(buffer, "VmRSS:") == 0) {
currRealMem= GetValue(file);
} else if (strcmp(buffer, "VmHWM:") == 0) {
peakRealMem= GetValue(file);
} else if (strcmp(buffer, "VmSize:") == 0) {
currVirtMem= GetValue(file);
} else if (strcmp(buffer, "VmPeak:") == 0) {
peakVirtMem= GetValue(file);
}
}
fclose(file);
return true;
}
inline int get_open_fds() {
DIR *dp = opendir("/proc/self/fd");
struct dirent *de;
int count = -3; // '.', '..', dp
if (dp == nullptr)
return -1;
while ((de = readdir(dp)) != nullptr)
count++;
(void)closedir(dp);
return count;
}
} // namespace OpenWifi::Utils

View File

@@ -112,31 +112,6 @@ namespace OpenWifi {
return true;
}
bool VenueDB::DoesVenueNameAlreadyExist(const std::string &name, const std::string &entity_uuid, const std::string &parent_uuid) {
std::string Statement;
if(!entity_uuid.empty()) {
Statement = fmt::format("select count(*) from venues where entity='{}' and upper(name)='{}'",
entity_uuid, Poco::toUpper(name));
} else {
Statement = fmt::format("select count(*) from venues where parent='{}' and upper(name)='{}'",
parent_uuid, Poco::toUpper(name));
}
std::uint64_t RecordCount = 0;
try {
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Command(Session);
Command << Statement,
Poco::Data::Keywords::into(RecordCount);
Command.execute();
} catch (...) {
}
return RecordCount!=0;
}
} // namespace OpenWifi
template <>

View File

@@ -26,7 +26,6 @@ namespace OpenWifi {
bool GetByIP(const std::string &IP, std::string &uuid);
bool Upgrade(uint32_t from, uint32_t &to) override;
bool EvaluateDeviceRules(const std::string &id, ProvObjects::DeviceRules &Rules);
bool DoesVenueNameAlreadyExist(const std::string &name, const std::string &entity_uuid, const std::string &parent_uuid);
private:
};