// // Created by stephane bourque on 2022-04-28. // #include "ProvWebSocketClient.h" #include "StorageService.h" #include "SerialNumberCache.h" #include "sdks/SDK_sec.h" namespace OpenWifi { ProvWebSocketClient::ProvWebSocketClient(Poco::Logger &Logger) : Logger_(Logger){ WebSocketClientServer()->SetProcessor(this); } ProvWebSocketClient::~ProvWebSocketClient() { WebSocketClientServer()->SetProcessor(nullptr); } void ProvWebSocketClient::ws_command_serial_number_search(const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) { Done = false; auto Prefix = O->get("serial_prefix").toString(); Poco::toLowerInPlace(Prefix); Logger().information(Poco::format("serial_number_search: %s", Prefix)); if (!Prefix.empty() && Prefix.length() < 13) { std::vector Numbers; SerialNumberCache()->FindNumbers(Prefix, 50, Numbers); Poco::JSON::Array Arr; for (const auto &i : Numbers) Arr.add(Utils::int_to_hex(i)); Poco::JSON::Object RetObj; RetObj.set("serialNumbers", Arr); std::ostringstream SS; Poco::JSON::Stringifier::stringify(RetObj, SS); Answer = SS.str(); } } void ProvWebSocketClient::ws_command_address_completion(const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) { Done = false; auto Address = O->get("address").toString(); Answer = GoogleGeoCodeCall(Address); } void ProvWebSocketClient::ws_command_exit([[maybe_unused]] const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) { Done = true; Answer = R"lit({ "closing" : "Goodbye! Aurevoir! Hasta la vista!" })lit"; } void ProvWebSocketClient::ws_command_invalid([[maybe_unused]] const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) { Done = false; Answer = std::string{R"lit({ "error" : "invalid command" })lit"}; } void ProvWebSocketClient::ws_command_subuser_search( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) { Done = false; auto operatorId = O->get("operatorId").toString(); std::string nameSearch, emailSearch; OpenWifi::RESTAPIHandler::AssignIfPresent(O,"nameSearch",nameSearch); OpenWifi::RESTAPIHandler::AssignIfPresent(O,"emailSearch",emailSearch); SecurityObjects::UserInfoList Users; SDK::Sec::Subscriber::Search(nullptr,operatorId,nameSearch,emailSearch,Users); Poco::JSON::Array Arr; for(const auto &i:Users.users) { Poco::JSON::Object OO; OO.set("name", i.name); OO.set("email", i.email); OO.set("id", i.id); i.to_json(OO); Arr.add(OO); } Poco::JSON::Object ObjAnswer; ObjAnswer.set("users", Arr); std::ostringstream SS; Poco::JSON::Stringifier::stringify(ObjAnswer, SS); Answer = SS.str(); } void ProvWebSocketClient::ws_command_subdevice_search( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) { Done = false; auto operatorId = O->get("operatorId").toString(); auto Prefix = O->get("serial_prefix").toString(); Poco::toLowerInPlace(Prefix); std::string Query; if(Prefix[0]=='*') { Query = fmt::format(" operatorId='{}' and (right(serialNumber,{})='{}' or right(realMacAddress,{})='{}' ) ", operatorId, Prefix.size()-1, Prefix.substr(1), Prefix.size()-1, Prefix.substr(1)); } else { Query = fmt::format(" operatorId='{}' and (left(serialNumber,{})='{}' or left(realMacAddress,{})='{}' ) ", operatorId, Prefix.size(), Prefix, Prefix.size(), Prefix); } std::vector SubDevices; StorageService()->SubscriberDeviceDB().GetRecords(0,200,SubDevices,Query); Poco::JSON::Array Arr; for(const auto &i:SubDevices) { Arr.add(i.serialNumber); } Poco::JSON::Object RetObj; RetObj.set("serialNumbers", Arr); std::ostringstream SS; Poco::JSON::Stringifier::stringify(RetObj, SS); Answer = SS.str(); } void ProvWebSocketClient::Processor(const Poco::JSON::Object::Ptr &O, std::string &Result, bool &Done ) { try { if (O->has("command") && O->has("id")) { auto id = (uint64_t) O->get("id"); std::string Answer; auto Command = O->get("command").toString(); if (Command == "serial_number_search" && O->has("serial_prefix")) { ws_command_serial_number_search(O,Done,Answer); } else if (WebSocketClientServer()->GeoCodeEnabled() && Command == "address_completion" && O->has("address")) { ws_command_address_completion(O,Done,Answer); } else if (WebSocketClientServer()->GeoCodeEnabled() && Command == "subuser_search" && O->has("operatorId")) { ws_command_subuser_search(O,Done,Answer); } else if (WebSocketClientServer()->GeoCodeEnabled() && Command == "subdevice_search" && O->has("operatorId") && O->has("serial_prefix")) { ws_command_subdevice_search(O,Done,Answer); } else if (Command=="exit") { ws_command_exit(O,Done,Answer); } else { ws_command_invalid(O,Done,Answer); } Result = fmt::format("{{ \"command_response_id\" : {} , \"response\" : {} }}" , id, Answer); } } catch (const Poco::Exception &E) { Logger().log(E); } } std::string ProvWebSocketClient::GoogleGeoCodeCall(const std::string &A) { try { std::string URI = { "https://maps.googleapis.com/maps/api/geocode/json"}; Poco::URI uri(URI); uri.addQueryParameter("address",A); uri.addQueryParameter("key", WebSocketClientServer()->GoogleApiKey()); Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort()); Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1); session.sendRequest(req); Poco::Net::HTTPResponse res; std::istream& rs = session.receiveResponse(res); if(res.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) { std::ostringstream os; Poco::StreamCopier::copyStream(rs,os); return os.str(); } else { std::ostringstream os; Poco::StreamCopier::copyStream(rs,os); return R"lit({ "error: )lit" + os.str() + R"lit( })lit"; } } catch(...) { } return "{ \"error\" : \"No call made\" }"; } }