JsonCommander.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  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["put"] = &JsonCommander::executePut;
  10. commandsMap["putdata"] = &JsonCommander::executePutdata;
  11. commandsMap["get"] = &JsonCommander::executeGet;
  12. commandsMap["getdata"] = &JsonCommander::executeGetdata;
  13. }
  14. JsonCommander::~JsonCommander() {}
  15. JsonCommander::Response JsonCommander::execute(const Json::Value &message) {
  16. JsonCommander::Response response;
  17. Response (JsonCommander::*commandExecutor)(const Json::Value &) =
  18. commandsMap[message["command"].asString()];
  19. if (commandExecutor != nullptr) {
  20. response = (this->*commandExecutor)(message);
  21. } else {
  22. // command does not exist
  23. response.action = close;
  24. }
  25. return response;
  26. }
  27. JsonCommander::Response
  28. JsonCommander::executeStatus(const Json::Value &message) {
  29. JsonCommander::Response response;
  30. response.action = send;
  31. response.json["command"] = "status";
  32. // answer a real status message
  33. std::string status;
  34. if (this->fileManager.isUploading() && this->fileManager.isDownloading()) {
  35. status = "download and upload running";
  36. } else if (this->fileManager.isUploading()) {
  37. status = "upload running";
  38. } else if (this->fileManager.isDownloading()) {
  39. status = "download running";
  40. } else {
  41. status = "ok";
  42. }
  43. response.json["response"] = status;
  44. return response;
  45. }
  46. JsonCommander::Response
  47. 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. // TODO return real file list
  59. Json::Value array;
  60. array.append("some");
  61. array.append("important");
  62. array.append("data");
  63. response.json["names"] = array;
  64. response.json["remaining"] = 0;
  65. return response;
  66. }
  67. JsonCommander::Response JsonCommander::executePut(const Json::Value &message) {
  68. JsonCommander::Response response;
  69. response.json["command"] = "put";
  70. response.json["file"] = message["file"].asString();
  71. if (!message["file"].isString() || !message["size"].isInt() ||
  72. !message["chunks"].isInt()) {
  73. // if request is incomplete close connection
  74. response.action = closeAndSend;
  75. response.json["accept"] = false;
  76. response.json["error"] = "incorrect put command request";
  77. } else if (fileManager.isUploading()) {
  78. // if an upload is alread running deny request
  79. response.action = send;
  80. response.json["accept"] = false;
  81. response.json["error"] = "upload already running";
  82. } else if (message["chunks"].asInt() <= 0) {
  83. response.action = send;
  84. response.json["accept"] = false;
  85. response.json["error"] = "there must be at least one chunk";
  86. } else if (fileManager.checkFilename(message["file"].asString())) {
  87. // accept request
  88. response.action = send;
  89. bool opened = fileManager.openPutFile(message["file"].asString());
  90. if (opened) {
  91. response.json["accept"] = true;
  92. response.json["error"] = "";
  93. this->putFileReceived = message["chunks"].asInt();
  94. } else {
  95. response.json["accept"] = false;
  96. response.json["error"] = "file already exists";
  97. }
  98. } else {
  99. // deny request if file name is not valid
  100. response.action = send;
  101. response.json["accept"] = false;
  102. response.json["error"] = "invalid file name";
  103. }
  104. return response;
  105. }
  106. JsonCommander::Response
  107. JsonCommander::executePutdata(const Json::Value &message) {
  108. JsonCommander::Response response;
  109. response.json["command"] = "putdata";
  110. response.json["file"] = message["file"].asString();
  111. response.json["received"] = message["remaining"].asInt();
  112. if (!message["file"].isString() || !message["data"].isString() ||
  113. !message["remaining"].isInt() || !message["cancel"].isBool()) {
  114. // if request is incomplete close connection
  115. response.action = closeAndSend;
  116. response.json["cancel"] = true;
  117. response.json["error"] = "incorrect putdata command request";
  118. this->fileManager.cancelPut();
  119. } else if (!fileManager.isUploading()) {
  120. // no upload running -> command
  121. response.action = send;
  122. response.json["cancel"] = true;
  123. response.json["error"] = "no upload running";
  124. } else if (message["cancel"].asBool()) {
  125. response.action = send;
  126. response.json["cancel"] = true;
  127. response.json["error"] = "";
  128. this->fileManager.cancelPut();
  129. } else if (message["file"].asString().compare(
  130. fileManager.getPutBaseFileName()) == 0) {
  131. if (--this->putFileReceived == message["remaining"].asInt()) {
  132. // accept request
  133. response.action = send;
  134. response.json["cancel"] = false;
  135. response.json["error"] = "";
  136. const std::vector<char> data =
  137. base64::decodeVector(message["data"].asString());
  138. fileManager.writePut(data);
  139. this->putFileReceived = message["remaining"].asInt();
  140. if (this->putFileReceived == 0) {
  141. // close file after last chunk was received
  142. this->fileManager.closePutFile();
  143. }
  144. } else {
  145. // wrong remaining number
  146. response.action = send;
  147. response.json["cancel"] = true;
  148. response.json["error"] = "wrong remaining number";
  149. this->fileManager.cancelPut();
  150. }
  151. } else {
  152. // wrong file name
  153. response.action = send;
  154. response.json["cancel"] = true;
  155. response.json["error"] = "another file was already being uploaded";
  156. this->fileManager.cancelPut();
  157. }
  158. return response;
  159. }
  160. JsonCommander::Response JsonCommander::executeGet(const Json::Value &message) {
  161. JsonCommander::Response response;
  162. response.json["command"] = "get";
  163. response.json["file"] = message["file"].asString();
  164. if (!message["file"].isString()) {
  165. // if request is incomplete close connection
  166. response.action = closeAndSend;
  167. response.json["accept"] = false;
  168. response.json["chunks"] = -1;
  169. response.json["error"] = "incorrect get command request";
  170. } else if (fileManager.isDownloading()) {
  171. // if an upload is alread running deny request
  172. response.action = send;
  173. response.json["accept"] = false;
  174. response.json["chunks"] = -1;
  175. response.json["error"] = "download already running";
  176. } else if (fileManager.checkFilename(message["file"].asString())) {
  177. // accept request
  178. response.action = send;
  179. bool opened = fileManager.openGetFile(message["file"].asString(),
  180. this->getFileRemaining);
  181. if (opened) {
  182. response.json["accept"] = true;
  183. response.json["chunks"] = this->getFileRemaining;
  184. response.json["error"] = "";
  185. } else {
  186. response.json["accept"] = false;
  187. response.json["chunks"] = -1;
  188. response.json["error"] = "file does not exist";
  189. }
  190. } else {
  191. // deny request if file name is not valid
  192. response.action = send;
  193. response.json["accept"] = false;
  194. response.json["chunks"] = -1;
  195. response.json["error"] = "invalid file name";
  196. }
  197. return response;
  198. }
  199. JsonCommander::Response
  200. JsonCommander::executeGetdata(const Json::Value &message) {
  201. JsonCommander::Response response;
  202. response.json["command"] = "getdata";
  203. response.json["file"] = message["file"].asString();
  204. response.json["remaining"] = message["chunk"].asInt();
  205. if (!message["file"].isString() || !message["chunk"].isInt() ||
  206. !message["cancel"].isBool()) {
  207. // if request is incomplete close connection
  208. response.action = closeAndSend;
  209. response.json["cancel"] = true;
  210. response.json["data"] = "";
  211. response.json["error"] = "incorrect putdata command request";
  212. this->fileManager.closeGetFile();
  213. } else if (!fileManager.isDownloading()) {
  214. // no upload running -> command
  215. response.action = send;
  216. response.json["cancel"] = true;
  217. response.json["data"] = "";
  218. response.json["error"] = "no download running";
  219. } else if (message["cancel"].asBool()) {
  220. response.action = send;
  221. response.json["cancel"] = true;
  222. response.json["data"] = "";
  223. response.json["error"] = "";
  224. this->fileManager.closeGetFile();
  225. } else if (message["file"].asString().compare(
  226. fileManager.getGetBaseFileName()) == 0) {
  227. if (--this->getFileRemaining == message["chunk"].asInt()) {
  228. // accept request
  229. response.action = send;
  230. response.json["cancel"] = false;
  231. response.json["error"] = "";
  232. const std::vector<char> data = fileManager.readGet();
  233. response.json["data"] = base64::encodeVector(data);
  234. fileManager.writePut(data);
  235. if (this->getFileRemaining == 0) {
  236. // close file after last chunk was sent
  237. this->fileManager.closeGetFile();
  238. }
  239. } else {
  240. // wrong chunk number
  241. response.action = send;
  242. response.json["cancel"] = true;
  243. response.json["data"] = "";
  244. response.json["error"] = "wrong chunk number";
  245. this->fileManager.closeGetFile();
  246. }
  247. } else {
  248. // wrong file name
  249. response.action = send;
  250. response.json["cancel"] = true;
  251. response.json["data"] = "";
  252. response.json["error"] = "another file was already being downloaded";
  253. this->fileManager.closeGetFile();
  254. }
  255. return response;
  256. }
  257. JsonCommander::Response JsonCommander::testVersion(const Json::Value &message) {
  258. JsonCommander::Response response;
  259. response.json["version"] = this->protocolVersion;
  260. // check version string is the same
  261. if (message["version"].asString().compare(this->protocolVersion) == 0) {
  262. response.action = send;
  263. response.json["accept"] = true;
  264. } else {
  265. response.action = closeAndSend;
  266. response.json["accept"] = false;
  267. }
  268. return response;
  269. }
  270. JsonCommander::Response JsonCommander::checkLogin(const Json::Value &message) {
  271. JsonCommander::Response response;
  272. if (!message["login"].isBool() || !message["user"].isString() ||
  273. !message["pass"].isString() || !message["cancel"].isBool()) {
  274. // invalid login request
  275. response.action = closeAndSend;
  276. response.json["accept"] = false;
  277. response.json["error"] = "invalid login request";
  278. } else if (message["cancel"].asBool()) {
  279. response.action = close;
  280. } else if (message["login"].asBool() &&
  281. UserManager::isAllowed(message["user"].asString(),
  282. message["pass"].asString())) {
  283. // credential check
  284. response.action = send;
  285. response.json["accept"] = true;
  286. response.json["error"] = "";
  287. } else if (!message["login"].asBool()) {
  288. // TODO implement registration
  289. response.action = closeAndSend;
  290. response.json["accept"] = false;
  291. response.json["error"] = "registration is not yet implemented";
  292. } else {
  293. response.action = closeAndSend;
  294. response.json["accept"] = false;
  295. response.json["error"] = "wrong username or password";
  296. }
  297. return response;
  298. }