mirror of
				https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
				synced 2025-10-31 18:57:51 +00:00 
			
		
		
		
	Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
This commit is contained in:
		| @@ -103,6 +103,7 @@ add_executable( owsec | |||||||
|         src/framework/RESTAPI_RateLimiter.h |         src/framework/RESTAPI_RateLimiter.h | ||||||
|         src/framework/WebSocketLogger.h |         src/framework/WebSocketLogger.h | ||||||
|         src/framework/RESTAPI_GenericServerAccounting.h |         src/framework/RESTAPI_GenericServerAccounting.h | ||||||
|  |         src/framework/RESTAPI_SystemConfiguration.h | ||||||
|         src/framework/CIDR.h |         src/framework/CIDR.h | ||||||
|         src/framework/RESTAPI_Handler.cpp |         src/framework/RESTAPI_Handler.cpp | ||||||
|         src/framework/RESTAPI_Handler.h |         src/framework/RESTAPI_Handler.h | ||||||
| @@ -168,7 +169,13 @@ add_executable( owsec | |||||||
|         src/storage/orm_actionLinks.cpp src/storage/orm_actionLinks.h |         src/storage/orm_actionLinks.cpp src/storage/orm_actionLinks.h | ||||||
|         src/storage/orm_avatar.cpp src/storage/orm_avatar.h |         src/storage/orm_avatar.cpp src/storage/orm_avatar.h | ||||||
|         src/SpecialUserHelpers.h |         src/SpecialUserHelpers.h | ||||||
|         src/RESTAPI/RESTAPI_db_helpers.h src/storage/orm_logins.cpp src/storage/orm_logins.h src/RESTAPI/RESTAPI_totp_handler.cpp src/RESTAPI/RESTAPI_totp_handler.h src/TotpCache.h src/RESTAPI/RESTAPI_subtotp_handler.cpp src/RESTAPI/RESTAPI_subtotp_handler.h src/RESTAPI/RESTAPI_signup_handler.cpp src/RESTAPI/RESTAPI_signup_handler.h src/MessagingTemplates.cpp src/MessagingTemplates.h) |         src/RESTAPI/RESTAPI_db_helpers.h src/storage/orm_logins.cpp src/storage/orm_logins.h | ||||||
|  |         src/RESTAPI/RESTAPI_totp_handler.cpp | ||||||
|  |         src/RESTAPI/RESTAPI_totp_handler.h | ||||||
|  |         src/TotpCache.h | ||||||
|  |         src/RESTAPI/RESTAPI_subtotp_handler.cpp src/RESTAPI/RESTAPI_subtotp_handler.h | ||||||
|  |         src/RESTAPI/RESTAPI_signup_handler.cpp src/RESTAPI/RESTAPI_signup_handler.h | ||||||
|  |         src/MessagingTemplates.cpp src/MessagingTemplates.h) | ||||||
|  |  | ||||||
| if(NOT SMALL_BUILD) | if(NOT SMALL_BUILD) | ||||||
|     target_link_libraries(owsec PUBLIC |     target_link_libraries(owsec PUBLIC | ||||||
|   | |||||||
| @@ -50,6 +50,8 @@ namespace OpenWifi::GWObjects { | |||||||
| 		field_to_json(Obj,"entity", entity); | 		field_to_json(Obj,"entity", entity); | ||||||
| 		field_to_json(Obj,"modified", modified); | 		field_to_json(Obj,"modified", modified); | ||||||
| 		field_to_json(Obj,"locale", locale); | 		field_to_json(Obj,"locale", locale); | ||||||
|  | 		field_to_json(Obj,"restrictedDevice", restrictedDevice); | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void Device::to_json_with_status(Poco::JSON::Object &Obj) const { | 	void Device::to_json_with_status(Poco::JSON::Object &Obj) const { | ||||||
| @@ -70,6 +72,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 			field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); | 			field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); | ||||||
| 			field_to_json(Obj,"associations_2G", (uint64_t) 0); | 			field_to_json(Obj,"associations_2G", (uint64_t) 0); | ||||||
| 			field_to_json(Obj,"associations_5G", (uint64_t) 0); | 			field_to_json(Obj,"associations_5G", (uint64_t) 0); | ||||||
|  | 			field_to_json(Obj,"associations_6G", (uint64_t) 0); | ||||||
| 		} | 		} | ||||||
| #endif | #endif | ||||||
| 	} | 	} | ||||||
| @@ -89,6 +92,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 			field_from_json(Obj,"subscriber", subscriber); | 			field_from_json(Obj,"subscriber", subscriber); | ||||||
| 			field_from_json(Obj,"entity", entity); | 			field_from_json(Obj,"entity", entity); | ||||||
| 			field_from_json(Obj,"locale", locale); | 			field_from_json(Obj,"locale", locale); | ||||||
|  | 			field_from_json(Obj,"restrictedDevice", restrictedDevice); | ||||||
| 			return true; | 			return true; | ||||||
| 		} catch (const Poco::Exception &E) { | 		} catch (const Poco::Exception &E) { | ||||||
| 		} | 		} | ||||||
| @@ -199,6 +203,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 		field_to_json(Obj,"lastContact", LastContact); | 		field_to_json(Obj,"lastContact", LastContact); | ||||||
| 		field_to_json(Obj,"associations_2G", Associations_2G); | 		field_to_json(Obj,"associations_2G", Associations_2G); | ||||||
| 		field_to_json(Obj,"associations_5G", Associations_5G); | 		field_to_json(Obj,"associations_5G", Associations_5G); | ||||||
|  | 		field_to_json(Obj,"associations_6G", Associations_6G); | ||||||
| 		field_to_json(Obj,"webSocketClients", webSocketClients); | 		field_to_json(Obj,"webSocketClients", webSocketClients); | ||||||
| 		field_to_json(Obj,"websocketPackets", websocketPackets); | 		field_to_json(Obj,"websocketPackets", websocketPackets); | ||||||
| 		field_to_json(Obj,"kafkaClients", kafkaClients); | 		field_to_json(Obj,"kafkaClients", kafkaClients); | ||||||
| @@ -208,6 +213,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 		field_to_json(Obj,"sessionId", sessionId); | 		field_to_json(Obj,"sessionId", sessionId); | ||||||
| 		field_to_json(Obj,"connectionCompletionTime", connectionCompletionTime); | 		field_to_json(Obj,"connectionCompletionTime", connectionCompletionTime); | ||||||
| 		field_to_json(Obj,"totalConnectionTime", Utils::Now() - started); | 		field_to_json(Obj,"totalConnectionTime", Utils::Now() - started); | ||||||
|  | 		field_to_json(Obj,"certificateExpiryDate", certificateExpiryDate); | ||||||
|  |  | ||||||
| 		switch(VerifiedCertificate) { | 		switch(VerifiedCertificate) { | ||||||
| 			case NO_CERTIFICATE: | 			case NO_CERTIFICATE: | ||||||
| @@ -299,8 +305,10 @@ namespace OpenWifi::GWObjects { | |||||||
| 		field_to_json(Obj,"timeout",timeout); | 		field_to_json(Obj,"timeout",timeout); | ||||||
| 		field_to_json(Obj,"type",type); | 		field_to_json(Obj,"type",type); | ||||||
| 		field_to_json(Obj,"script",script); | 		field_to_json(Obj,"script",script); | ||||||
| 		field_to_json(Obj,"scriptId",scriptId); |  | ||||||
| 		field_to_json(Obj,"when",when); | 		field_to_json(Obj,"when",when); | ||||||
|  | 		field_to_json(Obj,"signature", signature); | ||||||
|  | 		field_to_json(Obj,"deferred", deferred); | ||||||
|  | 		field_to_json(Obj,"uri", uri); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool ScriptRequest::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool ScriptRequest::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
| @@ -309,8 +317,10 @@ namespace OpenWifi::GWObjects { | |||||||
| 			field_from_json(Obj,"timeout",timeout); | 			field_from_json(Obj,"timeout",timeout); | ||||||
| 			field_from_json(Obj,"type",type); | 			field_from_json(Obj,"type",type); | ||||||
| 			field_from_json(Obj,"script",script); | 			field_from_json(Obj,"script",script); | ||||||
| 			field_from_json(Obj,"scriptId",scriptId); |  | ||||||
| 			field_from_json(Obj,"when",when); | 			field_from_json(Obj,"when",when); | ||||||
|  | 			field_from_json(Obj,"signature", signature); | ||||||
|  | 			field_from_json(Obj,"deferred", deferred); | ||||||
|  | 			field_from_json(Obj,"uri", uri); | ||||||
| 			return true; | 			return true; | ||||||
| 		} catch (const Poco::Exception &E) { | 		} catch (const Poco::Exception &E) { | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -28,6 +28,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 		uint64_t TX = 0, RX = 0; | 		uint64_t TX = 0, RX = 0; | ||||||
| 		uint64_t Associations_2G=0; | 		uint64_t Associations_2G=0; | ||||||
| 		uint64_t Associations_5G=0; | 		uint64_t Associations_5G=0; | ||||||
|  | 		uint64_t Associations_6G=0; | ||||||
| 		bool Connected = false; | 		bool Connected = false; | ||||||
| 		uint64_t LastContact=0; | 		uint64_t LastContact=0; | ||||||
| 		std::string Firmware; | 		std::string Firmware; | ||||||
| @@ -41,6 +42,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 		uint64_t 		started=0; | 		uint64_t 		started=0; | ||||||
| 		uint64_t 		sessionId=0; | 		uint64_t 		sessionId=0; | ||||||
| 		double      	connectionCompletionTime=0.0; | 		double      	connectionCompletionTime=0.0; | ||||||
|  | 		std::uint64_t	certificateExpiryDate=0; | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 	}; | 	}; | ||||||
| @@ -68,6 +70,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 		std::string entity; | 		std::string entity; | ||||||
| 		uint64_t 	modified=0; | 		uint64_t 	modified=0; | ||||||
| 		std::string locale; | 		std::string locale; | ||||||
|  | 		bool 		restrictedDevice=false; | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 		void to_json_with_status(Poco::JSON::Object &Obj) const; | 		void to_json_with_status(Poco::JSON::Object &Obj) const; | ||||||
| @@ -214,12 +217,15 @@ namespace OpenWifi::GWObjects { | |||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct ScriptRequest { | 	struct ScriptRequest { | ||||||
| 		uint64_t 	timeout=30; |  | ||||||
| 		std::string serialNumber; | 		std::string serialNumber; | ||||||
|  | 		uint64_t 	timeout=30; | ||||||
| 		std::string type; | 		std::string type; | ||||||
| 		std::string script; | 		std::string script; | ||||||
| 		std::string scriptId; | 		std::uint64_t when; | ||||||
| 		uint64_t 	when=0; | 		std::string signature; | ||||||
|  | 		bool deferred; | ||||||
|  | 		std::string uri; | ||||||
|  |  | ||||||
| 		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); | ||||||
| 	}; | 	}; | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ | |||||||
| #include "Poco/FormattingChannel.h" | #include "Poco/FormattingChannel.h" | ||||||
| #include "Poco/AsyncChannel.h" | #include "Poco/AsyncChannel.h" | ||||||
| #include "Poco/NullChannel.h" | #include "Poco/NullChannel.h" | ||||||
|  | #include "Poco/SplitterChannel.h" | ||||||
| #include "Poco/Net/HTTPStreamFactory.h" | #include "Poco/Net/HTTPStreamFactory.h" | ||||||
| #include "Poco/Net/HTTPSStreamFactory.h" | #include "Poco/Net/HTTPSStreamFactory.h" | ||||||
| #include "Poco/Net/FTPSStreamFactory.h" | #include "Poco/Net/FTPSStreamFactory.h" | ||||||
| @@ -26,7 +27,7 @@ | |||||||
| #include "framework/RESTAPI_ExtServer.h" | #include "framework/RESTAPI_ExtServer.h" | ||||||
| #include "framework/RESTAPI_IntServer.h" | #include "framework/RESTAPI_IntServer.h" | ||||||
| #include "framework/utils.h" | #include "framework/utils.h" | ||||||
|  | #include "framework/WebSocketLogger.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| @@ -193,6 +194,8 @@ namespace OpenWifi { | |||||||
| 			auto LoggingFormat = MicroService::instance().ConfigGetString("logging.format", | 			auto LoggingFormat = MicroService::instance().ConfigGetString("logging.format", | ||||||
| 																		  "%Y-%m-%d %H:%M:%S.%i %s: [%p][thr:%I] %t"); | 																		  "%Y-%m-%d %H:%M:%S.%i %s: [%p][thr:%I] %t"); | ||||||
| 			auto UseAsyncLogs_ = MicroService::instance().ConfigGetBool("logging.asynch",false); | 			auto UseAsyncLogs_ = MicroService::instance().ConfigGetBool("logging.asynch",false); | ||||||
|  | 			auto DisableWebSocketLogging = MicroService::instance().ConfigGetBool("logging.websocket",false); | ||||||
|  |  | ||||||
| 			if (LoggingDestination == "null") { | 			if (LoggingDestination == "null") { | ||||||
| 				Poco::AutoPtr<Poco::NullChannel> DevNull(new Poco::NullChannel); | 				Poco::AutoPtr<Poco::NullChannel> DevNull(new Poco::NullChannel); | ||||||
| 				Poco::Logger::root().setChannel(DevNull); | 				Poco::Logger::root().setChannel(DevNull); | ||||||
| @@ -240,25 +243,62 @@ namespace OpenWifi { | |||||||
| 				Poco::AutoPtr<Poco::FileChannel> FileChannel(new Poco::FileChannel); | 				Poco::AutoPtr<Poco::FileChannel> FileChannel(new Poco::FileChannel); | ||||||
| 				FileChannel->setProperty("rotation", "10 M"); | 				FileChannel->setProperty("rotation", "10 M"); | ||||||
| 				FileChannel->setProperty("archive", "timestamp"); | 				FileChannel->setProperty("archive", "timestamp"); | ||||||
|  | 				FileChannel->setProperty("purgeCount", "10"); | ||||||
| 				FileChannel->setProperty("path", LoggingLocation); | 				FileChannel->setProperty("path", LoggingLocation); | ||||||
| 				if(UseAsyncLogs_) { | 				if(UseAsyncLogs_) { | ||||||
|  | 					std::cout << __LINE__ << std::endl; | ||||||
| 					Poco::AutoPtr<Poco::AsyncChannel> Async_File( | 					Poco::AutoPtr<Poco::AsyncChannel> Async_File( | ||||||
| 						new Poco::AsyncChannel(FileChannel)); | 						new Poco::AsyncChannel(FileChannel)); | ||||||
|  | 					std::cout << __LINE__ << std::endl; | ||||||
| 					Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter); | 					Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter); | ||||||
|  | 					std::cout << __LINE__ << std::endl; | ||||||
| 					Formatter->setProperty("pattern", LoggingFormat); | 					Formatter->setProperty("pattern", LoggingFormat); | ||||||
|  | 					std::cout << __LINE__ << std::endl; | ||||||
| 					Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel( | 					Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel( | ||||||
| 						new Poco::FormattingChannel(Formatter, Async_File)); | 						new Poco::FormattingChannel(Formatter, Async_File)); | ||||||
|  | 					std::cout << __LINE__ << std::endl; | ||||||
|  | 					if(DisableWebSocketLogging) { | ||||||
|  | 						std::cout << __LINE__ << std::endl; | ||||||
| 						Poco::Logger::root().setChannel(FormattingChannel); | 						Poco::Logger::root().setChannel(FormattingChannel); | ||||||
|  | 					} else { | ||||||
|  | 						std::cout << __LINE__ << std::endl; | ||||||
|  | 						Poco::AutoPtr<WebSocketLogger>			WSLogger(new WebSocketLogger); | ||||||
|  | 						Poco::AutoPtr<Poco::SplitterChannel>	Splitter(new Poco::SplitterChannel); | ||||||
|  | 						Splitter->addChannel(WSLogger); | ||||||
|  | 						Splitter->addChannel(FormattingChannel); | ||||||
|  | 						std::cout << __LINE__ << std::endl; | ||||||
|  | 						Poco::Logger::root().setChannel(Splitter); | ||||||
|  | 					} | ||||||
|  |  | ||||||
| 				} else { | 				} else { | ||||||
| 					Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter); | 					Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter); | ||||||
| 					Formatter->setProperty("pattern", LoggingFormat); | 					Formatter->setProperty("pattern", LoggingFormat); | ||||||
| 					Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel( | 					Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel( | ||||||
| 						new Poco::FormattingChannel(Formatter, FileChannel)); | 						new Poco::FormattingChannel(Formatter, FileChannel)); | ||||||
|  | 					if(DisableWebSocketLogging) { | ||||||
|  | 						std::cout << __LINE__ << std::endl; | ||||||
| 						Poco::Logger::root().setChannel(FormattingChannel); | 						Poco::Logger::root().setChannel(FormattingChannel); | ||||||
|  | 					} else { | ||||||
|  | 						std::cout << __LINE__ << std::endl; | ||||||
|  | 						Poco::AutoPtr<Poco::SplitterChannel>	Splitter(new Poco::SplitterChannel); | ||||||
|  | 						Poco::AutoPtr<WebSocketLogger>			WSLogger(new WebSocketLogger); | ||||||
|  | 						Splitter->addChannel(WSLogger); | ||||||
|  | 						Splitter->addChannel(FormattingChannel); | ||||||
|  | 						std::cout << __LINE__ << std::endl; | ||||||
|  | 						Poco::Logger::root().setChannel(Splitter); | ||||||
|  | 					} | ||||||
|  | 					std::cout << __LINE__ << std::endl; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			auto Level = Poco::Logger::parseLevel(MicroService::instance().ConfigGetString("logging.level", "debug")); | 			auto Level = Poco::Logger::parseLevel(MicroService::instance().ConfigGetString("logging.level", "debug")); | ||||||
| 			Poco::Logger::root().setLevel(Level); | 			Poco::Logger::root().setLevel(Level); | ||||||
|  |  | ||||||
|  | 			if(!DisableWebSocketLogging) { | ||||||
|  | 				static const UI_WebSocketClientServer::NotificationTypeIdVec Notifications = { | ||||||
|  | 					{1, "log"}}; | ||||||
|  |  | ||||||
|  | 				UI_WebSocketClientServer()->RegisterNotifications(Notifications); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -630,4 +670,15 @@ namespace OpenWifi { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	void MicroService::DeleteOverrideConfiguration() { | ||||||
|  | 		Poco::File	F(DataDir_ + ExtraConfigurationFilename); | ||||||
|  |  | ||||||
|  | 		try { | ||||||
|  | 			if(F.exists()) | ||||||
|  | 				F.remove(); | ||||||
|  | 		} catch (...) { | ||||||
|  |  | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -81,6 +81,8 @@ namespace OpenWifi { | |||||||
| 			// Logger_ = Poco::Logger::root().get("BASE-SVC"); | 			// Logger_ = Poco::Logger::root().get("BASE-SVC"); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		inline static const char * ExtraConfigurationFilename = "/configuration_override.json"; | ||||||
|  |  | ||||||
| 		inline void SaveConfig() { PropConfigurationFile_->save(ConfigFileName_); } | 		inline void SaveConfig() { PropConfigurationFile_->save(ConfigFileName_); } | ||||||
| 		inline auto UpdateConfig() { return PropConfigurationFile_; } | 		inline auto UpdateConfig() { return PropConfigurationFile_; } | ||||||
| 		inline bool NoAPISecurity() const { return NoAPISecurity_; } | 		inline bool NoAPISecurity() const { return NoAPISecurity_; } | ||||||
| @@ -151,6 +153,8 @@ namespace OpenWifi { | |||||||
| 		int main(const ArgVec &args) override; | 		int main(const ArgVec &args) override; | ||||||
|         void InitializeLoggingSystem(); |         void InitializeLoggingSystem(); | ||||||
|  |  | ||||||
|  | 		void DeleteOverrideConfiguration(); | ||||||
|  |  | ||||||
| 		[[nodiscard]] std::string Sign(Poco::JWT::Token &T, const std::string &Algo); | 		[[nodiscard]] std::string Sign(Poco::JWT::Token &T, const std::string &Algo); | ||||||
| 		void AddActivity(const std::string &Activity); | 		void AddActivity(const std::string &Activity); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -114,4 +114,8 @@ namespace OpenWifi { | |||||||
|     std::string MicroServiceGetPublicAPIEndPoint() { |     std::string MicroServiceGetPublicAPIEndPoint() { | ||||||
|         return MicroService::instance().GetPublicAPIEndPoint(); |         return MicroService::instance().GetPublicAPIEndPoint(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | 	void MicroServiceDeleteOverrideConfiguration() { | ||||||
|  | 		return MicroService::instance().DeleteOverrideConfiguration(); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -52,4 +52,5 @@ namespace OpenWifi { | |||||||
|     std::uint64_t MicroServiceRandom(std::uint64_t Range); |     std::uint64_t MicroServiceRandom(std::uint64_t Range); | ||||||
|     std::string MicroServiceSign(Poco::JWT::Token &T, const std::string &Algo); |     std::string MicroServiceSign(Poco::JWT::Token &T, const std::string &Algo); | ||||||
|     std::string MicroServiceGetPublicAPIEndPoint(); |     std::string MicroServiceGetPublicAPIEndPoint(); | ||||||
|  | 	void MicroServiceDeleteOverrideConfiguration(); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										52
									
								
								src/framework/RESTAPI_SystemConfiguration.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/framework/RESTAPI_SystemConfiguration.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | |||||||
|  | // | ||||||
|  | // Created by stephane bourque on 2022-10-31. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "framework/RESTAPI_Handler.h" | ||||||
|  | #include "framework/MicroServiceFuncs.h" | ||||||
|  |  | ||||||
|  | using namespace std::chrono_literals; | ||||||
|  |  | ||||||
|  | namespace OpenWifi { | ||||||
|  |  | ||||||
|  | 	class RESTAPI_system_configuration : public RESTAPIHandler { | ||||||
|  | 	  public: | ||||||
|  | 		RESTAPI_system_configuration(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, | ||||||
|  | 									 RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, | ||||||
|  | 									 bool Internal) | ||||||
|  | 			: RESTAPIHandler(bindings, L, | ||||||
|  | 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_PUT, | ||||||
|  | 													  Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|  | 													  Poco::Net::HTTPRequest::HTTP_DELETE, | ||||||
|  | 													  Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
|  | 							 Server, TransactionId, Internal) {} | ||||||
|  |  | ||||||
|  | 		static auto PathName() { return std::list<std::string>{"/api/v1/systemConfiguration"}; } | ||||||
|  |  | ||||||
|  | 		inline void DoPost() final {} | ||||||
|  |  | ||||||
|  | 		inline void DoGet() final { | ||||||
|  |  | ||||||
|  | 			return OK(); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		inline void DoPut() final{ | ||||||
|  | 			if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) { | ||||||
|  | 				return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			return OK(); | ||||||
|  | 		}; | ||||||
|  |  | ||||||
|  | 		inline void DoDelete() final{ | ||||||
|  | 			if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) { | ||||||
|  | 				return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); | ||||||
|  | 			} | ||||||
|  | 			MicroServiceDeleteOverrideConfiguration(); | ||||||
|  | 			return OK(); | ||||||
|  | 		}; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -10,10 +10,12 @@ | |||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     template<typename ContentStruct> |     template<typename ContentStruct> | ||||||
|  |  | ||||||
|     struct WebSocketNotification { |     struct WebSocketNotification { | ||||||
|         inline static uint64_t xid = 1; |         inline static uint64_t xid = 1; | ||||||
|         uint64_t 		notification_id = ++xid; |         uint64_t 		notification_id = ++xid; | ||||||
|         std::string type; | //        std::string 	type; | ||||||
|  | 		std::uint64_t 	type_id=0; | ||||||
|         ContentStruct 	content; |         ContentStruct 	content; | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; |         void to_json(Poco::JSON::Object &Obj) const; | ||||||
| @@ -24,7 +26,8 @@ namespace OpenWifi { | |||||||
|     template<typename ContentStruct> |     template<typename ContentStruct> | ||||||
|     void WebSocketNotification<ContentStruct>::to_json(Poco::JSON::Object &Obj) const { |     void WebSocketNotification<ContentStruct>::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         RESTAPI_utils::field_to_json(Obj, "notification_id", notification_id); |         RESTAPI_utils::field_to_json(Obj, "notification_id", notification_id); | ||||||
|         RESTAPI_utils::field_to_json(Obj, "type", type); | //        RESTAPI_utils::field_to_json(Obj, "type", type); | ||||||
|  | 		RESTAPI_utils::field_to_json(Obj, "type_id", type_id); | ||||||
|         RESTAPI_utils::field_to_json(Obj, "content", content); |         RESTAPI_utils::field_to_json(Obj, "content", content); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -32,8 +35,9 @@ namespace OpenWifi { | |||||||
|     bool WebSocketNotification<ContentStruct>::from_json(const Poco::JSON::Object::Ptr &Obj) { |     bool WebSocketNotification<ContentStruct>::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         try { |         try { | ||||||
|             RESTAPI_utils::field_from_json(Obj, "notification_id", notification_id); |             RESTAPI_utils::field_from_json(Obj, "notification_id", notification_id); | ||||||
|  |   //          RESTAPI_utils::field_from_json(Obj, "type", type); | ||||||
|  | 			RESTAPI_utils::field_from_json(Obj, "type_id", type_id); | ||||||
| 			RESTAPI_utils::field_from_json(Obj, "content", content); | 			RESTAPI_utils::field_from_json(Obj, "content", content); | ||||||
|             RESTAPI_utils::field_from_json(Obj, "type", type); |  | ||||||
|             return true; |             return true; | ||||||
|         } catch (...) { |         } catch (...) { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -39,6 +39,7 @@ namespace OpenWifi { | |||||||
|                                          *this, &UI_WebSocketClientServer::OnSocketError)); |                                          *this, &UI_WebSocketClientServer::OnSocketError)); | ||||||
|         Client->SocketRegistered_ = true; |         Client->SocketRegistered_ = true; | ||||||
|         Clients_[ClientSocket] = std::move(Client); |         Clients_[ClientSocket] = std::move(Client); | ||||||
|  | 		UsersConnected_ = Clients_.size(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	void UI_WebSocketClientServer::SetProcessor( UI_WebSocketClientProcessor * F) { | 	void UI_WebSocketClientServer::SetProcessor( UI_WebSocketClientProcessor * F) { | ||||||
| @@ -65,6 +66,7 @@ namespace OpenWifi { | |||||||
|                                                 Poco::Net::ErrorNotification>(*this,&UI_WebSocketClientServer::OnSocketError)); |                                                 Poco::Net::ErrorNotification>(*this,&UI_WebSocketClientServer::OnSocketError)); | ||||||
|         } |         } | ||||||
|         Clients_.erase(Client); |         Clients_.erase(Client); | ||||||
|  | 		UsersConnected_ = Clients_.size(); | ||||||
|         std::cout << "How many clients: " << Clients_.size() << std::endl; |         std::cout << "How many clients: " << Clients_.size() << std::endl; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -101,39 +103,37 @@ namespace OpenWifi { | |||||||
| 		} | 		} | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	bool UI_WebSocketClientServer::SendToId(const std::string &Id, const std::string &Payload) { | 	bool UI_WebSocketClientServer::IsFiltered(std::uint64_t id, const OpenWifi::UI_WebSocketClientInfo &Client) { | ||||||
|  | 		return std::find(Client.Filter_.begin(), Client.Filter_.end(),id)!=end(Client.Filter_); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, std::uint64_t id, const std::string &Payload) { | ||||||
| 		std::lock_guard G(Mutex_); | 		std::lock_guard G(Mutex_); | ||||||
|  |  | ||||||
| 		for(const auto &Client:Clients_) { | 		for(const auto &Client:Clients_) { | ||||||
|             if(Client.second->Id_==Id) | 			if(Client.second->UserName_ == UserName) { | ||||||
|                 return Client.second->WS_->sendFrame(Payload.c_str(),(int)Payload.size()); | 				try { | ||||||
|         } | 					if(!IsFiltered(id,*Client.second) && Client.second->Authenticated_) { | ||||||
|  | 						return Client.second->WS_->sendFrame( | ||||||
|  | 								   Payload.c_str(), (int)Payload.size()) == (int)Payload.size(); | ||||||
|  | 					} else { | ||||||
| 						return false; | 						return false; | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 	bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, const std::string &Payload) { |  | ||||||
| 		std::lock_guard G(Mutex_); |  | ||||||
| 		uint64_t Sent=0; |  | ||||||
|  |  | ||||||
| 		for(const auto &client:Clients_) { |  | ||||||
| 			if(client.second->UserName_ == UserName) { |  | ||||||
| 				try { |  | ||||||
| 					if (client.second->WS_->sendFrame(Payload.c_str(),(int)Payload.size())) |  | ||||||
| 						Sent++; |  | ||||||
| 				} catch (...) { | 				} catch (...) { | ||||||
| 					return false; | 					return false; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		return Sent>0; | 		return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void UI_WebSocketClientServer::SendToAll(const std::string &Payload) { | 	void UI_WebSocketClientServer::SendToAll(std::uint64_t id, const std::string &Payload) { | ||||||
| 		std::lock_guard G(Mutex_); | 		std::lock_guard G(Mutex_); | ||||||
|  |  | ||||||
| 		for(const auto &client:Clients_) { | 		for(const auto &Client:Clients_) { | ||||||
| 			try { | 			try { | ||||||
| 				client.second->WS_->sendFrame(Payload.c_str(),(int)Payload.size()); | 				if(!IsFiltered(id,*Client.second) && Client.second->Authenticated_) | ||||||
|  | 					Client.second->WS_->sendFrame(Payload.c_str(),(int)Payload.size()); | ||||||
| 			} catch (...) { | 			} catch (...) { | ||||||
|  |  | ||||||
| 			} | 			} | ||||||
| @@ -144,6 +144,29 @@ namespace OpenWifi { | |||||||
|         return Clients_.find(ClientSocket); |         return Clients_.find(ClientSocket); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | 	void UI_WebSocketClientServer::SortNotifications() { | ||||||
|  | 		struct { | ||||||
|  | 			bool operator()(const NotificationEntry &A, const NotificationEntry & B) const { | ||||||
|  | 				return A.id < B.id; }; | ||||||
|  | 		} CompareNotifications; | ||||||
|  | 		std::sort(NotificationTypes_.begin(), NotificationTypes_.end(), CompareNotifications); | ||||||
|  |  | ||||||
|  | 		NotificationTypesJSON_.clear(); | ||||||
|  | 		Poco::JSON::Array		AllNotifications; | ||||||
|  | 		for(const auto ¬ification:NotificationTypes_) { | ||||||
|  | 			Poco::JSON::Object	Notification; | ||||||
|  | 			Notification.set("id", notification.id); | ||||||
|  | 			Notification.set("helper", notification.helper); | ||||||
|  | 			AllNotifications.add(Notification); | ||||||
|  | 		} | ||||||
|  | 		NotificationTypesJSON_.set("notificationTypes", AllNotifications); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void UI_WebSocketClientServer::RegisterNotifications(const OpenWifi::UI_WebSocketClientServer::NotificationTypeIdVec &Notifications) { | ||||||
|  | 		std::copy(Notifications.begin(), Notifications.end(), std::back_inserter(NotificationTypes_)); | ||||||
|  | 		SortNotifications(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     void UI_WebSocketClientServer::OnSocketError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) { |     void UI_WebSocketClientServer::OnSocketError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) { | ||||||
|         std::lock_guard     G(LocalMutex_); |         std::lock_guard     G(LocalMutex_); | ||||||
|         auto Client = FindWSClient(G,pNf->socket().impl()->sockfd()); |         auto Client = FindWSClient(G,pNf->socket().impl()->sockfd()); | ||||||
| @@ -188,6 +211,7 @@ namespace OpenWifi { | |||||||
|                 return EndConnection(G, Client); |                 return EndConnection(G, Client); | ||||||
| 			} break; | 			} break; | ||||||
| 			case Poco::Net::WebSocket::FRAME_OP_TEXT: { | 			case Poco::Net::WebSocket::FRAME_OP_TEXT: { | ||||||
|  | 				constexpr const char *DropMessagesCommand = "drop-notifications"; | ||||||
| 				IncomingFrame.append(0); | 				IncomingFrame.append(0); | ||||||
| 				if (!Client->second->Authenticated_) { | 				if (!Client->second->Authenticated_) { | ||||||
| 					std::string Frame{IncomingFrame.begin()}; | 					std::string Frame{IncomingFrame.begin()}; | ||||||
| @@ -198,19 +222,36 @@ namespace OpenWifi { | |||||||
|                         Client->second->Authenticated_ = true; |                         Client->second->Authenticated_ = true; | ||||||
|                         Client->second->UserName_ = Client->second->UserInfo_.userinfo.email; |                         Client->second->UserName_ = Client->second->UserInfo_.userinfo.email; | ||||||
| 						poco_debug(Logger(),fmt::format("START({}): {} UI Client is starting WS connection.", Client->second->Id_, Client->second->UserName_)); | 						poco_debug(Logger(),fmt::format("START({}): {} UI Client is starting WS connection.", Client->second->Id_, Client->second->UserName_)); | ||||||
| 						std::string S{"Welcome! Bienvenue! Bienvenidos!"}; | 						auto WelcomeMessage = NotificationTypesJSON_; | ||||||
| 						Client->second->WS_->sendFrame(S.c_str(), S.size()); | 						WelcomeMessage.set("success", "Welcome! Bienvenue! Bienvenidos!"); | ||||||
|  | 						std::ostringstream OS; | ||||||
|  | 						WelcomeMessage.stringify(OS); | ||||||
|  | 						Client->second->WS_->sendFrame(OS.str().c_str(), (int) OS.str().size()); | ||||||
|                         Client->second->UserName_ = Client->second->UserInfo_.userinfo.email; |                         Client->second->UserName_ = Client->second->UserInfo_.userinfo.email; | ||||||
| 					} else { | 					} else { | ||||||
| 						std::string S{"Invalid token. Closing connection."}; | 						Poco::JSON::Object	WelcomeMessage; | ||||||
|                         Client->second->WS_->sendFrame(S.c_str(), S.size()); | 						WelcomeMessage.set("error", "Invalid token. Closing connection."); | ||||||
|  | 						std::ostringstream OS; | ||||||
|  | 						WelcomeMessage.stringify(OS); | ||||||
|  | 						Client->second->WS_->sendFrame(OS.str().c_str(), (int) OS.str().size()); | ||||||
|  |                         Client->second->WS_->sendFrame(OS.str().c_str(), (int) OS.str().size()); | ||||||
|                         return EndConnection(G, Client); |                         return EndConnection(G, Client); | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 				} else { | 				} else { | ||||||
|                     Poco::JSON::Parser P; |                     Poco::JSON::Parser P; | ||||||
|                     auto Obj = |                     auto Obj = | ||||||
|                         P.parse(IncomingFrame.begin()).extract<Poco::JSON::Object::Ptr>(); |                         P.parse(IncomingFrame.begin()).extract<Poco::JSON::Object::Ptr>(); | ||||||
|  |  | ||||||
|  | 					if(Obj->has(DropMessagesCommand) && Obj->isArray(DropMessagesCommand)) { | ||||||
|  | 						auto Filters = Obj->getArray(DropMessagesCommand); | ||||||
|  | 						Client->second->Filter_.clear(); | ||||||
|  | 						for(const auto &Filter:*Filters) { | ||||||
|  | 							Client->second->Filter_.emplace_back( (std::uint64_t) Filter); | ||||||
|  | 						} | ||||||
|  | 						std::sort(begin(Client->second->Filter_),end(Client->second->Filter_)); | ||||||
|  | 						return; | ||||||
|  | 					} | ||||||
|  |  | ||||||
|                     std::string Answer; |                     std::string Answer; | ||||||
|                     bool CloseConnection=false; |                     bool CloseConnection=false; | ||||||
|                     if (Processor_ != nullptr) { |                     if (Processor_ != nullptr) { | ||||||
|   | |||||||
| @@ -19,8 +19,6 @@ | |||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| 	class UI_WebSocketClient; |  | ||||||
|  |  | ||||||
| 	class UI_WebSocketClientProcessor { | 	class UI_WebSocketClientProcessor { | ||||||
| 	  public: | 	  public: | ||||||
| 		virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done ) = 0; | 		virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done ) = 0; | ||||||
| @@ -33,6 +31,7 @@ namespace OpenWifi { | |||||||
|         std::string					            UserName_; |         std::string					            UserName_; | ||||||
|         bool 			                        Authenticated_ = false; |         bool 			                        Authenticated_ = false; | ||||||
|         bool				                    SocketRegistered_=false; |         bool				                    SocketRegistered_=false; | ||||||
|  | 		std::vector<std::uint64_t>				Filter_; | ||||||
|         SecurityObjects::UserInfoAndPolicy      UserInfo_; |         SecurityObjects::UserInfoAndPolicy      UserInfo_; | ||||||
|  |  | ||||||
|         UI_WebSocketClientInfo(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &username) { |         UI_WebSocketClientInfo(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &username) { | ||||||
| @@ -50,6 +49,10 @@ namespace OpenWifi { | |||||||
| 			return instance_; | 			return instance_; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		bool IsAnyoneConnected() { | ||||||
|  | 			return UsersConnected_; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		int Start() override; | 		int Start() override; | ||||||
| 		void Stop() override; | 		void Stop() override; | ||||||
| 		void run() override; | 		void run() override; | ||||||
| @@ -69,7 +72,7 @@ namespace OpenWifi { | |||||||
| 			std::ostringstream OO; | 			std::ostringstream OO; | ||||||
| 			Msg.stringify(OO); | 			Msg.stringify(OO); | ||||||
|  |  | ||||||
| 			return SendToUser(userName,OO.str()); | 			return SendToUser(userName, Notification.type_id, OO.str()); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		template <typename T> void SendNotification(const WebSocketNotification<T> &Notification) { | 		template <typename T> void SendNotification(const WebSocketNotification<T> &Notification) { | ||||||
| @@ -79,16 +82,26 @@ namespace OpenWifi { | |||||||
| 			Msg.set("notification",Payload); | 			Msg.set("notification",Payload); | ||||||
| 			std::ostringstream OO; | 			std::ostringstream OO; | ||||||
| 			Msg.stringify(OO); | 			Msg.stringify(OO); | ||||||
| 			SendToAll(OO.str()); | 			SendToAll(Notification.type_id, OO.str()); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|         [[nodiscard]] bool SendToId(const std::string &Id, const std::string &Payload); | 		[[nodiscard]] bool SendToUser(const std::string &userName, std::uint64_t id, const std::string &Payload); | ||||||
| 		[[nodiscard]] bool SendToUser(const std::string &userName, const std::string &Payload); | 		void SendToAll(std::uint64_t id, const std::string &Payload); | ||||||
| 		void SendToAll(const std::string &Payload); |  | ||||||
|  | 		struct NotificationEntry { | ||||||
|  | 			std::uint64_t 	id=0; | ||||||
|  | 			std::string 	helper; | ||||||
|  | 		}; | ||||||
|  |  | ||||||
|         using ClientList = std::map<int,std::unique_ptr<UI_WebSocketClientInfo>>; |         using ClientList = std::map<int,std::unique_ptr<UI_WebSocketClientInfo>>; | ||||||
|  | 		using NotificationTypeIdVec = std::vector<NotificationEntry>; | ||||||
|  |  | ||||||
|  | 		void RegisterNotifications(const NotificationTypeIdVec & Notifications); | ||||||
|  | 		bool IsFiltered(std::uint64_t id, const UI_WebSocketClientInfo &Client); | ||||||
|  |  | ||||||
|     private: |     private: | ||||||
| 		mutable std::atomic_bool Running_ = false; | 		mutable std::atomic_bool Running_ = false; | ||||||
|  | 		std::atomic_uint64_t 						UsersConnected_=0; | ||||||
| 		Poco::Thread 								Thr_; | 		Poco::Thread 								Thr_; | ||||||
| 		Poco::Net::SocketReactor					Reactor_; | 		Poco::Net::SocketReactor					Reactor_; | ||||||
| 		Poco::Thread								ReactorThread_; | 		Poco::Thread								ReactorThread_; | ||||||
| @@ -97,6 +110,9 @@ namespace OpenWifi { | |||||||
| 		std::string GoogleApiKey_; | 		std::string GoogleApiKey_; | ||||||
|         ClientList    Clients_; |         ClientList    Clients_; | ||||||
| 		UI_WebSocketClientProcessor                 *Processor_ = nullptr; | 		UI_WebSocketClientProcessor                 *Processor_ = nullptr; | ||||||
|  | 		NotificationTypeIdVec						NotificationTypes_; | ||||||
|  | 		Poco::JSON::Object							NotificationTypesJSON_; | ||||||
|  |  | ||||||
| 		UI_WebSocketClientServer() noexcept; | 		UI_WebSocketClientServer() noexcept; | ||||||
|         void EndConnection(std::lock_guard<std::recursive_mutex> &G, ClientList::iterator & Client); |         void EndConnection(std::lock_guard<std::recursive_mutex> &G, ClientList::iterator & Client); | ||||||
|  |  | ||||||
| @@ -106,7 +122,7 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|         ClientList::iterator FindWSClient( std::lock_guard<std::recursive_mutex> &G, int ClientSocket); |         ClientList::iterator FindWSClient( std::lock_guard<std::recursive_mutex> &G, int ClientSocket); | ||||||
|  |  | ||||||
|  | 		void SortNotifications(); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	inline auto UI_WebSocketClientServer() { return UI_WebSocketClientServer::instance(); } | 	inline auto UI_WebSocketClientServer() { return UI_WebSocketClientServer::instance(); } | ||||||
|   | |||||||
| @@ -5,29 +5,39 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "framework/SubSystemServer.h" | #include "framework/SubSystemServer.h" | ||||||
|  | #include "framework/UI_WebSocketClientServer.h" | ||||||
|  | #include "framework/UI_WebSocketClientNotifications.h" | ||||||
|  |  | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| 	class WebSocketLogger : public Poco::Channel { | 	class WebSocketLogger : public Poco::Channel { | ||||||
| 	  public: | 	  public: | ||||||
|  |  | ||||||
| 		inline std::string getProperty( [[maybe_unused]] const std::string &p ) const final { | 		WebSocketLogger() { | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		~WebSocketLogger() { | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		std::string getProperty( [[maybe_unused]] const std::string &p ) const { | ||||||
|  | 			std::cout << "WS getProperty" << std::endl; | ||||||
| 			return ""; | 			return ""; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		inline void close() final { | 		void close() final { | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		inline void open() final { | 		void open() final { | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		inline static std::string to_string(Poco::Message::Priority p) { | 		static std::string to_string(Poco::Message::Priority p) { | ||||||
| 			switch(p) { | 			switch(p) { | ||||||
| 			case Poco::Message::PRIO_INFORMATION: return "information"; | 			case Poco::Message::PRIO_INFORMATION: return "information"; | ||||||
| 			case Poco::Message::PRIO_CRITICAL: return "critical"; | 			case Poco::Message::PRIO_CRITICAL: return "critical"; | ||||||
| 			case Poco::Message::PRIO_DEBUG: return "debug"; | 			case Poco::Message::PRIO_DEBUG: return "debug"; | ||||||
| 			case Poco::Message::PRIO_ERROR: return "error"; | 			case Poco::Message::PRIO_ERROR: return "error"; | ||||||
| 			case Poco::Message::PRIO_FATAL: return "level"; | 			case Poco::Message::PRIO_FATAL: return "fatal"; | ||||||
| 			case Poco::Message::PRIO_NOTICE: return "notice"; | 			case Poco::Message::PRIO_NOTICE: return "notice"; | ||||||
| 			case Poco::Message::PRIO_TRACE: return "trace"; | 			case Poco::Message::PRIO_TRACE: return "trace"; | ||||||
| 			case Poco::Message::PRIO_WARNING: return "warning"; | 			case Poco::Message::PRIO_WARNING: return "warning"; | ||||||
| @@ -35,55 +45,63 @@ namespace OpenWifi { | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		inline void log(const Poco::Message &m) final { | 		struct NotificationLogMessage { | ||||||
| 			if(Enabled_) { | 			std::string 		msg; | ||||||
| 				/* | 			std::string 		level; | ||||||
| 				nlohmann::json log_msg; | 			std::string 		timestamp; | ||||||
| 				log_msg["msg"] = m.getText(); | 			std::string 		source; | ||||||
| 				log_msg["level"] = to_string(m.getPriority()); | 			std::string 		thread_name; | ||||||
| 				log_msg["timestamp"] = Poco::DateTimeFormatter::format(m.getTime(), Poco::DateTimeFormat::ISO8601_FORMAT); | 			std::uint64_t 		thread_id=0; | ||||||
| 				log_msg["source"] = m.getSource(); |  | ||||||
| 				log_msg["thread_name"] = m.getThread(); |  | ||||||
| 				log_msg["thread_id"] = m.getTid(); |  | ||||||
|  |  | ||||||
| 				std::cout << log_msg << std::endl; | 			inline void to_json(Poco::JSON::Object &Obj) const { | ||||||
| 				 */ | 				RESTAPI_utils::field_to_json(Obj,"msg", msg); | ||||||
| 				std::lock_guard	G(Mutex_); | 				RESTAPI_utils::field_to_json(Obj,"level", level); | ||||||
| 				std::vector<uint64_t>	Remove; | 				RESTAPI_utils::field_to_json(Obj,"timestamp", timestamp); | ||||||
| 				for(const auto &[Id,CallBack]:CallBacks_) { | 				RESTAPI_utils::field_to_json(Obj,"source", source); | ||||||
|  | 				RESTAPI_utils::field_to_json(Obj,"thread_name", thread_name); | ||||||
|  | 				RESTAPI_utils::field_to_json(Obj,"thread_id", thread_id); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			inline bool from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
| 				try { | 				try { | ||||||
| 						CallBack(m); | 					RESTAPI_utils::field_from_json(Obj, "msg", msg); | ||||||
| 					} catch (...) { | 					RESTAPI_utils::field_from_json(Obj, "level", level); | ||||||
| 						Remove.push_back(Id); | 					RESTAPI_utils::field_from_json(Obj, "timestamp", timestamp); | ||||||
| 					} | 					RESTAPI_utils::field_from_json(Obj, "source", source); | ||||||
| 				} | 					RESTAPI_utils::field_from_json(Obj, "thread_name", thread_name); | ||||||
| 				for(const auto &i:Remove) | 					RESTAPI_utils::field_from_json(Obj, "thread_id", thread_id); | ||||||
| 					CallBacks_.erase(i); | 					return true; | ||||||
| 			} | 				} catch(...) { | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		inline void setProperty([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) final { |  | ||||||
|  |  | ||||||
| 				} | 				} | ||||||
|  | 				return false; | ||||||
| 		inline static auto instance() { |  | ||||||
| 			static auto instance_ = new WebSocketLogger; |  | ||||||
| 			return instance_; |  | ||||||
| 			} | 			} | ||||||
| 		inline void Enable(bool enable) { Enabled_ = enable; } |  | ||||||
| 		typedef std::function<void(const Poco::Message &M)> logmuxer_callback_func_t; |  | ||||||
| 		inline void RegisterCallback(const logmuxer_callback_func_t & R, uint64_t &Id) { |  | ||||||
| 			std::lock_guard	G(Mutex_); |  | ||||||
| 			Id = CallBackId_++; |  | ||||||
| 			CallBacks_[Id] = R; |  | ||||||
| 		} |  | ||||||
| 	  private: |  | ||||||
| 		std::recursive_mutex	Mutex_; |  | ||||||
| 		std::map<uint64_t,logmuxer_callback_func_t>  CallBacks_; |  | ||||||
| 		inline static uint64_t CallBackId_=1; |  | ||||||
| 		bool Enabled_ = false; |  | ||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
| 	inline auto WebSocketLogger() { return WebSocketLogger::instance(); } | 		typedef WebSocketNotification<NotificationLogMessage> WebSocketClientNotificationLogMessage_t; | ||||||
|  |  | ||||||
|  | 		void log(const Poco::Message &m) final { | ||||||
|  | 			if(UI_WebSocketClientServer()->IsAnyoneConnected()) { | ||||||
|  | 				WebSocketClientNotificationLogMessage_t		Msg; | ||||||
|  | 				Msg.content.msg = m.getText(); | ||||||
|  | 				Msg.content.level = WebSocketLogger::to_string(m.getPriority()); | ||||||
|  | 				Msg.content.timestamp = Poco::DateTimeFormatter::format(m.getTime(), Poco::DateTimeFormat::ISO8601_FORMAT); | ||||||
|  | 				Msg.content.source = m.getSource(); | ||||||
|  | 				Msg.content.thread_name = m.getThread(); | ||||||
|  | 				Msg.content.thread_id = m.getTid(); | ||||||
|  | 				Msg.type_id = 1; | ||||||
|  | 				UI_WebSocketClientServer()->SendNotification(Msg); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		void setProperty([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) { | ||||||
|  | 			std::cout << "WS setProperty" << std::endl; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 	  private: | ||||||
|  | 		std::recursive_mutex	Mutex_; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | //	inline auto WebSocketLogger() { return WebSocketLogger::instance(); } | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -219,6 +219,9 @@ namespace OpenWifi::RESTAPI::Errors { | |||||||
|  |  | ||||||
| 	static const struct msg MaximumRTTYSessionsReached{1144,"Too many RTTY sessions currently active"}; | 	static const struct msg MaximumRTTYSessionsReached{1144,"Too many RTTY sessions currently active"}; | ||||||
| 	static const struct msg DeviceIsAlreadyBusy{1145,"Device is already executing a command. Please try later."}; | 	static const struct msg DeviceIsAlreadyBusy{1145,"Device is already executing a command. Please try later."}; | ||||||
|  |  | ||||||
|  | 	static const struct msg DeviceRequiresSignature{1146,"Device requires device signature to be provided."}; | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -433,6 +436,8 @@ namespace OpenWifi::uCentralProtocol { | |||||||
|     static const char *CHANNELS = "channels"; |     static const char *CHANNELS = "channels"; | ||||||
|     static const char *PASSWORD = "password"; |     static const char *PASSWORD = "password"; | ||||||
|     static const char *DEVICEUPDATE = "deviceupdate"; |     static const char *DEVICEUPDATE = "deviceupdate"; | ||||||
|  | 	static const char *FWSIGNATURE = "FWsignature"; | ||||||
|  | 	static const char *SIGNATURE = "signature"; | ||||||
|  |  | ||||||
|     static const char *SERIALNUMBER = "serialNumber"; |     static const char *SERIALNUMBER = "serialNumber"; | ||||||
|     static const char *COMPATIBLE = "compatible"; |     static const char *COMPATIBLE = "compatible"; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 stephb9959
					stephb9959