Compare commits

...

45 Commits

Author SHA1 Message Date
TIP Automation User
f8d3079f44 Chg: update image tag in helm values to v2.6.0-RC3 2022-07-09 12:17:34 +00:00
Stephane Bourque
81cec762f7 Merge pull request #60 from Telecominfraproject/main
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10079
2022-07-08 21:51:22 -07:00
Stephane Bourque
a430ad7e71 Merge pull request #59 from Telecominfraproject/WIFI-100079
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10079
2022-07-08 21:16:35 -07:00
stephb9959
d1c13ad2dd Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10079
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-08 21:15:54 -07:00
Stephane Bourque
b837e41569 Merge pull request #58 from Telecominfraproject/WIFI-100079
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10079
2022-07-08 08:55:10 -07:00
stephb9959
5e39987e36 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10079
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-08 08:49:53 -07:00
Stephane Bourque
890eb7311a Merge pull request #57 from Telecominfraproject/WIFI-10040
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
2022-07-04 21:40:16 -07:00
stephb9959
fc509adf01 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-04 14:11:59 -07:00
Stephane Bourque
f43198f874 Merge pull request #56 from Telecominfraproject/main
https://telecominfraproject.atlassian.net/browse/WIFI-10040
2022-07-01 12:31:50 -07:00
Stephane Bourque
767331f575 Merge pull request #55 from Telecominfraproject/WIFI-10040
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
2022-07-01 10:34:35 -07:00
stephb9959
d26ef6eeba Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-01 09:50:21 -07:00
Johann Hoffmann
8c672f058f Always re-generate config file if TEMPLATE_CONFIG is set to true (#53)
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-24 18:49:02 +02:00
Johann Hoffmann
3134947b57 Always re-generate config file if TEMPLATE_CONFIG is set to true (#54)
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-24 18:48:51 +02:00
stephb9959
448563ab06 Merge remote-tracking branch 'origin/main' 2022-06-18 22:02:30 -07:00
stephb9959
2a22a35e58 Framework update.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-18 22:02:22 -07:00
TIP Automation User
8e8656a6ae Chg: update image tag in helm values to v2.6.0-RC2 2022-06-17 13:39:12 +00:00
Johann Hoffmann
e745d4efe7 Supress curl output in PR cleanup workflow
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-17 12:03:20 +02:00
Johann Hoffmann
701e0b50ff [WIFI-9534] OWSEC error while doing GIT pull. (#52)
* Add condition to avoid deleting default and release branch images

Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>

* Fix regex

Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>

* Fix condition

Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-17 12:00:54 +02:00
Johann Hoffmann
df082a969e Temporarily disable cleanup for merges into release branches
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-15 14:50:15 +02:00
jaspreetsachdev
8863d2ecc9 Merge branch 'main' into release/v2.6.0 2022-06-14 16:29:49 -04:00
jaspreetsachdev
5e1937ec4f Merge branch 'main' of https://github.com/Telecominfraproject/wlan-cloud-ucentralsec 2022-06-14 16:22:46 -04:00
Stephane Bourque
e679dc7458 Fixing bug: https://telecominfraproject.atlassian.net/browse/WIFI-9471
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
7e1a962b57 Fixing bug
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
Dmitry Dunaev
8ad2e12f12 [WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
23d16e619a Framework update.
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
760cad9a14 Framework update.
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
94997a1f9f Framework update.
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
Dmitry Dunaev
9060fef03d [WIFI-7555] Fix: helm path
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
Johann Hoffmann
2f8eb90c5a Enable CI for pull requests in release branches
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
c0d0435efa Framework update.
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
6942de0475 Framework update.
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
cce2528ec4 Framework update.
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
3be0fd45d9 Framework update.
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
8b1a80ce09 Merge remote-tracking branch 'origin/main' 2022-06-14 07:44:17 -07:00
Stephane Bourque
5e12f00558 Fixing bug: https://telecominfraproject.atlassian.net/browse/WIFI-9471
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-14 07:44:04 -07:00
stephb9959
1d534cb974 Fixing bug 2022-06-14 07:26:44 -07:00
stephb9959
a7e9c96f8d Fixing bug 2022-06-14 07:22:17 -07:00
stephb9959
cb3f7a0872 Merge remote-tracking branch 'origin/main' 2022-06-14 07:13:19 -07:00
stephb9959
6ad434c02f Framework update. 2022-06-14 07:13:10 -07:00
Dmitry Dunaev
62e3ada15c Merge pull request #47 from Telecominfraproject/fix/wifi-9174--dep-charts
[WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
2022-06-03 19:31:44 +03:00
Dmitry Dunaev
2beef2daba [WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-06-03 19:31:22 +03:00
stephb9959
4b131465fb Framework update. 2022-05-31 23:53:47 -07:00
stephb9959
cafc243e55 Framework update. 2022-05-31 23:26:05 -07:00
stephb9959
5c44134f9d Merge remote-tracking branch 'origin/main' 2022-05-31 11:50:44 -07:00
stephb9959
8ed86d3582 Framework update. 2022-05-31 11:50:37 -07:00
23 changed files with 768 additions and 405 deletions

View File

@@ -17,4 +17,10 @@ jobs:
steps: steps:
- run: | - run: |
export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-') export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
curl -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owsec/$PR_BRANCH_TAG"
if [[ ! $PR_BRANCH_TAG =~ (main|master|release-*) ]]; then
echo "PR branch is $PR_BRANCH_TAG, deleting Docker image"
curl -s -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owsec/$PR_BRANCH_TAG"
else
echo "PR branch is $PR_BRANCH_TAG, not deleting Docker image"
fi

2
build
View File

@@ -1 +1 @@
57 60

View File

@@ -5,7 +5,7 @@ if [ "$SELFSIGNED_CERTS" = 'true' ]; then
update-ca-certificates update-ca-certificates
fi fi
if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWSEC_CONFIG"/owsec.properties ]]; then if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWSEC_ROOT/certs/restapi-ca.pem"} \ RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWSEC_ROOT/certs/restapi-ca.pem"} \
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16001"} \ RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16001"} \
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWSEC_ROOT/certs/restapi-cert.pem"} \ RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWSEC_ROOT/certs/restapi-cert.pem"} \

View File

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

View File

@@ -24,6 +24,7 @@ namespace OpenWifi {
void ActionLinkManager::run() { void ActionLinkManager::run() {
Running_ = true ; Running_ = true ;
Utils::SetThreadName("action-mgr");
while(Running_) { while(Running_) {
Poco::Thread::trySleep(2000); Poco::Thread::trySleep(2000);

View File

@@ -10,6 +10,7 @@
// Arilia Wireless Inc. // Arilia Wireless Inc.
// //
#include "Poco/Util/Application.h" #include "Poco/Util/Application.h"
#include "Poco/Util/Option.h" #include "Poco/Util/Option.h"
#include "Poco/Environment.h" #include "Poco/Environment.h"

View File

@@ -12,6 +12,10 @@ namespace OpenWifi {
void OpenWifi::RESTAPI_sms_handler::DoPost() { void OpenWifi::RESTAPI_sms_handler::DoPost() {
const auto &Obj = ParsedBody_; const auto &Obj = ParsedBody_;
if(!SMSSender()->Enabled()) {
return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
}
std::string Arg; std::string Arg;
if(HasParameter("validateNumber",Arg) && Arg=="true" && Obj->has("to")) { if(HasParameter("validateNumber",Arg) && Arg=="true" && Obj->has("to")) {
auto Number = Obj->get("to").toString(); auto Number = Obj->get("to").toString();

View File

@@ -76,12 +76,21 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::SMSMissingPhoneNumber); return BadRequest(RESTAPI::Errors::SMSMissingPhoneNumber);
} }
if(!SMSSender()->Enabled()) {
return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
}
if (SMSSender()->StartValidation(MFC.sms, UserInfo_.userinfo.email)) { if (SMSSender()->StartValidation(MFC.sms, UserInfo_.userinfo.email)) {
return OK(); return OK();
} else { } else {
return InternalError(RESTAPI::Errors::SMSTryLater); return InternalError(RESTAPI::Errors::SMSTryLater);
} }
} else if (GetBoolParameter("completeValidation", false)) { } else if (GetBoolParameter("completeValidation", false)) {
if(!SMSSender()->Enabled()) {
return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
}
auto ChallengeCode = GetParameter("challengeCode", ""); auto ChallengeCode = GetParameter("challengeCode", "");
if (ChallengeCode.empty()) { if (ChallengeCode.empty()) {
return BadRequest(RESTAPI::Errors::SMSMissingChallenge); return BadRequest(RESTAPI::Errors::SMSMissingChallenge);

View File

@@ -11,7 +11,6 @@ namespace OpenWifi {
auto Reset = GetBoolParameter("reset",false); auto Reset = GetBoolParameter("reset",false);
std::string QRCode; std::string QRCode;
if(TotpCache()->StartValidation(UserInfo_.userinfo,false,QRCode,Reset)) { if(TotpCache()->StartValidation(UserInfo_.userinfo,false,QRCode,Reset)) {
return SendFileContent(QRCode, "image/svg+xml","qrcode.svg"); return SendFileContent(QRCode, "image/svg+xml","qrcode.svg");
} }

View File

@@ -538,8 +538,8 @@ namespace OpenWifi::AnalyticsObjects {
void WifiClientHistory::to_json(Poco::JSON::Object &Obj) const { void WifiClientHistory::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"timestamp",timestamp); field_to_json(Obj,"timestamp",timestamp);
field_to_json(Obj,"stationId",stationId); field_to_json(Obj,"station_id",station_id);
field_to_json(Obj,"bssId",bssId); field_to_json(Obj,"bssid",bssid);
field_to_json(Obj,"ssid",ssid); field_to_json(Obj,"ssid",ssid);
field_to_json(Obj,"rssi",rssi); field_to_json(Obj,"rssi",rssi);
field_to_json(Obj,"rx_bitrate",rx_bitrate); field_to_json(Obj,"rx_bitrate",rx_bitrate);
@@ -573,13 +573,14 @@ namespace OpenWifi::AnalyticsObjects {
field_to_json(Obj,"connected",connected); field_to_json(Obj,"connected",connected);
field_to_json(Obj,"inactive",inactive); field_to_json(Obj,"inactive",inactive);
field_to_json(Obj,"tx_retries",tx_retries); field_to_json(Obj,"tx_retries",tx_retries);
field_to_json(Obj,"venue_id",venue_id);
} }
bool WifiClientHistory::from_json(const Poco::JSON::Object::Ptr &Obj) { bool WifiClientHistory::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json(Obj,"timestamp",timestamp); field_from_json(Obj,"timestamp",timestamp);
field_from_json(Obj,"stationId",stationId); field_from_json(Obj,"station_id",station_id);
field_from_json(Obj,"bssId",bssId); field_from_json(Obj,"bssid",bssid);
field_from_json(Obj,"ssid",ssid); field_from_json(Obj,"ssid",ssid);
field_from_json(Obj,"rssi",rssi); field_from_json(Obj,"rssi",rssi);
field_from_json(Obj,"rx_bitrate",rx_bitrate); field_from_json(Obj,"rx_bitrate",rx_bitrate);
@@ -613,6 +614,7 @@ namespace OpenWifi::AnalyticsObjects {
field_from_json(Obj,"connected",connected); field_from_json(Obj,"connected",connected);
field_from_json(Obj,"inactive",inactive); field_from_json(Obj,"inactive",inactive);
field_from_json(Obj,"tx_retries",tx_retries); field_from_json(Obj,"tx_retries",tx_retries);
field_from_json(Obj,"venue_id",venue_id);
return true; return true;
} catch(...) { } catch(...) {

View File

@@ -376,8 +376,8 @@ namespace OpenWifi {
struct WifiClientHistory { struct WifiClientHistory {
uint64_t timestamp=OpenWifi::Now(); uint64_t timestamp=OpenWifi::Now();
std::string stationId; std::string station_id;
std::string bssId; std::string bssid;
std::string ssid; std::string ssid;
int64_t rssi=0; int64_t rssi=0;
uint32_t rx_bitrate=0; uint32_t rx_bitrate=0;
@@ -411,6 +411,7 @@ namespace OpenWifi {
uint64_t connected=0; uint64_t connected=0;
uint64_t inactive=0; uint64_t inactive=0;
uint64_t tx_retries=0; uint64_t tx_retries=0;
std::string venue_id;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj); bool from_json(const Poco::JSON::Object::Ptr &Obj);

View File

@@ -3,176 +3,206 @@
// //
#include "RESTAPI_CertObjects.h" #include "RESTAPI_CertObjects.h"
#include "framework/MicroService.h"
using OpenWifi::RESTAPI_utils::field_to_json; using OpenWifi::RESTAPI_utils::field_to_json;
using OpenWifi::RESTAPI_utils::field_from_json; using OpenWifi::RESTAPI_utils::field_from_json;
namespace OpenWifi { namespace OpenWifi::CertObjects {
namespace CertObjects { void CertificateEntry::to_json(Poco::JSON::Object &Obj) const {
void CertificateEntry::to_json(Poco::JSON::Object &Obj) const { field_to_json(Obj,"id", id);
field_to_json(Obj,"id", id); field_to_json(Obj,"entity", entity);
field_to_json(Obj,"entity", entity); field_to_json(Obj,"creator", creator);
field_to_json(Obj,"creator", creator); field_to_json(Obj,"type", type);
field_to_json(Obj,"type", type); field_to_json(Obj,"status", status);
field_to_json(Obj,"status", status); field_to_json(Obj,"certificate", certificate);
field_to_json(Obj,"certificate", certificate); field_to_json(Obj,"key", key);
field_to_json(Obj,"key", key); field_to_json(Obj,"devid", devid);
field_to_json(Obj,"devid", devid); field_to_json(Obj,"cas", cas);
field_to_json(Obj,"cas", cas); field_to_json(Obj,"manufacturer", manufacturer);
field_to_json(Obj,"manufacturer", manufacturer); field_to_json(Obj,"model", model);
field_to_json(Obj,"model", model); field_to_json(Obj,"redirector", redirector);
field_to_json(Obj,"redirector", redirector); field_to_json(Obj,"commonName", commonName);
field_to_json(Obj,"commonName", commonName); field_to_json(Obj,"certificateId", certificateId);
field_to_json(Obj,"certificateId", certificateId); field_to_json(Obj,"batch", batch);
field_to_json(Obj,"batch", batch); field_to_json(Obj,"created", created);
field_to_json(Obj,"created", created); field_to_json(Obj,"modified", modified);
field_to_json(Obj,"modified", modified); field_to_json(Obj,"revoked", revoked);
field_to_json(Obj,"revoked", revoked); field_to_json(Obj,"revokeCount", revokeCount);
field_to_json(Obj,"revokeCount", revokeCount); field_to_json(Obj,"synched", synched);
} }
bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json(Obj,"id", id); field_from_json(Obj,"id", id);
field_from_json(Obj,"entity", entity); field_from_json(Obj,"entity", entity);
field_from_json(Obj,"creator", creator); field_from_json(Obj,"creator", creator);
field_from_json(Obj,"type", type); field_from_json(Obj,"type", type);
field_from_json(Obj,"status", status); field_from_json(Obj,"status", status);
field_from_json(Obj,"certificate", certificate); field_from_json(Obj,"certificate", certificate);
field_from_json(Obj,"key", key); field_from_json(Obj,"key", key);
field_from_json(Obj,"devid", devid); field_from_json(Obj,"devid", devid);
field_from_json(Obj,"cas", cas); field_from_json(Obj,"cas", cas);
field_from_json(Obj,"manufacturer", manufacturer); field_from_json(Obj,"manufacturer", manufacturer);
field_from_json(Obj,"model", model); field_from_json(Obj,"model", model);
field_from_json(Obj,"redirector", redirector); field_from_json(Obj,"redirector", redirector);
field_from_json(Obj,"commonName", commonName); field_from_json(Obj,"commonName", commonName);
field_from_json(Obj,"certificateId", certificateId); field_from_json(Obj,"certificateId", certificateId);
field_from_json(Obj,"batch", batch); field_from_json(Obj,"batch", batch);
field_from_json(Obj,"created", created); field_from_json(Obj,"created", created);
field_from_json(Obj,"modified", modified); field_from_json(Obj,"modified", modified);
field_from_json(Obj,"revoked", revoked); field_from_json(Obj,"revoked", revoked);
field_from_json(Obj,"revokeCount", revokeCount); field_from_json(Obj,"revokeCount", revokeCount);
return true; field_from_json(Obj,"synched", synched);
} catch (...) { return true;
} } catch (...) {
return false;
} }
return false;
}
void EntityEntry::to_json(Poco::JSON::Object &Obj) const { void EntityEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id); field_to_json(Obj,"id", id);
field_to_json(Obj,"creator", creator); field_to_json(Obj,"creator", creator);
field_to_json(Obj,"name", name); field_to_json(Obj,"name", name);
field_to_json(Obj,"description", description); field_to_json(Obj,"description", description);
field_to_json(Obj,"defaultRedirector", defaultRedirector); field_to_json(Obj,"defaultRedirector", defaultRedirector);
field_to_json(Obj,"apiKey", apiKey); field_to_json(Obj,"apiKey", apiKey);
field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile); field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile); field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
field_to_json(Obj,"organization", organization); field_to_json(Obj,"organization", organization);
field_to_json(Obj,"created", created); field_to_json(Obj,"created", created);
field_to_json(Obj,"modified", modified); field_to_json(Obj,"modified", modified);
field_to_json(Obj,"suspended", suspended); field_to_json(Obj,"suspended", suspended);
field_to_json(Obj,"deleted", deleted); field_to_json(Obj,"deleted", deleted);
field_to_json(Obj,"notes", notes); field_to_json(Obj,"notes", notes);
} }
bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json(Obj,"id", id); field_from_json(Obj,"id", id);
field_from_json(Obj,"creator", creator); field_from_json(Obj,"creator", creator);
field_from_json(Obj,"name", name); field_from_json(Obj,"name", name);
field_from_json(Obj,"description", description); field_from_json(Obj,"description", description);
field_from_json(Obj,"defaultRedirector", defaultRedirector); field_from_json(Obj,"defaultRedirector", defaultRedirector);
field_from_json(Obj,"apiKey", apiKey); field_from_json(Obj,"apiKey", apiKey);
field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile); field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile); field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
field_from_json(Obj,"organization", organization); field_from_json(Obj,"organization", organization);
field_from_json(Obj,"created", created); field_from_json(Obj,"created", created);
field_from_json(Obj,"modified", modified); field_from_json(Obj,"modified", modified);
field_from_json(Obj,"suspended", suspended); field_from_json(Obj,"suspended", suspended);
field_from_json(Obj,"deleted", deleted); field_from_json(Obj,"deleted", deleted);
field_from_json(Obj,"notes", notes); field_from_json(Obj,"notes", notes);
return true; return true;
} catch (...) { } catch (...) {
}
return false;
} }
return false;
}
void BatchEntry::to_json(Poco::JSON::Object &Obj) const { void BatchEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id); field_to_json(Obj,"id", id);
field_to_json(Obj,"entity", entity); field_to_json(Obj,"entity", entity);
field_to_json(Obj,"creator", creator); field_to_json(Obj,"creator", creator);
field_to_json(Obj,"name", name); field_to_json(Obj,"name", name);
field_to_json(Obj,"description", description); field_to_json(Obj,"description", description);
field_to_json(Obj,"manufacturer", manufacturer); field_to_json(Obj,"manufacturer", manufacturer);
field_to_json(Obj,"model", model); field_to_json(Obj,"model", model);
field_to_json(Obj,"redirector", redirector); field_to_json(Obj,"redirector", redirector);
field_to_json(Obj,"commonNames", commonNames); field_to_json(Obj,"commonNames", commonNames);
field_to_json(Obj,"jobHistory", jobHistory); field_to_json(Obj,"jobHistory", jobHistory);
field_to_json(Obj,"notes", notes); field_to_json(Obj,"notes", notes);
field_to_json(Obj,"submitted", submitted); field_to_json(Obj,"submitted", submitted);
field_to_json(Obj,"started", started); field_to_json(Obj,"started", started);
field_to_json(Obj,"completed", completed); field_to_json(Obj,"completed", completed);
field_to_json(Obj,"modified", modified); field_to_json(Obj,"modified", modified);
} }
bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json(Obj,"id", id); field_from_json(Obj,"id", id);
field_from_json(Obj,"entity", entity); field_from_json(Obj,"entity", entity);
field_from_json(Obj,"creator", creator); field_from_json(Obj,"creator", creator);
field_from_json(Obj,"name", name); field_from_json(Obj,"name", name);
field_from_json(Obj,"description", description); field_from_json(Obj,"description", description);
field_from_json(Obj,"manufacturer", manufacturer); field_from_json(Obj,"manufacturer", manufacturer);
field_from_json(Obj,"model", model); field_from_json(Obj,"model", model);
field_from_json(Obj,"redirector", redirector); field_from_json(Obj,"redirector", redirector);
field_from_json(Obj,"commonNames", commonNames); field_from_json(Obj,"commonNames", commonNames);
field_from_json(Obj,"jobHistory", jobHistory); field_from_json(Obj,"jobHistory", jobHistory);
field_from_json(Obj,"notes", notes); field_from_json(Obj,"notes", notes);
field_from_json(Obj,"submitted", submitted); field_from_json(Obj,"submitted", submitted);
field_from_json(Obj,"started", started); field_from_json(Obj,"started", started);
field_from_json(Obj,"completed", completed); field_from_json(Obj,"completed", completed);
field_from_json(Obj,"modified", modified); field_from_json(Obj,"modified", modified);
return true; return true;
} catch (...) { } catch (...) {
}
return false;
} }
return false;
}
void JobEntry::to_json(Poco::JSON::Object &Obj) const { void JobEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id); field_to_json(Obj,"id", id);
field_to_json(Obj,"entity", entity); field_to_json(Obj,"entity", entity);
field_to_json(Obj,"creator", creator); field_to_json(Obj,"creator", creator);
field_to_json(Obj,"batch", batch); field_to_json(Obj,"batch", batch);
field_to_json(Obj,"commonNames", commonNames); field_to_json(Obj,"commonNames", commonNames);
field_to_json(Obj,"completedNames", completedNames); field_to_json(Obj,"completedNames", completedNames);
field_to_json(Obj,"errorNames", errorNames); field_to_json(Obj,"errorNames", errorNames);
field_to_json(Obj,"status", status); field_to_json(Obj,"status", status);
field_to_json(Obj,"command", command); field_to_json(Obj,"command", command);
field_to_json(Obj,"parameters", parameters); field_to_json(Obj,"parameters", parameters);
field_to_json(Obj,"submitted", submitted); field_to_json(Obj,"submitted", submitted);
field_to_json(Obj,"started", started); field_to_json(Obj,"started", started);
field_to_json(Obj,"completed", completed); field_to_json(Obj,"completed", completed);
} }
bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json(Obj,"id", id); field_from_json(Obj,"id", id);
field_from_json(Obj,"entity", entity); field_from_json(Obj,"entity", entity);
field_from_json(Obj,"creator", creator); field_from_json(Obj,"creator", creator);
field_from_json(Obj,"batch", batch); field_from_json(Obj,"batch", batch);
field_from_json(Obj,"commonNames", commonNames); field_from_json(Obj,"commonNames", commonNames);
field_from_json(Obj,"completedNames", completedNames); field_from_json(Obj,"completedNames", completedNames);
field_from_json(Obj,"errorNames", errorNames); field_from_json(Obj,"errorNames", errorNames);
field_from_json(Obj,"status", status); field_from_json(Obj,"status", status);
field_from_json(Obj,"command", command); field_from_json(Obj,"command", command);
field_from_json(Obj,"parameters", parameters); field_from_json(Obj,"parameters", parameters);
field_from_json(Obj,"submitted", submitted); field_from_json(Obj,"submitted", submitted);
field_from_json(Obj,"started", started); field_from_json(Obj,"started", started);
field_from_json(Obj,"completed", completed); field_from_json(Obj,"completed", completed);
return true; return true;
} catch (...) { } catch (...) {
}
return false;
} }
return false;
}
void DashBoardYearlyStats::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "year", year);
field_to_json(Obj, "activeCerts", activeCerts);
field_to_json(Obj, "revokedCerts", revokedCerts);
}
void Dashboard::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"snapshot", snapshot);
field_to_json(Obj,"numberOfIssuedCerts", numberOfIssuedCerts);
field_to_json(Obj,"numberOfRevokedCerts", numberOfRevokedCerts);
field_to_json(Obj,"activeCertsPerOrganization", activeCertsPerOrganization);
field_to_json(Obj,"revokedCertsPerOrganization", revokedCertsPerOrganization);
field_to_json(Obj,"numberOfRedirectors", numberOfRedirectors);
field_to_json(Obj,"deviceTypes", deviceTypes);
field_to_json(Obj,"monthlyNumberOfCerts", monthlyNumberOfCerts);
field_to_json(Obj,"monthlyNumberOfCertsPerOrgPerYear", monthlyNumberOfCertsPerOrgPerYear);
}
void Dashboard::reset() {
snapshot=0;
numberOfRevokedCerts = numberOfIssuedCerts = 0;
activeCertsPerOrganization.clear();
revokedCertsPerOrganization.clear();
numberOfRedirectors.clear();
deviceTypes.clear();
monthlyNumberOfCerts.clear();
monthlyNumberOfCertsPerOrgPerYear.clear();
} }
} }

View File

@@ -5,97 +5,118 @@
#pragma once #pragma once
#include <string> #include <string>
#include "framework/MicroService.h"
#include "framework/OpenWifiTypes.h" #include "framework/OpenWifiTypes.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h" #include "RESTObjects/RESTAPI_SecurityObjects.h"
namespace OpenWifi { namespace OpenWifi::CertObjects {
namespace CertObjects { struct CertificateEntry {
OpenWifi::Types::UUID_t id;
OpenWifi::Types::UUID_t entity;
OpenWifi::Types::UUID_t creator;
std::string type;
std::string status;
std::string certificate;
std::string key;
std::string devid;
std::string cas;
std::string manufacturer;
std::string model;
std::string redirector;
std::string commonName;
std::string certificateId;
OpenWifi::Types::UUID_t batch;
uint64_t created = 0;
uint64_t modified = 0;
uint64_t revoked = 0;
uint64_t revokeCount = 0;
uint64_t synched = 0;
struct CertificateEntry { void to_json(Poco::JSON::Object &Obj) const;
OpenWifi::Types::UUID_t id; bool from_json(const Poco::JSON::Object::Ptr &Obj);
OpenWifi::Types::UUID_t entity; };
OpenWifi::Types::UUID_t creator;
std::string type;
std::string status;
std::string certificate;
std::string key;
std::string devid;
std::string cas;
std::string manufacturer;
std::string model;
std::string redirector;
std::string commonName;
std::string certificateId;
OpenWifi::Types::UUID_t batch;
uint64_t created = 0;
uint64_t modified = 0;
uint64_t revoked = 0;
uint64_t revokeCount = 0;
void to_json(Poco::JSON::Object &Obj) const; struct EntityEntry {
bool from_json(const Poco::JSON::Object::Ptr &Obj); OpenWifi::Types::UUID_t id;
}; OpenWifi::Types::UUID_t creator;
std::string name;
std::string description;
std::string defaultRedirector;
std::string apiKey;
std::string serverEnrollmentProfile;
std::string clientEnrollmentProfile;
std::string organization;
SecurityObjects::NoteInfoVec notes;
bool suspended=false;
bool deleted=false;
uint64_t created = 0 ;
uint64_t modified = 0 ;
struct EntityEntry { void to_json(Poco::JSON::Object &Obj) const;
OpenWifi::Types::UUID_t id; bool from_json(const Poco::JSON::Object::Ptr &Obj);
OpenWifi::Types::UUID_t creator; };
std::string name;
std::string description;
std::string defaultRedirector;
std::string apiKey;
std::string serverEnrollmentProfile;
std::string clientEnrollmentProfile;
std::string organization;
SecurityObjects::NoteInfoVec notes;
bool suspended=false;
bool deleted=false;
uint64_t created = 0 ;
uint64_t modified = 0 ;
void to_json(Poco::JSON::Object &Obj) const; struct BatchEntry {
bool from_json(const Poco::JSON::Object::Ptr &Obj); OpenWifi::Types::UUID_t id;
}; OpenWifi::Types::UUID_t entity;
OpenWifi::Types::UUID_t creator;
std::string name;
std::string description;
std::string manufacturer;
std::string model;
std::string redirector;
std::vector<std::string> commonNames;
std::vector<std::string> jobHistory;
SecurityObjects::NoteInfoVec notes;
uint64_t submitted = 0 ;
uint64_t started = 0 ;
uint64_t completed = 0 ;
uint64_t modified = 0 ;
struct BatchEntry { void to_json(Poco::JSON::Object &Obj) const;
OpenWifi::Types::UUID_t id; bool from_json(const Poco::JSON::Object::Ptr &Obj);
OpenWifi::Types::UUID_t entity; };
OpenWifi::Types::UUID_t creator;
std::string name;
std::string description;
std::string manufacturer;
std::string model;
std::string redirector;
std::vector<std::string> commonNames;
std::vector<std::string> jobHistory;
SecurityObjects::NoteInfoVec notes;
uint64_t submitted = 0 ;
uint64_t started = 0 ;
uint64_t completed = 0 ;
uint64_t modified = 0 ;
void to_json(Poco::JSON::Object &Obj) const; struct JobEntry {
bool from_json(const Poco::JSON::Object::Ptr &Obj); OpenWifi::Types::UUID_t id;
}; OpenWifi::Types::UUID_t entity;
OpenWifi::Types::UUID_t creator;
OpenWifi::Types::UUID_t batch;
std::string command;
OpenWifi::Types::StringVec commonNames;
OpenWifi::Types::StringVec completedNames;
OpenWifi::Types::StringVec errorNames;
Types::StringPairVec parameters;
std::string status;
uint64_t submitted=0;
uint64_t started=0;
uint64_t completed=0;
struct JobEntry { void to_json(Poco::JSON::Object &Obj) const;
OpenWifi::Types::UUID_t id; bool from_json(const Poco::JSON::Object::Ptr &Obj);
OpenWifi::Types::UUID_t entity; };
OpenWifi::Types::UUID_t creator;
OpenWifi::Types::UUID_t batch; struct DashBoardYearlyStats {
std::string command; uint64_t year=0;
OpenWifi::Types::StringVec commonNames; OpenWifi::Types::Counted3DMapSII activeCerts;
OpenWifi::Types::StringVec completedNames; OpenWifi::Types::Counted3DMapSII revokedCerts;
OpenWifi::Types::StringVec errorNames;
Types::StringPairVec parameters; void to_json(Poco::JSON::Object &Obj) const;
std::string status; };
uint64_t submitted=0;
uint64_t started=0; struct Dashboard {
uint64_t completed=0; uint64_t snapshot=0;
uint64_t numberOfIssuedCerts=0;
uint64_t numberOfRevokedCerts=0;
OpenWifi::Types::CountedMap activeCertsPerOrganization;
OpenWifi::Types::CountedMap revokedCertsPerOrganization;
OpenWifi::Types::CountedMap numberOfRedirectors;
OpenWifi::Types::CountedMap deviceTypes;
OpenWifi::Types::CountedMap monthlyNumberOfCerts;
std::vector<DashBoardYearlyStats> monthlyNumberOfCertsPerOrgPerYear;
void to_json(Poco::JSON::Object &Obj) const;
void reset();
};
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
}
} }

View File

@@ -9,6 +9,7 @@
#pragma once #pragma once
#include <string> #include <string>
#include <type_traits>
#include "framework/OpenWifiTypes.h" #include "framework/OpenWifiTypes.h"
#include "Poco/JSON/Object.h" #include "Poco/JSON/Object.h"
#include "Poco/Data/LOB.h" #include "Poco/Data/LOB.h"
@@ -27,8 +28,13 @@ namespace OpenWifi {
bool Delete_ = true; bool Delete_ = true;
bool PortalLogin_ = true; bool PortalLogin_ = true;
AclTemplate() noexcept = default;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj); }; bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
static_assert( std::is_nothrow_move_constructible_v<AclTemplate> );
struct WebToken { struct WebToken {
std::string access_token_; std::string access_token_;

View File

@@ -45,6 +45,8 @@ namespace OpenWifi {
bool SMSSender::StartValidation(const std::string &Number, const std::string &UserName) { bool SMSSender::StartValidation(const std::string &Number, const std::string &UserName) {
std::lock_guard G(Mutex_); std::lock_guard G(Mutex_);
if(!Enabled_)
return false;
CleanCache(); CleanCache();
uint64_t Now=OpenWifi::Now(); uint64_t Now=OpenWifi::Now();
auto Challenge = MFAServer::MakeChallenge(); auto Challenge = MFAServer::MakeChallenge();
@@ -56,6 +58,9 @@ namespace OpenWifi {
bool SMSSender::IsNumberValid(const std::string &Number, const std::string &UserName) { bool SMSSender::IsNumberValid(const std::string &Number, const std::string &UserName) {
std::lock_guard G(Mutex_); std::lock_guard G(Mutex_);
if(!Enabled_)
return false;
for(const auto &i:Cache_) { for(const auto &i:Cache_) {
if(i.Number==Number && i.UserName==UserName) if(i.Number==Number && i.UserName==UserName)
return i.Validated; return i.Validated;
@@ -66,6 +71,9 @@ namespace OpenWifi {
bool SMSSender::CompleteValidation(const std::string &Number, const std::string &Code, const std::string &UserName) { bool SMSSender::CompleteValidation(const std::string &Number, const std::string &Code, const std::string &UserName) {
std::lock_guard G(Mutex_); std::lock_guard G(Mutex_);
if(!Enabled_)
return false;
for(auto &i:Cache_) { for(auto &i:Cache_) {
if(i.Code==Code && i.Number==Number && i.UserName==UserName) { if(i.Code==Code && i.Number==Number && i.UserName==UserName) {
i.Validated=true; i.Validated=true;

View File

@@ -65,7 +65,7 @@ namespace OpenWifi {
void SMTPMailerService::run() { void SMTPMailerService::run() {
Running_ = true; Running_ = true;
Utils::SetThreadName("smtp-mailer");
while(Running_) { while(Running_) {
Poco::Thread::trySleep(10000); Poco::Thread::trySleep(10000);

View File

@@ -63,6 +63,7 @@ namespace OpenWifi {
} }
void Archiver::onTimer([[maybe_unused]] Poco::Timer &timer) { void Archiver::onTimer([[maybe_unused]] Poco::Timer &timer) {
Utils::SetThreadName("archiver");
Poco::Logger &logger = Poco::Logger::get("STORAGE-ARCHIVER"); Poco::Logger &logger = Poco::Logger::get("STORAGE-ARCHIVER");
logger.information("Squiggy the DB: removing old tokens."); logger.information("Squiggy the DB: removing old tokens.");
StorageService()->SubTokenDB().CleanExpiredTokens(); StorageService()->SubTokenDB().CleanExpiredTokens();

View File

@@ -41,7 +41,6 @@ namespace OpenWifi {
} }
std::string GenerateQRCode(const std::string &Secret, const std::string &email) { std::string GenerateQRCode(const std::string &Secret, const std::string &email) {
std::string uri{ std::string uri{
"otpauth://totp/" + Issuer_ + ":" + "otpauth://totp/" + Issuer_ + ":" +
email + "?secret=" + Secret + "&issuer=" + Issuer_ email + "?secret=" + Secret + "&issuer=" + Issuer_
@@ -55,10 +54,10 @@ namespace OpenWifi {
static bool ValidateCode( const std::string &Secret, const std::string &Code, std::string & Expecting) { static bool ValidateCode( const std::string &Secret, const std::string &Code, std::string & Expecting) {
uint64_t Now = OpenWifi::Now(); uint64_t Now = OpenWifi::Now();
uint32_t p = CppTotp::totp(CppTotp::Bytes::ByteString{ (const u_char *)Secret.c_str()}, Now, 0, 30, 6); uint32_t p = CppTotp::totp(CppTotp::Bytes::ByteString{ (const u_char *)Secret.c_str()}, Now, 0, 30, 6);
char buffer[16]; char buffer[16]{0};
sprintf(buffer,"%06u",p); sprintf(buffer,"%06u",p);
Expecting = buffer; Expecting = std::string(buffer);
return Code == buffer; return Code == Expecting;
} }
int Start() override { int Start() override {
@@ -92,26 +91,13 @@ namespace OpenWifi {
auto Secret = GenerateSecret(20, Base32Secret); auto Secret = GenerateSecret(20, Base32Secret);
QRCode = GenerateQRCode(Base32Secret, User.email); QRCode = GenerateQRCode(Base32Secret, User.email);
/*
struct Entry {
bool Subscriber=false;
uint64_t Start = 0;
uint64_t Done = 0 ;
uint64_t Verifications = 0 ;
std::string Secret;
std::string QRCode;
std::string LastCode;
};
*/
Entry E{ .Subscriber = Subscriber, Entry E{ .Subscriber = Subscriber,
.Start = OpenWifi::Now(), .Start = OpenWifi::Now(),
.Done = 0, .Done = 0,
.Verifications = 0, .Verifications = 0,
.Secret = Secret, .Secret = Secret,
.QRCode = QRCode, .QRCode = QRCode,
.LastCode = 0 .LastCode = ""
}; };
Cache_[User.id] = E; Cache_[User.id] = E;
return true; return true;

View File

@@ -13,9 +13,10 @@
namespace OpenWifi { namespace OpenWifi {
static const std::string GitUCentralJSONSchemaFile{"https://raw.githubusercontent.com/blogic/ucentral-schema/main/ucentral.schema.json"}; static const std::string GitUCentralJSONSchemaFile{
"https://raw.githubusercontent.com/blogic/ucentral-schema/main/ucentral.schema.json"};
static json DefaultUCentralSchema = R"( static json DefaultUCentralSchema = R"(
{ {
"$id": "https://openwrt.org/ucentral.schema.json", "$id": "https://openwrt.org/ucentral.schema.json",
@@ -518,7 +519,7 @@ namespace OpenWifi {
"maximum": 4050 "maximum": 4050
}, },
"proto": { "proto": {
"decription": "The L2 vlan tag that shall be added (1q,1ad) ", "decription": "The L2 vlan tag that shall be added (1q,1ad ) ",
"type": "string", "type": "string",
"enum": [ "enum": [
"802.1ad", "802.1ad",
@@ -669,6 +670,47 @@ namespace OpenWifi {
} }
} }
}, },
"interface.ipv4.port-forward": {
"type": "object",
"properties": {
"protocol": {
"type": "string",
"enum": [
"tcp",
"udp",
"any"
],
"default": "any"
},
"external-port": {
"type": [
"integer",
"string"
],
"minimum": 0,
"maximum": 65535,
"format": "uc-portrange"
},
"internal-address": {
"type": "string",
"format": "ipv4",
"example": "0.0.0.120"
},
"internal-port": {
"type": [
"integer",
"string"
],
"minimum": 0,
"maximum": 65535,
"format": "uc-portrange"
}
},
"required": [
"external-port",
"internal-address"
]
},
"interface.ipv4": { "interface.ipv4": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -722,6 +764,12 @@ namespace OpenWifi {
"items": { "items": {
"$ref": "#/$defs/interface.ipv4.dhcp-lease" "$ref": "#/$defs/interface.ipv4.dhcp-lease"
} }
},
"port-forward": {
"type": "array",
"items": {
"$ref": "#/$defs/interface.ipv4.port-forward"
}
} }
} }
}, },
@@ -751,6 +799,96 @@ namespace OpenWifi {
} }
} }
}, },
"interface.ipv6.port-forward": {
"type": "object",
"properties": {
"protocol": {
"type": "string",
"enum": [
"tcp",
"udp",
"any"
],
"default": "any"
},
"external-port": {
"type": [
"integer",
"string"
],
"minimum": 0,
"maximum": 65535,
"format": "uc-portrange"
},
"internal-address": {
"type": "string",
"format": "ipv6",
"example": "::1234:abcd"
},
"internal-port": {
"type": [
"integer",
"string"
],
"minimum": 0,
"maximum": 65535,
"format": "uc-portrange"
}
},
"required": [
"external-port",
"internal-address"
]
},
"interface.ipv6.traffic-allow": {
"type": "object",
"properties": {
"protocol": {
"type": "string",
"default": "any"
},
"source-address": {
"type": "string",
"format": "uc-cidr6",
"example": "2001:db8:1234:abcd::/64",
"default": "::/0"
},
"source-ports": {
"type": "array",
"minItems": 1,
"items": {
"type": [
"integer",
"string"
],
"minimum": 0,
"maximum": 65535,
"format": "uc-portrange"
}
},
"destination-address": {
"type": "string",
"format": "ipv6",
"example": "::1000"
},
"destination-ports": {
"type": "array",
"minItems": 1,
"items": {
"type": [
"integer",
"string"
],
"minimum": 0,
"maximum": 65535,
"format": "uc-portrange"
}
}
},
"required": [
"destination-address"
]
},
"interface.ipv6": { "interface.ipv6": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -782,6 +920,18 @@ namespace OpenWifi {
}, },
"dhcpv6": { "dhcpv6": {
"$ref": "#/$defs/interface.ipv6.dhcpv6" "$ref": "#/$defs/interface.ipv6.dhcpv6"
},
"port-forward": {
"type": "array",
"items": {
"$ref": "#/$defs/interface.ipv6.port-forward"
}
},
"traffic-allow": {
"type": "array",
"items": {
"$ref": "#/$defs/interface.ipv6.traffic-allow"
}
} }
} }
}, },
@@ -866,7 +1016,7 @@ namespace OpenWifi {
}, },
"gateway-fqdn": { "gateway-fqdn": {
"type": "string", "type": "string",
"format": "fqdn", "format": "uc-fqdn",
"default": "ucentral.splash" "default": "ucentral.splash"
}, },
"max-clients": { "max-clients": {
@@ -901,6 +1051,7 @@ namespace OpenWifi {
"psk", "psk",
"psk2", "psk2",
"psk-mixed", "psk-mixed",
"psk2-radius",
"wpa", "wpa",
"wpa2", "wpa2",
"wpa-mixed", "wpa-mixed",
@@ -961,6 +1112,10 @@ namespace OpenWifi {
"type": "boolean", "type": "boolean",
"default": false "default": false
}, },
"reduced-neighbor-reporting": {
"type": "boolean",
"default": false
},
"lci": { "lci": {
"type": "string" "type": "string"
}, },
@@ -1527,6 +1682,11 @@ namespace OpenWifi {
"decription": "This option allows embedding custom vendor specific IEs inside the beacons of a BSS in AP mode.", "decription": "This option allows embedding custom vendor specific IEs inside the beacons of a BSS in AP mode.",
"type": "string" "type": "string"
}, },
"fils-discovery-interval": {
"type": "integer",
"default": 20,
"maximum": 10000
},
"encryption": { "encryption": {
"$ref": "#/$defs/interface.ssid.encryption" "$ref": "#/$defs/interface.ssid.encryption"
}, },
@@ -2087,6 +2247,10 @@ namespace OpenWifi {
"auto-channel": { "auto-channel": {
"type": "boolean", "type": "boolean",
"default": false "default": false
},
"ipv6": {
"type": "boolean",
"default": false
} }
} }
}, },
@@ -2193,7 +2357,7 @@ namespace OpenWifi {
"properties": { "properties": {
"fqdn": { "fqdn": {
"type": "string", "type": "string",
"format": "fqdn" "format": "uc-fqdn"
}, },
"suffix-matching": { "suffix-matching": {
"type": "boolean", "type": "boolean",
@@ -2444,8 +2608,7 @@ namespace OpenWifi {
} }
} }
} }
)"_json;
)"_json;
class custom_error_handler : public nlohmann::json_schema::basic_error_handler class custom_error_handler : public nlohmann::json_schema::basic_error_handler
{ {
@@ -2460,9 +2623,18 @@ namespace OpenWifi {
void ConfigurationValidator::Init() { void ConfigurationValidator::Init() {
if(Initialized_) if(Initialized_)
return; return;
std::string GitSchema; std::string GitSchema;
if(MicroService::instance().ConfigGetBool("ucentral.datamodel.internal",true)) {
RootSchema_ = DefaultUCentralSchema;
Logger().information("Using uCentral validation from built-in default.");
Initialized_ = Working_ = true;
return;
}
try { try {
if(Utils::wgets(GitUCentralJSONSchemaFile, GitSchema)) { auto GitURI = MicroService::instance().ConfigGetString("ucentral.datamodel.uri",GitUCentralJSONSchemaFile);
if(Utils::wgets(GitURI, GitSchema)) {
RootSchema_ = json::parse(GitSchema); RootSchema_ = json::parse(GitSchema);
Logger().information("Using uCentral validation schema from GIT."); Logger().information("Using uCentral validation schema from GIT.");
} else { } else {
@@ -2528,6 +2700,17 @@ namespace OpenWifi {
return IsCIDRv4(value) || IsCIDRv6(value); return IsCIDRv4(value) || IsCIDRv6(value);
} }
static inline bool IsPortRangeIsValid(const std::string &r) {
const auto ports = Poco::StringTokenizer("-",r,Poco::StringTokenizer::TOK_TRIM);
for(const auto &port:ports) {
uint32_t port_num = std::stoul(port);
if(port_num==0 || port_num>65535)
return false;
}
return true;
}
void ConfigurationValidator::my_format_checker(const std::string &format, const std::string &value) void ConfigurationValidator::my_format_checker(const std::string &format, const std::string &value)
{ {
static const std::regex host_regex{"^(?=.{1,254}$)((?=[a-z0-9-]{1,63}\\.)(xn--+)?[a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,63}$"}; static const std::regex host_regex{"^(?=.{1,254}$)((?=[a-z0-9-]{1,63}\\.)(xn--+)?[a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,63}$"};
@@ -2578,6 +2761,14 @@ namespace OpenWifi {
} catch (...) { } catch (...) {
} }
throw std::invalid_argument(value + " is not a valid URI: should be something like https://hello.world.com."); throw std::invalid_argument(value + " is not a valid URI: should be something like https://hello.world.com.");
} else if(format == "uc-portrange") {
try {
if(IsPortRangeIsValid(value))
return;
throw std::invalid_argument(value + " is not a valid port range: should an integer between 1-65535 or a port range like post-port.");
} catch (...) {
}
throw std::invalid_argument(value + " is not a valid port range: should an integer between 1-65535 or a port range like post-port.");
} else if(format == "ip") { } else if(format == "ip") {
if (IsIP(value)) if (IsIP(value))
return; return;

View File

@@ -27,6 +27,11 @@ namespace OpenWifi {
inline uint64_t Now() { return std::time(nullptr); }; inline uint64_t Now() { return std::time(nullptr); };
} }
namespace OpenWifi::Utils {
std::vector<unsigned char> base64decode(const std::string& input);
std::string base64encode(const unsigned char *input, uint32_t size);
}
using namespace std::chrono_literals; using namespace std::chrono_literals;
#include "Poco/Util/Application.h" #include "Poco/Util/Application.h"
@@ -238,6 +243,11 @@ namespace OpenWifi::RESTAPI_utils {
Obj.set(Field,Value); Obj.set(Field,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; Poco::JSON::Array Array;
for(const auto &i:S) { for(const auto &i:S) {
@@ -334,12 +344,12 @@ namespace OpenWifi::RESTAPI_utils {
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)) if(Obj->has(Field) && !Obj->isNull(Field))
Value = (double) Obj->get(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)) if(Obj->has(Field) && !Obj->isNull(Field))
Value = (float) Obj->get(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) {
@@ -374,7 +384,14 @@ namespace OpenWifi::RESTAPI_utils {
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)) if(Obj->has(Field) && !Obj->isNull(Field))
Value = (uint64_t ) Obj->get(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) {
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) {
@@ -643,6 +660,27 @@ namespace OpenWifi::RESTAPI_utils {
namespace OpenWifi::Utils { namespace OpenWifi::Utils {
inline void SetThreadName(const char *name) {
#ifdef __linux__
Poco::Thread::current()->setName(name);
pthread_setname_np(pthread_self(), name);
#endif
#ifdef __APPLE__
Poco::Thread::current()->setName(name);
pthread_setname_np(name);
#endif
}
inline void SetThreadName(Poco::Thread &thr, const char *name) {
#ifdef __linux__
thr.setName(name);
pthread_setname_np(thr.tid(), name);
#endif
#ifdef __APPLE__
thr.setName(name);
#endif
}
enum MediaTypeEncodings { enum MediaTypeEncodings {
PLAIN, PLAIN,
BINARY, BINARY,
@@ -1167,6 +1205,7 @@ namespace OpenWifi {
static const std::string uSERVICE_SUBCRIBER{ "owsub"}; static const std::string uSERVICE_SUBCRIBER{ "owsub"};
static const std::string uSERVICE_INSTALLER{ "owinst"}; static const std::string uSERVICE_INSTALLER{ "owinst"};
static const std::string uSERVICE_ANALYTICS{ "owanalytics"}; static const std::string uSERVICE_ANALYTICS{ "owanalytics"};
static const std::string uSERVICE_OWRRM{ "owrrm"};
class ConfigurationEntry { class ConfigurationEntry {
public: public:
@@ -1315,7 +1354,7 @@ namespace OpenWifi {
inline void Start(); inline void Start();
inline void Stop(); inline void Stop();
private: private:
std::atomic_bool Running_ = false; mutable std::atomic_bool Running_ = false;
Poco::Thread Thread_; Poco::Thread Thread_;
}; };
@@ -1846,7 +1885,8 @@ namespace OpenWifi {
Request = &RequestIn; Request = &RequestIn;
Response = &ResponseIn; Response = &ResponseIn;
Poco::Thread::current()->setName("WebServerThread_" + std::to_string(TransactionId_)); std::string th_name = "restsvr_" + std::to_string(TransactionId_);
Utils::SetThreadName(th_name.c_str());
if(Request->getContentLength()>0) { if(Request->getContentLength()>0) {
if(Request->getContentType().find("application/json")!=std::string::npos) { if(Request->getContentType().find("application/json")!=std::string::npos) {
@@ -1895,36 +1935,32 @@ namespace OpenWifi {
[[nodiscard]] inline bool NeedAdditionalInfo() const { return QB_.AdditionalInfo; } [[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; }
/* [[nodiscard]] inline const Poco::JSON::Object::Ptr ParseStream() { inline static bool ParseBindings(const std::string & Request, const std::list<std::string> & EndPoints, BindingMap &bindings) {
return IncomingParser_.parse(Request->stream()).extract<Poco::JSON::Object::Ptr>(); bindings.clear();
} auto PathItems = Poco::StringTokenizer(Request, "/");
*/
inline static bool ParseBindings(const std::string & Request, const std::list<std::string> & EndPoints, BindingMap &bindings) { for(const auto &EndPoint:EndPoints) {
bindings.clear(); auto ParamItems = Poco::StringTokenizer(EndPoint, "/");
std::vector<std::string> PathItems = Utils::Split(Request, '/'); if (PathItems.count() != ParamItems.count())
continue;
for(const auto &EndPoint:EndPoints) { bool Matched = true;
std::vector<std::string> ParamItems = Utils::Split(EndPoint, '/'); for (size_t i = 0; i < PathItems.count(); i++) {
if (PathItems.size() != ParamItems.size()) if (PathItems[i] != ParamItems[i]) {
continue; if (ParamItems[i][0] == '{') {
auto ParamName = ParamItems[i].substr(1, ParamItems[i].size() - 2);
bool Matched = true; bindings[Poco::toLower(ParamName)] = PathItems[i];
for (size_t i = 0; i != PathItems.size() && Matched; i++) { } else {
if (PathItems[i] != ParamItems[i]) { Matched = false;
if (ParamItems[i][0] == '{') { break;
auto ParamName = ParamItems[i].substr(1, ParamItems[i].size() - 2); }
bindings[Poco::toLower(ParamName)] = PathItems[i]; }
} else { }
Matched = false; if(Matched)
} return true;
} }
} return false;
if(Matched) }
return true;
}
return false;
}
inline void PrintBindings() { inline void PrintBindings() {
for (const auto &[key, value] : Bindings_) for (const auto &[key, value] : Bindings_)
@@ -2045,6 +2081,17 @@ namespace OpenWifi {
return false; return false;
} }
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);
Value.assignRaw((const unsigned char *)&DecodedBlob[0],DecodedBlob.size());
return true;
}
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)) { if(O->has(Field)) {
assignee = value; assignee = value;
@@ -2582,7 +2629,7 @@ namespace OpenWifi {
private: private:
std::recursive_mutex Mutex_; std::recursive_mutex Mutex_;
Poco::Thread Worker_; Poco::Thread Worker_;
std::atomic_bool Running_=false; mutable std::atomic_bool Running_=false;
Poco::NotificationQueue Queue_; Poco::NotificationQueue Queue_;
}; };
@@ -2608,7 +2655,7 @@ namespace OpenWifi {
private: private:
std::recursive_mutex Mutex_; std::recursive_mutex Mutex_;
Poco::Thread Worker_; Poco::Thread Worker_;
std::atomic_bool Running_=false; mutable std::atomic_bool Running_=false;
}; };
class KafkaDispatcher : public Poco::Runnable { class KafkaDispatcher : public Poco::Runnable {
@@ -2665,6 +2712,7 @@ namespace OpenWifi {
inline void run() override { inline void run() override {
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification()); Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
Utils::SetThreadName("kafka-dispatch");
while(Note && Running_) { while(Note && Running_) {
auto Msg = dynamic_cast<KafkaMessage*>(Note.get()); auto Msg = dynamic_cast<KafkaMessage*>(Note.get());
if(Msg!= nullptr) { if(Msg!= nullptr) {
@@ -2690,7 +2738,7 @@ namespace OpenWifi {
std::recursive_mutex Mutex_; std::recursive_mutex Mutex_;
Types::NotifyTable Notifiers_; Types::NotifyTable Notifiers_;
Poco::Thread Worker_; Poco::Thread Worker_;
std::atomic_bool Running_=false; mutable std::atomic_bool Running_=false;
uint64_t FunctionId_=1; uint64_t FunctionId_=1;
Poco::NotificationQueue Queue_; Poco::NotificationQueue Queue_;
}; };
@@ -2885,6 +2933,7 @@ namespace OpenWifi {
void handleRequest(Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override void handleRequest(Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override
{ {
Utils::SetThreadName("alb-request");
try { try {
if((id_ % 100) == 0) { if((id_ % 100) == 0) {
Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.", Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.",
@@ -2953,7 +3002,7 @@ namespace OpenWifi {
std::unique_ptr<Poco::Net::HTTPServer> Server_; std::unique_ptr<Poco::Net::HTTPServer> Server_;
std::unique_ptr<Poco::Net::ServerSocket> Socket_; std::unique_ptr<Poco::Net::ServerSocket> Socket_;
int Port_ = 0; int Port_ = 0;
std::atomic_bool Running_=false; mutable std::atomic_bool Running_=false;
}; };
inline auto ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); } inline auto ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); }
@@ -2985,7 +3034,7 @@ namespace OpenWifi {
inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) { inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) {
RESTAPIHandler::BindingMap Bindings; RESTAPIHandler::BindingMap Bindings;
Poco::Thread::current()->setName(fmt::format("RESTAPI_ExtServer_{}",Id)); Utils::SetThreadName(fmt::format("rest_ext_{}",Id).c_str());
return RESTAPI_ExtRouter(Path, Bindings, Logger(), Server_, Id); return RESTAPI_ExtRouter(Path, Bindings, Logger(), Server_, Id);
} }
@@ -3009,7 +3058,7 @@ namespace OpenWifi {
inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override { inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override {
try { try {
Poco::URI uri(Request.getURI()); Poco::URI uri(Request.getURI());
Poco::Thread::current()->setName(fmt::format("ExtWebServer_{}",TransactionId_)); Utils::SetThreadName(fmt::format("rest_ext_{}",TransactionId_).c_str());
return RESTAPI_ExtServer()->CallServer(uri.getPath(), TransactionId_++); return RESTAPI_ExtServer()->CallServer(uri.getPath(), TransactionId_++);
} catch (...) { } catch (...) {
@@ -3118,7 +3167,7 @@ namespace OpenWifi {
inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) { inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) {
RESTAPIHandler::BindingMap Bindings; RESTAPIHandler::BindingMap Bindings;
Poco::Thread::current()->setName(fmt::format("RESTAPI_IntServer_{}",Id)); Utils::SetThreadName(fmt::format("rest_int_{}",Id).c_str());
return RESTAPI_IntRouter(Path, Bindings, Logger(), Server_, Id); return RESTAPI_IntRouter(Path, Bindings, Logger(), Server_, Id);
} }
private: private:
@@ -3527,7 +3576,9 @@ namespace OpenWifi {
void DaemonPostInitialization(Poco::Util::Application &self); void DaemonPostInitialization(Poco::Util::Application &self);
inline void MicroService::initialize(Poco::Util::Application &self) { inline void MicroService::initialize(Poco::Util::Application &self) {
// add the default services // Utils::SetThreadName("microservice");
// add the default services
LoadConfigurationFile(); LoadConfigurationFile();
InitializeLoggingSystem(); InitializeLoggingSystem();
@@ -3922,6 +3973,7 @@ namespace OpenWifi {
inline int MicroService::main([[maybe_unused]] const ArgVec &args) { inline int MicroService::main([[maybe_unused]] const ArgVec &args) {
// Utils::SetThreadName("main");
MyErrorHandler ErrorHandler(*this); MyErrorHandler ErrorHandler(*this);
Poco::ErrorHandler::set(&ErrorHandler); Poco::ErrorHandler::set(&ErrorHandler);
@@ -4037,6 +4089,7 @@ namespace OpenWifi {
inline void BusEventManager::run() { inline void BusEventManager::run() {
Running_ = true; Running_ = true;
Utils::SetThreadName("BusEventManager");
auto Msg = MicroService::instance().MakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN); auto Msg = MicroService::instance().MakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN);
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroService::instance().PrivateEndPoint(),Msg, false); KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroService::instance().PrivateEndPoint(),Msg, false);
while(Running_) { while(Running_) {
@@ -4122,6 +4175,8 @@ namespace OpenWifi {
} }
inline void KafkaProducer::run() { inline void KafkaProducer::run() {
Utils::SetThreadName("KafkaProducer");
cppkafka::Configuration Config({ cppkafka::Configuration Config({
{ "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") }, { "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
{ "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") } { "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") }
@@ -4160,6 +4215,8 @@ namespace OpenWifi {
} }
inline void KafkaConsumer::run() { inline void KafkaConsumer::run() {
Utils::SetThreadName("KafkaConsumer");
cppkafka::Configuration Config({ cppkafka::Configuration Config({
{ "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") }, { "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
{ "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") }, { "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") },
@@ -4400,7 +4457,7 @@ namespace OpenWifi {
Path, Path,
Poco::Net::HTTPMessage::HTTP_1_1); Poco::Net::HTTPMessage::HTTP_1_1);
Poco::Logger::get("REST-CALLER-GET").debug(fmt::format(" {}", URI.toString())); poco_debug(Poco::Logger::get("REST-CALLER-GET"),fmt::format(" {}", URI.toString()));
if(BearerToken.empty()) { if(BearerToken.empty()) {
Request.add("X-API-KEY", Svc.AccessKey); Request.add("X-API-KEY", Svc.AccessKey);
@@ -4458,7 +4515,7 @@ namespace OpenWifi {
for (const auto &qp : QueryData_) for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second); URI.addQueryParameter(qp.first, qp.second);
Poco::Logger::get("REST-CALLER-PUT").debug(fmt::format("{}", URI.toString())); poco_debug(Poco::Logger::get("REST-CALLER-PUT"),fmt::format("{}", URI.toString()));
std::string Path(URI.getPathAndQuery()); std::string Path(URI.getPathAndQuery());
@@ -4537,7 +4594,7 @@ namespace OpenWifi {
for (const auto &qp : QueryData_) for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second); URI.addQueryParameter(qp.first, qp.second);
Poco::Logger::get("REST-CALLER-POST").debug(fmt::format(" {}", URI.toString())); poco_debug(Poco::Logger::get("REST-CALLER-POST"),fmt::format(" {}", URI.toString()));
std::string Path(URI.getPathAndQuery()); std::string Path(URI.getPathAndQuery());
@@ -4613,7 +4670,7 @@ namespace OpenWifi {
for (const auto &qp : QueryData_) for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second); URI.addQueryParameter(qp.first, qp.second);
Poco::Logger::get("REST-CALLER-DELETE").debug(fmt::format(" {}", URI.toString())); poco_debug(Poco::Logger::get("REST-CALLER-DELETE"),fmt::format(" {}", URI.toString()));
std::string Path(URI.getPathAndQuery()); std::string Path(URI.getPathAndQuery());
@@ -4818,7 +4875,7 @@ namespace OpenWifi {
[[nodiscard]] bool SendToUser(const std::string &userName, const std::string &Payload); [[nodiscard]] bool SendToUser(const std::string &userName, const std::string &Payload);
void SendToAll(const std::string &Payload); void SendToAll(const std::string &Payload);
private: private:
std::atomic_bool Running_ = false; mutable std::atomic_bool Running_ = false;
Poco::Thread Thr_; Poco::Thread Thr_;
// std::unique_ptr<MyParallelSocketReactor> ReactorPool_; // std::unique_ptr<MyParallelSocketReactor> ReactorPool_;
Poco::Net::SocketReactor Reactor_; Poco::Net::SocketReactor Reactor_;
@@ -4915,6 +4972,7 @@ namespace OpenWifi {
inline void WebSocketClientServer::run() { inline void WebSocketClientServer::run() {
Running_ = true ; Running_ = true ;
Utils::SetThreadName("ws:clnt-svr");
while(Running_) { while(Running_) {
Poco::Thread::trySleep(2000); Poco::Thread::trySleep(2000);
@@ -4962,8 +5020,12 @@ namespace OpenWifi {
for(const auto &client:Clients_) { for(const auto &client:Clients_) {
if(client.second.second == UserName) { if(client.second.second == UserName) {
if(client.second.first->Send(Payload)) try {
Sent++; if (client.second.first->Send(Payload))
Sent++;
} catch (...) {
return false;
}
} }
} }
return Sent>0; return Sent>0;
@@ -4985,70 +5047,70 @@ namespace OpenWifi {
int flags; int flags;
int n; int n;
bool Done=false; bool Done=false;
Poco::Buffer<char> IncomingFrame(0); try {
n = WS_->receiveFrame(IncomingFrame, flags); Poco::Buffer<char> IncomingFrame(0);
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK; n = WS_->receiveFrame(IncomingFrame, flags);
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
if(n==0) { if (n == 0) {
return delete this; return delete this;
} }
switch(Op) { switch (Op) {
case Poco::Net::WebSocket::FRAME_OP_PING: { case Poco::Net::WebSocket::FRAME_OP_PING: {
WS_->sendFrame("", 0, WS_->sendFrame("", 0,
(int)Poco::Net::WebSocket::FRAME_OP_PONG | (int)Poco::Net::WebSocket::FRAME_OP_PONG |
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN); (int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
} } break;
break; case Poco::Net::WebSocket::FRAME_OP_PONG: {
case Poco::Net::WebSocket::FRAME_OP_PONG: { } break;
} case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
break; Logger().warning(Poco::format("CLOSE(%s): Client is closing its connection.", Id_));
case Poco::Net::WebSocket::FRAME_OP_CLOSE: { Done = true;
Logger().warning(Poco::format("CLOSE(%s): Client is closing its connection.",Id_)); } break;
Done=true; case Poco::Net::WebSocket::FRAME_OP_TEXT: {
} IncomingFrame.append(0);
break; if (!Authenticated_) {
case Poco::Net::WebSocket::FRAME_OP_TEXT: { std::string Frame{IncomingFrame.begin()};
IncomingFrame.append(0); auto Tokens = Utils::Split(Frame, ':');
if(!Authenticated_) { bool Expired = false, Contacted = false;
std::string Frame{IncomingFrame.begin()}; if (Tokens.size() == 2 &&
auto Tokens = Utils::Split(Frame,':'); AuthClient()->IsAuthorized(Tokens[1], UserInfo_, Expired, Contacted)) {
bool Expired = false, Contacted = false; Authenticated_ = true;
if(Tokens.size()==2 && AuthClient()->IsAuthorized(Tokens[1], UserInfo_, Expired, Contacted)) { std::string S{"Welcome! Bienvenue! Bienvenidos!"};
Authenticated_=true; WS_->sendFrame(S.c_str(), S.size());
std::string S{"Welcome! Bienvenue! Bienvenidos!"}; WebSocketClientServer()->SetUser(Id_, UserInfo_.userinfo.email);
WS_->sendFrame(S.c_str(),S.size()); } else {
WebSocketClientServer()->SetUser(Id_,UserInfo_.userinfo.email); std::string S{"Invalid token. Closing connection."};
} else { WS_->sendFrame(S.c_str(), S.size());
std::string S{"Invalid token. Closing connection."}; Done = true;
WS_->sendFrame(S.c_str(),S.size()); }
Done=true;
}
} else { } else {
try { try {
Poco::JSON::Parser P; Poco::JSON::Parser P;
auto Obj = P.parse(IncomingFrame.begin()) auto Obj =
.extract<Poco::JSON::Object::Ptr>(); P.parse(IncomingFrame.begin()).extract<Poco::JSON::Object::Ptr>();
std::string Answer; std::string Answer;
if(Processor_!= nullptr) if (Processor_ != nullptr)
Processor_->Processor(Obj, Answer, Done); Processor_->Processor(Obj, Answer, Done);
if (!Answer.empty()) if (!Answer.empty())
WS_->sendFrame(Answer.c_str(), (int) Answer.size()); WS_->sendFrame(Answer.c_str(), (int)Answer.size());
else { else {
WS_->sendFrame("{}", 2); WS_->sendFrame("{}", 2);
} }
} catch (const Poco::JSON::JSONException & E) { } catch (const Poco::JSON::JSONException &E) {
Logger().log(E); Logger().log(E);
} Done=true;
} }
} }
break; } break;
default: default: {
{ }
}
} } catch (...) {
} Done=true;
}
if(Done) { if(Done) {
delete this; delete this;

View File

@@ -133,6 +133,37 @@ namespace ORM {
return R; return R;
} }
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>)
{
if(!Value.empty()) {
if(!Result.empty())
Result += " and ";
Result += fieldName;
Result += '=';
Result += "'";
Result += Escape(Value);
Result += "'";
}
} else {
if(!Result.empty())
Result += " and ";
Result += fieldName ;
Result += '=';
Result += std::to_string(Value);
}
return WHERE_AND_(Result,args...);
}
template <typename... Args> std::string WHERE_AND(Args... args) {
std::string Result;
return WHERE_AND_(Result, args...);
}
enum SqlComparison { EQ = 0, NEQ, LT, LTE, GT, GTE }; enum SqlComparison { EQ = 0, NEQ, LT, LTE, GT, GTE };
enum SqlBinaryOp { AND = 0 , OR }; enum SqlBinaryOp { AND = 0 , OR };

View File

@@ -5,6 +5,7 @@
#pragma once #pragma once
#include <string> #include <string>
#include <cstring>
#include "Poco/String.h" #include "Poco/String.h"
#if defined(__GNUC__) #if defined(__GNUC__)
@@ -428,6 +429,7 @@ namespace OpenWifi::uCentralProtocol {
static const char *RADIUSACCT = "acct"; static const char *RADIUSACCT = "acct";
static const char *RADIUSAUTH = "auth"; static const char *RADIUSAUTH = "auth";
static const char *RADIUSDST = "dst"; static const char *RADIUSDST = "dst";
static const char *IES = "ies";
} }
namespace OpenWifi::uCentralProtocol::Events { namespace OpenWifi::uCentralProtocol::Events {
@@ -457,25 +459,28 @@ namespace OpenWifi::uCentralProtocol::Events {
ET_TELEMETRY ET_TELEMETRY
}; };
inline static EVENT_MSG EventFromString(const std::string & Method) { inline EVENT_MSG EventFromString(const std::string & Method) {
static std::vector<std::pair<const char *,EVENT_MSG>> Values{ if(strcmp(STATE,Method.c_str())==0)
{ CFGPENDING , ET_CFGPENDING }, return ET_STATE;
{ CONNECT, ET_CONNECT }, else if(strcmp(HEALTHCHECK,Method.c_str())==0)
{ CRASHLOG, ET_CRASHLOG }, return ET_HEALTHCHECK;
{ DEVICEUPDATE, ET_DEVICEUPDATE }, else if(strcmp(CONNECT,Method.c_str())==0)
{ HEALTHCHECK, ET_HEALTHCHECK }, return ET_CONNECT;
{ LOG, ET_LOG }, else if(strcmp(CFGPENDING,Method.c_str())==0)
{ PING, ET_PING }, return ET_CFGPENDING;
{ RECOVERY, ET_RECOVERY }, else if(strcmp(CRASHLOG,Method.c_str())==0)
{ STATE, ET_STATE }, return ET_CRASHLOG;
{ TELEMETRY, ET_TELEMETRY } else if(strcmp(DEVICEUPDATE,Method.c_str())==0)
}; return ET_DEVICEUPDATE;
else if(strcmp(LOG,Method.c_str())==0)
std::string L = Poco::toLower(Method); return ET_LOG;
auto hint = std::find_if(cbegin(Values),cend(Values),[&](const std::pair<const char *,EVENT_MSG> &v) ->bool { return strcmp(v.first,L.c_str())==0; }); else if(strcmp(PING,Method.c_str())==0)
if(hint == cend(Values)) return ET_PING;
return ET_UNKNOWN; else if(strcmp(RECOVERY,Method.c_str())==0)
return hint->second; return ET_RECOVERY;
else if(strcmp(TELEMETRY,Method.c_str())==0)
return ET_TELEMETRY;
return ET_UNKNOWN;
}; };
} }

View File

@@ -1 +0,0 @@
null