JsonCommander.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. #include "../include/JsonCommander.h"
  2. #include "../include/UserManager.h"
  3. #include "../include/base64.h"
  4. JsonCommander::JsonCommander(FileManager &fileManager) : fileManager(fileManager) {
  5. commandsMap["status"] = &JsonCommander::executeStatus;
  6. commandsMap["close"] = &JsonCommander::executeClose;
  7. commandsMap["list"] = &JsonCommander::executeList;
  8. commandsMap["listdata"] = &JsonCommander::executeListData;
  9. commandsMap["put"] = &JsonCommander::executePut;
  10. commandsMap["putdata"] = &JsonCommander::executePutdata;
  11. commandsMap["get"] = &JsonCommander::executeGet;
  12. commandsMap["getdata"] = &JsonCommander::executeGetdata;
  13. commandsMap["head"] = &JsonCommander::executeHead;
  14. commandsMap["deleteme"] = &JsonCommander::executeDeleteMe;
  15. commandsMap["deletefile"] = &JsonCommander::executeDeleteFile;
  16. }
  17. JsonCommander::~JsonCommander() {}
  18. JsonCommander::Response JsonCommander::execute(const Json::Value &message) {
  19. JsonCommander::Response response;
  20. Response (JsonCommander::*commandExecutor)(const Json::Value &) = commandsMap[message["command"].asString()];
  21. if (commandExecutor != nullptr) {
  22. response = (this->*commandExecutor)(message);
  23. } else {
  24. // command does not exist
  25. response.action = close;
  26. }
  27. return response;
  28. }
  29. JsonCommander::Response JsonCommander::executeStatus(const Json::Value &message) {
  30. JsonCommander::Response response;
  31. response.action = send;
  32. response.json["command"] = "status";
  33. // answer a real status message
  34. std::string status;
  35. if (this->fileManager.isUploading() && this->fileManager.isDownloading()) {
  36. status = "download and upload running";
  37. } else if (this->fileManager.isUploading()) {
  38. status = "upload running";
  39. } else if (this->fileManager.isDownloading()) {
  40. status = "download running";
  41. } else {
  42. status = "ok";
  43. }
  44. response.json["response"] = status;
  45. return response;
  46. }
  47. JsonCommander::Response JsonCommander::executeClose(const Json::Value &message) {
  48. JsonCommander::Response response;
  49. response.action = closeAndSend;
  50. response.json["command"] = "close";
  51. response.json["response"] = "bye";
  52. return response;
  53. }
  54. JsonCommander::Response JsonCommander::executeList(const Json::Value &message) {
  55. JsonCommander::Response response;
  56. response.action = send;
  57. response.json["command"] = "list";
  58. int chunks;
  59. if (fileManager.getRemainingListChunks() > 0) {
  60. response.json["accept"] = false;
  61. response.json["chunks"] = -1;
  62. response.json["items"] = -1;
  63. response.json["error"] = "there is already an open list command";
  64. } else if ((chunks = fileManager.openList()) == -1) { // TODO do we need to check? maybe. Think about it
  65. response.json["accept"] = false;
  66. response.json["chunks"] = -1;
  67. response.json["items"] = -1;
  68. response.json["error"] = "there is a filename which is too long";
  69. } else {
  70. response.json["accept"] = true;
  71. response.json["chunks"] = chunks;
  72. response.json["items"] = fileManager.getListSize();
  73. response.json["error"] = "";
  74. }
  75. return response;
  76. }
  77. JsonCommander::Response JsonCommander::executeListData(const Json::Value &message) {
  78. JsonCommander::Response response;
  79. response.action = send;
  80. response.json["command"] = "listdata";
  81. Json::Value array;
  82. const int remainingListchunks = fileManager.getRemainingListChunks();
  83. if (!message["chunk"].isInt() || !message["cancel"].isBool()) {
  84. response.action = closeAndSend;
  85. response.json["cancel"] = true;
  86. response.json["remaining"] = -1;
  87. response.json["names"] = Json::arrayValue;
  88. response.json["error"] = "incorrect listdata command request";
  89. } else if (remainingListchunks == 0) {
  90. response.json["cancel"] = true;
  91. response.json["remaining"] = -1;
  92. response.json["names"] = Json::arrayValue;
  93. response.json["error"] = "there are no chunks to send";
  94. } else if (message["cancel"].asBool()) {
  95. response.json["cancel"] = true;
  96. response.json["remaining"] = message["chunk"].asInt(); // so it can be associated to the request
  97. response.json["names"] = Json::arrayValue;
  98. response.json["error"] = "";
  99. fileManager.cancelList();
  100. } else if (remainingListchunks - 1 != message["chunk"].asInt()) {
  101. response.action = closeAndSend;
  102. response.json["cancel"] = true;
  103. response.json["remaining"] = -1;
  104. response.json["names"] = Json::arrayValue;
  105. response.json["error"] = "wrong chunk number";
  106. } else {
  107. std::vector<std::string> v = fileManager.getNextChunkFromList();
  108. for (int i = 0; i < v.size(); i++)
  109. array.append(v.at(i));
  110. response.json["remaining"] = message["chunk"].asInt();
  111. response.json["cancel"] = false;
  112. response.json["names"] = array;
  113. response.json["error"] = "";
  114. }
  115. return response;
  116. }
  117. JsonCommander::Response JsonCommander::executePut(const Json::Value &message) {
  118. JsonCommander::Response response;
  119. response.json["command"] = "put";
  120. response.json["file"] = message["file"].asString();
  121. if (!message["file"].isString() || !message["size"].isInt() || !message["chunks"].isInt()) {
  122. // if request is incomplete close connection
  123. response.action = closeAndSend;
  124. response.json["accept"] = false;
  125. response.json["error"] = "incorrect put command request";
  126. } else if (fileManager.isUploading()) {
  127. // if an upload is alread running deny request
  128. response.action = send;
  129. response.json["accept"] = false;
  130. response.json["error"] = "upload already running";
  131. } else if (message["chunks"].asInt() <= 0) {
  132. response.action = send;
  133. response.json["accept"] = false;
  134. response.json["error"] = "there must be at least one chunk";
  135. } else if (fileManager.checkFilename(message["file"].asString())) {
  136. // accept request
  137. response.action = send;
  138. bool opened = fileManager.openPutFile(message["file"].asString());
  139. if (opened) {
  140. response.json["accept"] = true;
  141. response.json["error"] = "";
  142. this->putFileReceived = message["chunks"].asInt();
  143. } else {
  144. response.json["accept"] = false;
  145. response.json["error"] = "file already exists";
  146. }
  147. } else {
  148. // deny request if file name is not valid
  149. response.action = send;
  150. response.json["accept"] = false;
  151. response.json["error"] = "invalid file name";
  152. }
  153. return response;
  154. }
  155. JsonCommander::Response JsonCommander::executePutdata(const Json::Value &message) {
  156. JsonCommander::Response response;
  157. response.json["command"] = "putdata";
  158. response.json["file"] = message["file"].asString();
  159. response.json["received"] = message["remaining"].asInt();
  160. if (!message["file"].isString() || !message["data"].isString() || !message["remaining"].isInt() || !message["cancel"].isBool()) {
  161. // if request is incomplete close connection
  162. response.action = closeAndSend;
  163. response.json["cancel"] = true;
  164. response.json["error"] = "incorrect putdata command request";
  165. this->fileManager.cancelPut();
  166. } else if (!fileManager.isUploading()) {
  167. // no upload running -> command
  168. response.action = send;
  169. response.json["cancel"] = true;
  170. response.json["error"] = "no upload running";
  171. } else if (message["cancel"].asBool()) {
  172. response.action = send;
  173. response.json["cancel"] = true;
  174. response.json["error"] = "";
  175. this->fileManager.cancelPut();
  176. } else if (message["file"].asString().compare(fileManager.getPutBaseFileName()) == 0) {
  177. if (--this->putFileReceived == message["remaining"].asInt()) {
  178. // accept request
  179. response.action = send;
  180. response.json["cancel"] = false;
  181. response.json["error"] = "";
  182. const std::vector<char> data = base64::decode<std::vector<char>>(message["data"].asString());
  183. fileManager.writePut(data);
  184. this->putFileReceived = message["remaining"].asInt();
  185. if (this->putFileReceived == 0) {
  186. // close file after last chunk was received
  187. this->fileManager.closePutFile();
  188. }
  189. } else {
  190. // wrong remaining number
  191. response.action = send;
  192. response.json["cancel"] = true;
  193. response.json["error"] = "wrong remaining number";
  194. this->fileManager.cancelPut();
  195. }
  196. } else {
  197. // wrong file name
  198. response.action = send;
  199. response.json["cancel"] = true;
  200. response.json["error"] = "another file was already being uploaded";
  201. this->fileManager.cancelPut();
  202. }
  203. return response;
  204. }
  205. JsonCommander::Response JsonCommander::executeGet(const Json::Value &message) {
  206. JsonCommander::Response response;
  207. response.json["command"] = "get";
  208. response.json["file"] = message["file"].asString();
  209. if (!message["file"].isString()) {
  210. // if request is incomplete close connection
  211. response.action = closeAndSend;
  212. response.json["accept"] = false;
  213. response.json["chunks"] = -1;
  214. response.json["error"] = "incorrect get command request";
  215. } else if (fileManager.isDownloading()) {
  216. // if an upload is alread running deny request
  217. response.action = send;
  218. response.json["accept"] = false;
  219. response.json["chunks"] = -1;
  220. response.json["error"] = "download already running";
  221. } else if (fileManager.checkFilename(message["file"].asString())) {
  222. // accept request
  223. response.action = send;
  224. std::pair<bool, int> opened = fileManager.openGetFile(message["file"].asString());
  225. if (opened.first) {
  226. this->getFileRemaining = opened.second;
  227. response.json["accept"] = true;
  228. response.json["chunks"] = this->getFileRemaining;
  229. response.json["error"] = "";
  230. } else {
  231. response.json["accept"] = false;
  232. response.json["chunks"] = -1;
  233. response.json["error"] = "file does not exist";
  234. }
  235. } else {
  236. // deny request if file name is not valid
  237. response.action = send;
  238. response.json["accept"] = false;
  239. response.json["chunks"] = -1;
  240. response.json["error"] = "invalid file name";
  241. }
  242. return response;
  243. }
  244. JsonCommander::Response JsonCommander::executeGetdata(const Json::Value &message) {
  245. JsonCommander::Response response;
  246. response.json["command"] = "getdata";
  247. response.json["file"] = message["file"].asString();
  248. response.json["remaining"] = message["chunk"].asInt();
  249. if (!message["file"].isString() || !message["chunk"].isInt() || !message["cancel"].isBool()) {
  250. // if request is incomplete close connection
  251. response.action = closeAndSend;
  252. response.json["cancel"] = true;
  253. response.json["data"] = "";
  254. response.json["error"] = "incorrect putdata command request";
  255. this->fileManager.closeGetFile();
  256. } else if (!fileManager.isDownloading()) {
  257. // no upload running -> command
  258. response.action = send;
  259. response.json["cancel"] = true;
  260. response.json["data"] = "";
  261. response.json["error"] = "no download running";
  262. } else if (message["cancel"].asBool()) {
  263. response.action = send;
  264. response.json["cancel"] = true;
  265. response.json["data"] = "";
  266. response.json["error"] = "";
  267. this->fileManager.closeGetFile();
  268. } else if (message["file"].asString().compare(fileManager.getGetBaseFileName()) == 0) {
  269. if (--this->getFileRemaining == message["chunk"].asInt()) {
  270. // accept request
  271. response.action = send;
  272. response.json["cancel"] = false;
  273. response.json["error"] = "";
  274. const std::vector<char> data = fileManager.readGet();
  275. response.json["data"] = base64::encode<std::vector<char>>(data);
  276. fileManager.writePut(data);
  277. if (this->getFileRemaining == 0) {
  278. // close file after last chunk was sent
  279. this->fileManager.closeGetFile();
  280. }
  281. } else {
  282. // wrong chunk number
  283. response.action = send;
  284. response.json["cancel"] = true;
  285. response.json["data"] = "";
  286. response.json["error"] = "wrong chunk number";
  287. this->fileManager.closeGetFile();
  288. }
  289. } else {
  290. // wrong file name
  291. response.action = send;
  292. response.json["cancel"] = true;
  293. response.json["data"] = "";
  294. response.json["error"] = "another file was already being downloaded";
  295. this->fileManager.closeGetFile();
  296. }
  297. return response;
  298. }
  299. JsonCommander::Response JsonCommander::executeHead(const Json::Value &message) {
  300. JsonCommander::Response response;
  301. response.action = send;
  302. response.json["command"] = "head";
  303. if (!message["file"].isString()) {
  304. response.json["accept"] = false;
  305. response.json["file"] = "";
  306. response.json["data"] = "";
  307. response.json["error"] = "incorrect head command request";
  308. } else {
  309. std::pair<std::vector<char>, FileManager::Error> res = fileManager.getBytesFromFile(message["file"].asString(), 4);
  310. switch (res.second) {
  311. case FileManager::Error::no_error:
  312. response.json["accept"] = true;
  313. response.json["file"] = message["file"].asString();
  314. response.json["data"] = base64::encode<std::vector<char>>(res.first);
  315. response.json["error"] = "";
  316. break;
  317. case FileManager::Error::no_such_file:
  318. response.json["accept"] = false;
  319. response.json["file"] = message["file"].asString();
  320. response.json["data"] = "";
  321. response.json["error"] = "no such file";
  322. break;
  323. case FileManager::Error::file_too_small:
  324. response.json["accept"] = false;
  325. response.json["file"] = message["file"].asString();
  326. response.json["data"] = "";
  327. response.json["error"] = "file is smaller than specified size";
  328. break;
  329. default:
  330. response.action = closeAndSend;
  331. response.json["accept"] = false;
  332. response.json["file"] = message["file"];
  333. response.json["data"] = "";
  334. response.json["error"] = "internal error. Please fix this!!!";
  335. }
  336. }
  337. return response;
  338. }
  339. JsonCommander::Response JsonCommander::executeDeleteMe(const Json::Value &message) {
  340. JsonCommander::Response response;
  341. response.json["command"] = "deleteme";
  342. if (!message["pass"].isString()) {
  343. response.action = closeAndSend;
  344. response.json["accept"] = false;
  345. response.json["error"] = "incorrect deleteme command request";
  346. } else if (UserManager::deleteUser(currentUser, message["pass"].asString())) {
  347. // success
  348. response.action = closeAndSend;
  349. response.json["accept"] = true;
  350. response.json["error"] = "";
  351. } else {
  352. response.action = send;
  353. response.json["accept"] = false;
  354. response.json["error"] = "wrong password";
  355. }
  356. return response;
  357. }
  358. JsonCommander::Response JsonCommander::testVersion(const Json::Value &message) {
  359. JsonCommander::Response response;
  360. response.json["major"] = this->protocolMajorVersion;
  361. response.json["minor"] = this->protocolMinorVersion;
  362. if (!message["major"].isInt() || !message["minor"].isInt()) {
  363. response.action = closeAndSend;
  364. response.json["accept"] = false;
  365. } else if (message["major"].asInt() == this->protocolMajorVersion && message["minor"].asInt() <= this->protocolMinorVersion) {
  366. response.action = send;
  367. response.json["accept"] = true;
  368. } else {
  369. response.action = closeAndSend;
  370. response.json["accept"] = false;
  371. }
  372. return response;
  373. }
  374. JsonCommander::Response JsonCommander::checkLogin(const Json::Value &message) {
  375. JsonCommander::Response response;
  376. if (!message["login"].isBool() || !message["user"].isString() || !message["pass"].isString() || !message["cancel"].isBool()) {
  377. // invalid login request
  378. response.action = closeAndSend;
  379. response.json["accept"] = false;
  380. response.json["error"] = "invalid login request";
  381. } else if (message["cancel"].asBool()) {
  382. response.action = close;
  383. } else if (message["login"].asBool() && UserManager::isAllowed(message["user"].asString(), message["pass"].asString())) {
  384. // credential check
  385. response.action = send;
  386. response.json["accept"] = true;
  387. response.json["error"] = "";
  388. currentUser = message["user"].asString();
  389. } else if (!message["login"].asBool()) {
  390. // add user. Check if already exists before
  391. if (!UserManager::addUser(message["user"].asString(), message["pass"].asString())) {
  392. response.action = closeAndSend;
  393. response.json["accept"] = false;
  394. response.json["error"] = "user does already exist";
  395. } else {
  396. response.action = send;
  397. response.json["accept"] = true;
  398. response.json["error"] = "";
  399. currentUser = message["user"].asString();
  400. }
  401. } else {
  402. // reject user
  403. response.action = closeAndSend;
  404. response.json["accept"] = false;
  405. response.json["error"] = "wrong username or password";
  406. }
  407. return response;
  408. }
  409. JsonCommander::Response JsonCommander::executeDeleteFile(const Json::Value &message) {
  410. JsonCommander::Response response;
  411. response.json["command"] = "deletefile";
  412. if (!message["file"].isString()) {
  413. response.action = closeAndSend;
  414. response.json["accept"] = false;
  415. response.json["error"] = "incorrect deletefile command request";
  416. response.json["file"] = "";
  417. } else {
  418. response.action = send;
  419. FileManager::Error err = fileManager.deleteFile(message["file"].asString());
  420. switch (err) {
  421. case FileManager::Error::no_error:
  422. response.json["accept"] = true;
  423. response.json["error"] = "";
  424. response.json["file"] = message["file"];
  425. break;
  426. case FileManager::Error::not_allowed:
  427. response.json["accept"] = false;
  428. response.json["error"] = "deleting files is disabled";
  429. response.json["file"] = message["file"];
  430. break;
  431. case FileManager::Error::no_such_file:
  432. response.json["accept"] = false;
  433. response.json["error"] = "no such file";
  434. response.json["file"] = message["file"];
  435. break;
  436. default:
  437. response.action = closeAndSend;
  438. response.json["accept"] = false;
  439. response.json["error"] = "internal error. Please fix this!!!";
  440. response.json["file"] = message["file"];
  441. }
  442. }
  443. return response;
  444. }