mirror of
https://github.com/Telecominfraproject/wlan-cloud-owprov.git
synced 2025-10-30 18:18:03 +00:00
Compare commits
4 Commits
v2.11.0-RC
...
v2.9.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9bc5086f24 | ||
|
|
71eefca353 | ||
|
|
1cccd2aa73 | ||
|
|
198888d554 |
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
#############################
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -19,4 +19,4 @@ namespace OpenWifi {
|
||||
static const std::string uSERVICE_ANALYTICS{ "owanalytics"};
|
||||
static const std::string uSERVICE_OWRRM{ "owrrm"};
|
||||
|
||||
} // namespace OpenWifi
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 = "");
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -4,4 +4,5 @@
|
||||
|
||||
#include "RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {} // namespace OpenWifi
|
||||
namespace OpenWifi {
|
||||
} // namespace OpenWifi
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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:
|
||||
|
||||
@@ -5,4 +5,7 @@
|
||||
#include "framework/UI_WebSocketClientNotifications.h"
|
||||
#include "framework/UI_WebSocketClientServer.h"
|
||||
|
||||
namespace OpenWifi {}
|
||||
namespace OpenWifi {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,9 @@ namespace OpenWifi {
|
||||
RESTAPI_utils::field_from_json(Obj, "content", content);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
}
|
||||
|
||||
|
||||
@@ -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 (...) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"}};
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <>
|
||||
|
||||
@@ -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:
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user