mirror of
				https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
				synced 2025-10-30 18:27:49 +00:00 
			
		
		
		
	Compare commits
	
		
			45 Commits
		
	
	
		
			v2.6.0-RC1
			...
			v2.6.0-RC3
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | f8d3079f44 | ||
|   | 81cec762f7 | ||
|   | a430ad7e71 | ||
|   | d1c13ad2dd | ||
|   | b837e41569 | ||
|   | 5e39987e36 | ||
|   | 890eb7311a | ||
|   | fc509adf01 | ||
|   | f43198f874 | ||
|   | 767331f575 | ||
|   | d26ef6eeba | ||
|   | 8c672f058f | ||
|   | 3134947b57 | ||
|   | 448563ab06 | ||
|   | 2a22a35e58 | ||
|   | 8e8656a6ae | ||
|   | e745d4efe7 | ||
|   | 701e0b50ff | ||
|   | df082a969e | ||
|   | 8863d2ecc9 | ||
|   | 5e1937ec4f | ||
|   | e679dc7458 | ||
|   | 7e1a962b57 | ||
|   | 8ad2e12f12 | ||
|   | 23d16e619a | ||
|   | 760cad9a14 | ||
|   | 94997a1f9f | ||
|   | 9060fef03d | ||
|   | 2f8eb90c5a | ||
|   | c0d0435efa | ||
|   | 6942de0475 | ||
|   | cce2528ec4 | ||
|   | 3be0fd45d9 | ||
|   | 8b1a80ce09 | ||
|   | 5e12f00558 | ||
|   | 1d534cb974 | ||
|   | a7e9c96f8d | ||
|   | cb3f7a0872 | ||
|   | 6ad434c02f | ||
|   | 62e3ada15c | ||
|   | 2beef2daba | ||
|   | 4b131465fb | ||
|   | cafc243e55 | ||
|   | 5c44134f9d | ||
|   | 8ed86d3582 | 
							
								
								
									
										8
									
								
								.github/workflows/cleanup.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/cleanup.yml
									
									
									
									
										vendored
									
									
								
							| @@ -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 | ||||||
|   | |||||||
| @@ -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"} \ | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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); | ||||||
|   | |||||||
| @@ -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" | ||||||
|   | |||||||
| @@ -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(); | ||||||
|   | |||||||
| @@ -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); | ||||||
|   | |||||||
| @@ -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"); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -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(...) { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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); | ||||||
|   | |||||||
| @@ -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(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -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); |  | ||||||
|         }; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| @@ -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_; | ||||||
|   | |||||||
| @@ -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; | ||||||
|   | |||||||
| @@ -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); | ||||||
|   | |||||||
| @@ -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(); | ||||||
|   | |||||||
| @@ -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; | ||||||
|   | |||||||
| @@ -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; | ||||||
|   | |||||||
| @@ -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; | ||||||
|   | |||||||
| @@ -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 }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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; | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1 +0,0 @@ | |||||||
| null |  | ||||||
		Reference in New Issue
	
	Block a user