web_handler.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. #include "ajax_handler.h"
  2. #include "settings/system_settings.h"
  3. #include "web_handler.h"
  4. #include <json/json.h>
  5. #include <string>
  6. #include <tsl/htrie_map.h>
  7. #include <utils/custom.h>
  8. #include <utils/logger.h>
  9. /* clang-format */
  10. #include <goahead.h>
  11. #undef min
  12. using WebsNode = tsl::htrie_map<char, std::function<Json::Value(Webs *, const std::string &)>>;
  13. static const WebsNode AJAX_WEB_NODES = {
  14. {"login",
  15. [](Webs *wp, const std::string &subID) -> Json::Value {
  16. std::string token = utils::get_rand(32);
  17. Json::Value param;
  18. Json::Reader jsonReader;
  19. HTELINK_LOG_DEBUG("input buf = %s", wp->input.buf);
  20. if (!jsonReader.parse(wp->input.buf, param, false)) {
  21. HTELINK_LOG_ERR("login parse buf error, buf = %s", (char *)wp->input.buf);
  22. return Json::nullValue;
  23. }
  24. HTELINK_LOG_DEBUG("param = %s", param.toStyledString().c_str());
  25. const std::string name = param["username"].asString();
  26. const std::string passwd = param["password"].asString();
  27. Json::Value result;
  28. result["code"] = 200;
  29. result["message"] = "验证成功";
  30. Json::Value tokenJson;
  31. tokenJson["token"] = token;
  32. result["data"] = tokenJson;
  33. return result;
  34. } },
  35. {"logout",
  36. [](Webs *wp, const std::string &subID) -> Json::Value {
  37. Json::Value result;
  38. return result;
  39. } },
  40. {"UID",
  41. [](Webs *wp, const std::string &subID) -> Json::Value {
  42. Json::Value result;
  43. return result;
  44. } },
  45. {"download",
  46. [](Webs *wp, const std::string &subID) -> Json::Value {
  47. Json::Value result;
  48. return result;
  49. } },
  50. {"getBaseConfig",
  51. [](Webs *wp, const std::string &subID) -> Json::Value {
  52. Json::Value result;
  53. result["data"] = webconfig::GetJsonDataCenter();
  54. result["code"] = 200;
  55. result["message"] = "SUCCESS";
  56. return result;
  57. } },
  58. {"getGatewayInfo",
  59. [](Webs *wp, const std::string &subID) -> Json::Value {
  60. Json::Value result;
  61. result["data"] = webconfig::GetJsonGatewayInfo();
  62. result["code"] = 200;
  63. result["message"] = "SUCCESS";
  64. return result;
  65. } },
  66. {"getGatewayStatus",
  67. [](Webs *wp, const std::string &subID) -> Json::Value {
  68. Json::Value result;
  69. Json::Value statJson;
  70. statJson["status"] = true;
  71. result["code"] = 200;
  72. result["message"] = u"在线";
  73. result["data"] = statJson;
  74. return result;
  75. } },
  76. {"getDarcyConfig",
  77. [](Webs *wp, const std::string &subID) -> Json::Value {
  78. Json::Value result;
  79. return result;
  80. } },
  81. {"reset",
  82. [](Webs *wp, const std::string &subID) -> Json::Value {
  83. Json::Value result;
  84. return result;
  85. } },
  86. {"setNetworkConfig",
  87. [](Webs *wp, const std::string &subID) -> Json::Value {
  88. Json::Value result;
  89. return result;
  90. } },
  91. {"restart",
  92. [](Webs *wp, const std::string &subID) -> Json::Value {
  93. Json::Value result;
  94. return result;
  95. } },
  96. {"reboot",
  97. [](Webs *wp, const std::string &subID) -> Json::Value {
  98. Json::Value result;
  99. return result;
  100. } },
  101. {"deviceType",
  102. [](Webs *wp, const std::string &subID) -> Json::Value {
  103. Json::Value result;
  104. return result;
  105. } },
  106. {"commu",
  107. [](Webs *wp, const std::string &subID) -> Json::Value {
  108. Json::Value result;
  109. return result;
  110. } },
  111. {"deviceList",
  112. [](Webs *wp, const std::string &subID) -> Json::Value {
  113. Json::Value result;
  114. return result;
  115. } },
  116. {"ctrlParams", [](Webs *wp, const std::string &subID) -> Json::Value {
  117. Json::Value result;
  118. return result;
  119. }}
  120. };
  121. /* clang-format off */
  122. static const WebsNode UID_WEB_NODES = {
  123. {"loadChildNodes/dataCenter", [](Webs *wp,const std::string &subID) -> Json::Value {
  124. Json::Value result;
  125. settings::ConfigParser configParser;
  126. std::vector<settings::ConfigParser::DataCenter> dataCenters = configParser.GetDataCenter();
  127. int index = 0;
  128. for (settings::ConfigParser::DataCenter &dc : dataCenters){
  129. char key[64];
  130. sprintf(key, "dataCenter/%d", index++);
  131. result[key] = dc.name;
  132. }
  133. return result;
  134. }},
  135. {"loadChildNodes/communicator", [](Webs *wp, const std::string &subID) -> Json::Value {
  136. Json::Value result;
  137. return result;
  138. }},
  139. {"loadChildNodes/d", [](Webs *wp, const std::string &subID) -> Json::Value {
  140. Json::Value result;
  141. return result;
  142. }},
  143. {"loadNode/getGatewayInfo", [](Webs *wp, const std::string &subID) -> Json::Value {
  144. settings::SystemSettings sysSettings;
  145. sysSettings.UpdateSysInfo();
  146. char disk[20], mem[20];
  147. sprintf(disk, "%d M/%d M", sysSettings.freeDiskSpace, sysSettings.totalDiskSpace);
  148. sprintf(mem, "%d M/%d M", sysSettings.freeMemory, sysSettings.totalMemory);
  149. Json::Value result;
  150. Json::Value diskJson;
  151. diskJson["free"] = sysSettings.freeDiskSpace;
  152. diskJson["total"] = sysSettings.totalDiskSpace;
  153. result["disk"] = diskJson;
  154. Json::Value memJson;
  155. memJson["free"] = sysSettings.freeMemory;
  156. memJson["total"] = sysSettings.totalMemory;
  157. result["memory"] = memJson;
  158. sysSettings.UpdateNetDev();
  159. Json::Value netJson;
  160. for (settings::SystemSettings::NetCard &netCard: sysSettings.netCards) {
  161. Json::Value netJ;
  162. netJ["ip"] = netCard.ipAddr;
  163. netJ["mac"] = netCard.MAC;
  164. netJson.append(netJ);
  165. }
  166. result["network"] = netJson;
  167. Json::Value sysJson;
  168. sysJson["version"] = sysSettings.appVer;
  169. sysJson["time"] = sysSettings.sysTime;
  170. sysJson["upgradeTime"] = sysSettings.upgradeTime;
  171. sysJson["updateConfigTime"] = sysSettings.updateConfigTime;
  172. result["system"] = sysJson;
  173. Json::Value root;
  174. root["data"] =result;
  175. return root;
  176. }},
  177. {"loadNode/getGatewayStatus", [](Webs *wp, const std::string &subID) -> Json::Value {
  178. Json::Value result;
  179. Json::Value statJson;
  180. statJson["status"] = false;
  181. result["code"] = 200;
  182. result["message"] = "";
  183. result["data"] = statJson;
  184. return result;
  185. }},
  186. {"loadNode/dataCenter", [](Webs *wp, const std::string &subID) -> Json::Value {
  187. settings::ConfigParser configParser;
  188. std::vector<settings::ConfigParser::DataCenter> dataCenters = configParser.GetDataCenter();
  189. Json::Value result;
  190. for (settings::ConfigParser::DataCenter &center : dataCenters) {
  191. Json::Value centerJson;
  192. centerJson["id"] = center.ID;
  193. centerJson["type"] = center.protoType;
  194. centerJson["ip"] = center.host;
  195. centerJson["port"] = center.port;
  196. centerJson["isOnline"] = false;
  197. centerJson["recv"] = 0;
  198. }
  199. return result;
  200. }},
  201. {"loadNode/communicator", [](Webs *wp, const std::string &subID) -> Json::Value {
  202. Json::Value result;
  203. return result;
  204. }},
  205. {"loadNode/d", [](Webs *wp, const std::string &subID) -> Json::Value {
  206. Json::Value result;
  207. return result;}},
  208. {"loadNode/param", [](Webs *wp, const std::string &subID) -> Json::Value {
  209. Json::Value result;
  210. return result;
  211. }},
  212. {"ctrl", [](Webs *wp, const std::string &subID) -> Json::Value {
  213. const char* id = websGetVar(wp, "deviceId", "");
  214. const char* name = websGetVar(wp, "paramName", "");
  215. const char* value = websGetVar(wp, "paramValue", "");
  216. return Json::nullValue;
  217. }},
  218. {"acquire", [](Webs *wp, const std::string &subID) -> Json::Value {
  219. Json::Value result;
  220. return result;
  221. }},
  222. {"point", [](Webs *wp, const std::string &subID) -> Json::Value {
  223. Json::Value result;
  224. return result;
  225. }},
  226. };
  227. /* clang-format on */
  228. WebHandler::WebHandler()
  229. {
  230. // WebNode webNode = {"loadChildNodes", {{"dataCenter", {}}, {"communicator", {}}, {"d", {}}}};
  231. }
  232. WebHandler *WebHandler::instance()
  233. {
  234. static WebHandler *webHandler = nullptr;
  235. if (webHandler == nullptr) {
  236. webHandler = new WebHandler();
  237. }
  238. ASSERT(webHandler != nullptr);
  239. return webHandler;
  240. }
  241. bool WebHandler::LoginVerify(Webs *wp)
  242. {
  243. char passbuf[ME_GOAHEAD_LIMIT_PASSWORD * 3 + 3];
  244. bool success;
  245. assert(wp);
  246. if (!wp->user && (wp->user = websLookupUser(wp->username)) == 0) {
  247. trace(5, "verifyUser: Unknown user \"%s\"", wp->username);
  248. return false;
  249. }
  250. /*
  251. Verify the password. If using Digest auth, we compare the digest of the password.
  252. Otherwise we encode the plain-text password and compare that
  253. */
  254. if (!wp->encoded) {
  255. fmt(passbuf, sizeof(passbuf), "%s:%s:%s", wp->username, "htelink", wp->password);
  256. wfree(wp->password);
  257. wp->password = websMD5(passbuf);
  258. wp->encoded = 1;
  259. }
  260. HTELINK_LOG_DEBUG("encode = %d, username = %s, password = %s, digest = %s, store password = %s", wp->encoded,
  261. wp->username, wp->password, wp->digest, wp->user->password);
  262. if (wp->digest) {
  263. success = smatch(wp->password, wp->digest);
  264. } else {
  265. success = smatch(wp->password, wp->user->password);
  266. }
  267. if (success) {
  268. trace(5, "User \"%s\" authenticated", wp->username);
  269. } else {
  270. trace(5, "Password for user \"%s\" failed to authenticate", wp->username);
  271. }
  272. return success;
  273. }
  274. Json::Value WebHandler::UidWebResult(Webs *wp, const std::string &node)
  275. {
  276. HTELINK_LOG_DEBUG("web handler, node: %s", node.c_str());
  277. std::string longest_prefix = UID_WEB_NODES.longest_prefix(node).key();
  278. HTELINK_LOG_DEBUG("longest prefix, key: %s", longest_prefix.c_str());
  279. std::function<Json::Value(Webs *, const std::string &)> func = UID_WEB_NODES.longest_prefix(node).value();
  280. if (!func) {
  281. return Json::nullValue;
  282. }
  283. const std::string subId = node.substr(longest_prefix.length());
  284. HTELINK_LOG_DEBUG("subId = %s", subId.c_str());
  285. return func(wp, subId);
  286. }
  287. Json::Value WebHandler::AjaxWebResult(Webs *wp, const std::string &node)
  288. {
  289. HTELINK_LOG_DEBUG("web handler, node: %s", node.c_str());
  290. WebsNode::const_iterator webNode = AJAX_WEB_NODES.longest_prefix(node);
  291. if (webNode == AJAX_WEB_NODES.end()) {
  292. HTELINK_LOG_ERR("web handler, node: %s not found", node.c_str());
  293. return Json::nullValue;
  294. }
  295. std::string longestPrefix = webNode.key();
  296. HTELINK_LOG_DEBUG("longest prefix, key: %s", longestPrefix.c_str());
  297. std::function<Json::Value(Webs *, const std::string &)> func = webNode.value();
  298. if (!func) {
  299. return Json::nullValue;
  300. }
  301. const std::string subId = node.substr(std::min(node.length(), longestPrefix.length() + 1));
  302. HTELINK_LOG_DEBUG("subId = %s", subId.c_str());
  303. return func(wp, subId);
  304. }
  305. bool WebHandler::WebResult(Webs *wp, const std::string &prefix)
  306. {
  307. HTELINK_LOG_DEBUG("webs ajax path: %s, prefix = %s, user = %s, method = %s, protocol = %s",
  308. wp->path == nullptr ? "" : wp->path, wp->route->prefix, wp->username, wp->method, wp->protocol);
  309. std::string path = wp->path;
  310. #undef min
  311. path = path.substr(std::min(path.length(), prefix.length()));
  312. Json::Value result;
  313. if (prefix == "/ajax/") {
  314. result = AjaxWebResult(wp, path);
  315. websSetStatus(wp, 200);
  316. } else if (prefix == "/uid/") {
  317. result = UidWebResult(wp, path);
  318. websSetStatus(wp, 200);
  319. } else {
  320. websSetStatus(wp, 401);
  321. }
  322. websWriteHeaders(wp, -1, 0);
  323. websWriteEndHeaders(wp);
  324. Json::FastWriter jsonWriter;
  325. std::string strJson = jsonWriter.write(result);
  326. HTELINK_LOG_DEBUG("response: %s", result.toStyledString().c_str());
  327. websWrite(wp, strJson.c_str());
  328. websDone(wp);
  329. return true;
  330. }