JsonCommander.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. #include "../include/JsonCommander.h"
  2. #include "../include/UserManager.h"
  3. #include "../include/base64.h"
  4. JsonCommander::JsonCommander(FileManager &fileManager)
  5. : fileManager(fileManager) {
  6. commandsMap["status"] = &JsonCommander::executeStatus;
  7. commandsMap["close"] = &JsonCommander::executeClose;
  8. commandsMap["list"] = &JsonCommander::executeList;
  9. commandsMap["listdata"] = &JsonCommander::executeListData;
  10. commandsMap["put"] = &JsonCommander::executePut;
  11. commandsMap["putdata"] = &JsonCommander::executePutdata;
  12. commandsMap["get"] = &JsonCommander::executeGet;
  13. commandsMap["getdata"] = &JsonCommander::executeGetdata;
  14. }
  15. JsonCommander::~JsonCommander() {}
  16. JsonCommander::Response JsonCommander::execute(const Json::Value &message) {
  17. JsonCommander::Response response;
  18. Response (JsonCommander::*commandExecutor)(const Json::Value &) =
  19. commandsMap[message["command"].asString()];
  20. if (commandExecutor != nullptr) {
  21. response = (this->*commandExecutor)(message);
  22. } else {
  23. // command does not exist
  24. response.action = close;
  25. }
  26. return response;
  27. }
  28. JsonCommander::Response
  29. 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
  48. JsonCommander::executeClose(const Json::Value &message) {
  49. JsonCommander::Response response;
  50. response.action = closeAndSend;
  51. response.json["command"] = "close";
  52. response.json["response"] = "bye";
  53. return response;
  54. }
  55. JsonCommander::Response JsonCommander::executeList(const Json::Value &message) {
  56. JsonCommander::Response response;
  57. response.action = send;
  58. response.json["command"] = "list";
  59. int chunks;
  60. if (fileManager.getRemainingListChunks() > 0) {
  61. response.json["accept"] = false;
  62. response.json["chunks"] = -1;
  63. response.json["items"] = -1;
  64. response.json["error"] = "there is already an open list command";
  65. } else if ((chunks = fileManager.openList()) ==
  66. -1) { // TODO do we need to check? maybe. Think about it
  67. response.json["accept"] = false;
  68. response.json["chunks"] = -1;
  69. response.json["items"] = -1;
  70. response.json["error"] = "there is a filename which is too long";
  71. } else {
  72. response.json["accept"] = true;
  73. response.json["chunks"] = chunks;
  74. response.json["items"] = fileManager.getListSize();
  75. response.json["error"] = "";
  76. }
  77. return response;
  78. }
  79. JsonCommander::Response
  80. JsonCommander::executeListData(const Json::Value &message) {
  81. JsonCommander::Response response;
  82. response.action = send;
  83. response.json["command"] = "listdata";
  84. Json::Value array;
  85. const int remainingListchunks = fileManager.getRemainingListChunks();
  86. if (!message["chunk"].isInt() || !message["cancel"].isBool()) {
  87. response.action = closeAndSend;
  88. response.json["cancel"] = true;
  89. response.json["remaining"] = -1;
  90. response.json["names"] = Json::arrayValue;
  91. response.json["error"] = "incorrect listdata command request";
  92. } else if (remainingListchunks == 0) {
  93. response.json["cancel"] = true;
  94. response.json["remaining"] = -1;
  95. response.json["names"] = Json::arrayValue;
  96. response.json["error"] = "there are no chunks to send";
  97. } else if (message["cancel"].asBool()) {
  98. response.json["cancel"] = true;
  99. response.json["remaining"] =
  100. message["chunk"].asInt(); // so it can be associated to the request
  101. response.json["names"] = Json::arrayValue;
  102. response.json["error"] = "";
  103. fileManager.cancelList();
  104. } else if (remainingListchunks - 1 != message["chunk"].asInt()) {
  105. response.action = closeAndSend;
  106. response.json["cancel"] = true;
  107. response.json["remaining"] = -1;
  108. response.json["names"] = Json::arrayValue;
  109. response.json["error"] = "wrong chunk number";
  110. } else {
  111. std::vector<std::string> v = fileManager.getNextChunkFromList();
  112. for (int i = 0; i < v.size(); i++)
  113. array.append(v.at(i));
  114. response.json["remaining"] = message["chunk"].asInt();
  115. response.json["cancel"] = false;
  116. response.json["names"] = array;
  117. response.json["error"] = "";
  118. }
  119. return response;
  120. }
  121. JsonCommander::Response JsonCommander::executePut(const Json::Value &message) {
  122. JsonCommander::Response response;
  123. response.json["command"] = "put";
  124. response.json["file"] = message["file"].asString();
  125. if (!message["file"].isString() || !message["size"].isInt() ||
  126. !message["chunks"].isInt()) {
  127. // if request is incomplete close connection
  128. response.action = closeAndSend;
  129. response.json["accept"] = false;
  130. response.json["error"] = "incorrect put command request";
  131. } else if (fileManager.isUploading()) {
  132. // if an upload is alread running deny request
  133. response.action = send;
  134. response.json["accept"] = false;
  135. response.json["error"] = "upload already running";
  136. } else if (message["chunks"].asInt() <= 0) {
  137. response.action = send;
  138. response.json["accept"] = false;
  139. response.json["error"] = "there must be at least one chunk";
  140. } else if (fileManager.checkFilename(message["file"].asString())) {
  141. // accept request
  142. response.action = send;
  143. bool opened = fileManager.openPutFile(message["file"].asString());
  144. if (opened) {
  145. response.json["accept"] = true;
  146. response.json["error"] = "";
  147. this->putFileReceived = message["chunks"].asInt();
  148. } else {
  149. response.json["accept"] = false;
  150. response.json["error"] = "file already exists";
  151. }
  152. } else {
  153. // deny request if file name is not valid
  154. response.action = send;
  155. response.json["accept"] = false;
  156. response.json["error"] = "invalid file name";
  157. }
  158. return response;
  159. }
  160. JsonCommander::Response
  161. JsonCommander::executePutdata(const Json::Value &message) {
  162. JsonCommander::Response response;
  163. response.json["command"] = "putdata";
  164. response.json["file"] = message["file"].asString();
  165. response.json["received"] = message["remaining"].asInt();
  166. if (!message["file"].isString() || !message["data"].isString() ||
  167. !message["remaining"].isInt() || !message["cancel"].isBool()) {
  168. // if request is incomplete close connection
  169. response.action = closeAndSend;
  170. response.json["cancel"] = true;
  171. response.json["error"] = "incorrect putdata command request";
  172. this->fileManager.cancelPut();
  173. } else if (!fileManager.isUploading()) {
  174. // no upload running -> command
  175. response.action = send;
  176. response.json["cancel"] = true;
  177. response.json["error"] = "no upload running";
  178. } else if (message["cancel"].asBool()) {
  179. response.action = send;
  180. response.json["cancel"] = true;
  181. response.json["error"] = "";
  182. this->fileManager.cancelPut();
  183. } else if (message["file"].asString().compare(
  184. fileManager.getPutBaseFileName()) == 0) {
  185. if (--this->putFileReceived == message["remaining"].asInt()) {
  186. // accept request
  187. response.action = send;
  188. response.json["cancel"] = false;
  189. response.json["error"] = "";
  190. const std::vector<char> data =
  191. base64::decodeVector(message["data"].asString());
  192. fileManager.writePut(data);
  193. this->putFileReceived = message["remaining"].asInt();
  194. if (this->putFileReceived == 0) {
  195. // close file after last chunk was received
  196. this->fileManager.closePutFile();
  197. }
  198. } else {
  199. // wrong remaining number
  200. response.action = send;
  201. response.json["cancel"] = true;
  202. response.json["error"] = "wrong remaining number";
  203. this->fileManager.cancelPut();
  204. }
  205. } else {
  206. // wrong file name
  207. response.action = send;
  208. response.json["cancel"] = true;
  209. response.json["error"] = "another file was already being uploaded";
  210. this->fileManager.cancelPut();
  211. }
  212. return response;
  213. }
  214. JsonCommander::Response JsonCommander::executeGet(const Json::Value &message) {
  215. JsonCommander::Response response;
  216. response.json["command"] = "get";
  217. response.json["file"] = message["file"].asString();
  218. if (!message["file"].isString()) {
  219. // if request is incomplete close connection
  220. response.action = closeAndSend;
  221. response.json["accept"] = false;
  222. response.json["chunks"] = -1;
  223. response.json["error"] = "incorrect get command request";
  224. } else if (fileManager.isDownloading()) {
  225. // if an upload is alread running deny request
  226. response.action = send;
  227. response.json["accept"] = false;
  228. response.json["chunks"] = -1;
  229. response.json["error"] = "download already running";
  230. } else if (fileManager.checkFilename(message["file"].asString())) {
  231. // accept request
  232. response.action = send;
  233. bool opened = fileManager.openGetFile(message["file"].asString(),
  234. this->getFileRemaining);
  235. if (opened) {
  236. response.json["accept"] = true;
  237. response.json["chunks"] = this->getFileRemaining;
  238. response.json["error"] = "";
  239. } else {
  240. response.json["accept"] = false;
  241. response.json["chunks"] = -1;
  242. response.json["error"] = "file does not exist";
  243. }
  244. } else {
  245. // deny request if file name is not valid
  246. response.action = send;
  247. response.json["accept"] = false;
  248. response.json["chunks"] = -1;
  249. response.json["error"] = "invalid file name";
  250. }
  251. return response;
  252. }
  253. JsonCommander::Response
  254. JsonCommander::executeGetdata(const Json::Value &message) {
  255. JsonCommander::Response response;
  256. response.json["command"] = "getdata";
  257. response.json["file"] = message["file"].asString();
  258. response.json["remaining"] = message["chunk"].asInt();
  259. if (!message["file"].isString() || !message["chunk"].isInt() ||
  260. !message["cancel"].isBool()) {
  261. // if request is incomplete close connection
  262. response.action = closeAndSend;
  263. response.json["cancel"] = true;
  264. response.json["data"] = "";
  265. response.json["error"] = "incorrect putdata command request";
  266. this->fileManager.closeGetFile();
  267. } else if (!fileManager.isDownloading()) {
  268. // no upload running -> command
  269. response.action = send;
  270. response.json["cancel"] = true;
  271. response.json["data"] = "";
  272. response.json["error"] = "no download running";
  273. } else if (message["cancel"].asBool()) {
  274. response.action = send;
  275. response.json["cancel"] = true;
  276. response.json["data"] = "";
  277. response.json["error"] = "";
  278. this->fileManager.closeGetFile();
  279. } else if (message["file"].asString().compare(
  280. fileManager.getGetBaseFileName()) == 0) {
  281. if (--this->getFileRemaining == message["chunk"].asInt()) {
  282. // accept request
  283. response.action = send;
  284. response.json["cancel"] = false;
  285. response.json["error"] = "";
  286. const std::vector<char> data = fileManager.readGet();
  287. response.json["data"] = base64::encodeVector(data);
  288. fileManager.writePut(data);
  289. if (this->getFileRemaining == 0) {
  290. // close file after last chunk was sent
  291. this->fileManager.closeGetFile();
  292. }
  293. } else {
  294. // wrong chunk number
  295. response.action = send;
  296. response.json["cancel"] = true;
  297. response.json["data"] = "";
  298. response.json["error"] = "wrong chunk number";
  299. this->fileManager.closeGetFile();
  300. }
  301. } else {
  302. // wrong file name
  303. response.action = send;
  304. response.json["cancel"] = true;
  305. response.json["data"] = "";
  306. response.json["error"] = "another file was already being downloaded";
  307. this->fileManager.closeGetFile();
  308. }
  309. return response;
  310. }
  311. JsonCommander::Response JsonCommander::testVersion(const Json::Value &message) {
  312. JsonCommander::Response response;
  313. response.json["version"] = this->protocolVersion;
  314. // check version string is the same
  315. if (message["version"].asString().compare(this->protocolVersion) == 0) {
  316. response.action = send;
  317. response.json["accept"] = true;
  318. } else {
  319. response.action = closeAndSend;
  320. response.json["accept"] = false;
  321. }
  322. return response;
  323. }
  324. JsonCommander::Response JsonCommander::checkLogin(const Json::Value &message) {
  325. JsonCommander::Response response;
  326. if (!message["login"].isBool() || !message["user"].isString() ||
  327. !message["pass"].isString() || !message["cancel"].isBool()) {
  328. // invalid login request
  329. response.action = closeAndSend;
  330. response.json["accept"] = false;
  331. response.json["error"] = "invalid login request";
  332. } else if (message["cancel"].asBool()) {
  333. response.action = close;
  334. } else if (message["login"].asBool() &&
  335. UserManager::isAllowed(message["user"].asString(),
  336. message["pass"].asString())) {
  337. // credential check
  338. response.action = send;
  339. response.json["accept"] = true;
  340. response.json["error"] = "";
  341. } else if (!message["login"].asBool()) {
  342. // add user. Check if already exists before
  343. if (!UserManager::addUser(message["user"].asString(),
  344. message["pass"].asString())) {
  345. response.action = closeAndSend;
  346. response.json["accept"] = false;
  347. response.json["error"] = "user does already exist";
  348. } else {
  349. response.action = send;
  350. response.json["accept"] = true;
  351. response.json["error"] = "";
  352. }
  353. } else {
  354. // reject user
  355. response.action = closeAndSend;
  356. response.json["accept"] = false;
  357. response.json["error"] = "wrong username or password";
  358. }
  359. return response;
  360. }