// // Created by stephane bourque on 2022-04-28. // #include "ProvWebSocketClient.h" #include "SerialNumberCache.h" #include "StorageService.h" #include "framework/UI_WebSocketClientServer.h" #include "sdks/SDK_sec.h" namespace OpenWifi { ProvWebSocketClient::ProvWebSocketClient(Poco::Logger &Logger) : Logger_(Logger) { UI_WebSocketClientServer()->SetProcessor(this); } ProvWebSocketClient::~ProvWebSocketClient() { UI_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 = ORM::Escape(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 = ORM::Escape(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, [[maybe_unused]] const SecurityObjects::UserInfo &UserInfo) { 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 (UI_WebSocketClientServer()->GeoCodeEnabled() && Command == "address_completion" && O->has("address")) { ws_command_address_completion(O, Done, Answer); } else if (UI_WebSocketClientServer()->GeoCodeEnabled() && Command == "subuser_search" && O->has("operatorId")) { ws_command_subuser_search(O, Done, Answer); } else if (UI_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", UI_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\" }"; } } // namespace OpenWifi