The next generation of the Teknik Services. Written in ASP.NET. https://www.teknik.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

VaultController.cs 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. using Microsoft.AspNetCore.Authorization;
  2. using Microsoft.AspNetCore.Http;
  3. using Microsoft.AspNetCore.Mvc;
  4. using Microsoft.EntityFrameworkCore;
  5. using Microsoft.Extensions.Logging;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Web;
  10. using Teknik.Areas.Paste;
  11. using Teknik.Areas.Users.Models;
  12. using Teknik.Areas.Users.Utility;
  13. using Teknik.Areas.Vault.Models;
  14. using Teknik.Areas.Vault.ViewModels;
  15. using Teknik.Attributes;
  16. using Teknik.Configuration;
  17. using Teknik.Controllers;
  18. using Teknik.Data;
  19. using Teknik.Filters;
  20. using Teknik.Logging;
  21. using Teknik.Models;
  22. using Teknik.Utilities;
  23. namespace Teknik.Areas.Vault.Controllers
  24. {
  25. [TeknikAuthorize]
  26. [Area("Vault")]
  27. public class VaultController : DefaultController
  28. {
  29. public VaultController(ILogger<Logger> logger, Config config, TeknikEntities dbContext) : base(logger, config, dbContext) { }
  30. [AllowAnonymous]
  31. public IActionResult ViewVault(string id)
  32. {
  33. Models.Vault foundVault = _dbContext.Vaults.Where(v => v.Url == id).FirstOrDefault();
  34. if (foundVault != null)
  35. {
  36. // Update view count
  37. foundVault.Views += 1;
  38. _dbContext.Entry(foundVault).State = EntityState.Modified;
  39. _dbContext.SaveChanges();
  40. ViewBag.Title = foundVault.Title + " - Teknik Vault";
  41. VaultViewModel model = new VaultViewModel();
  42. model.CurrentSub = Subdomain;
  43. model.Url = foundVault.Url;
  44. model.UserId = foundVault.UserId;
  45. model.User = foundVault.User;
  46. model.Title = foundVault.Title;
  47. model.Description = foundVault.Description;
  48. model.DateCreated = foundVault.DateCreated;
  49. model.DateEdited = foundVault.DateEdited;
  50. if (foundVault.VaultItems.Any())
  51. {
  52. foreach (VaultItem item in foundVault.VaultItems)
  53. {
  54. if (item.GetType().BaseType == typeof(UploadVaultItem))
  55. {
  56. UploadVaultItem upload = (UploadVaultItem)item;
  57. // Increment Views
  58. upload.Upload.Downloads += 1;
  59. _dbContext.Entry(upload.Upload).State = EntityState.Modified;
  60. _dbContext.SaveChanges();
  61. UploadItemViewModel uploadModel = new UploadItemViewModel();
  62. uploadModel.VaultItemId = item.VaultItemId;
  63. uploadModel.Title = item.Title;
  64. uploadModel.Description = item.Description;
  65. uploadModel.DateAdded = item.DateAdded;
  66. uploadModel.Upload = upload.Upload;
  67. model.Items.Add(uploadModel);
  68. }
  69. else if (item.GetType().BaseType == typeof(PasteVaultItem))
  70. {
  71. PasteVaultItem paste = (PasteVaultItem)item;
  72. // Increment Views
  73. paste.Paste.Views += 1;
  74. _dbContext.Entry(paste.Paste).State = EntityState.Modified;
  75. _dbContext.SaveChanges();
  76. // Check Expiration
  77. if (PasteHelper.CheckExpiration(paste.Paste))
  78. {
  79. _dbContext.Pastes.Remove(paste.Paste);
  80. _dbContext.SaveChanges();
  81. break;
  82. }
  83. PasteItemViewModel pasteModel = new PasteItemViewModel();
  84. pasteModel.VaultItemId = item.VaultItemId;
  85. pasteModel.Title = item.Title;
  86. pasteModel.Description = item.Description;
  87. pasteModel.DateAdded = item.DateAdded;
  88. pasteModel.Paste = paste.Paste;
  89. model.Items.Add(pasteModel);
  90. }
  91. }
  92. }
  93. return View(model);
  94. }
  95. return new StatusCodeResult(StatusCodes.Status404NotFound);
  96. }
  97. [HttpGet]
  98. [AllowAnonymous]
  99. public IActionResult NewVault()
  100. {
  101. ViewBag.Title = "Create Vault";
  102. ModifyVaultViewModel model = new ModifyVaultViewModel();
  103. model.CurrentSub = Subdomain;
  104. return View("~/Areas/Vault/Views/Vault/ModifyVault.cshtml", model);
  105. }
  106. [HttpGet]
  107. [AllowAnonymous]
  108. public IActionResult NewVaultFromService(string type, string items)
  109. {
  110. ViewBag.Title = "Create Vault";
  111. ModifyVaultViewModel model = new ModifyVaultViewModel();
  112. model.CurrentSub = Subdomain;
  113. string decodedItems = HttpUtility.UrlDecode(items);
  114. string[] allURLs = decodedItems.Split(',');
  115. int index = 0;
  116. foreach (string url in allURLs)
  117. {
  118. string[] urlInfo = url.Split(':');
  119. string uploadId = urlInfo[0];
  120. string title = string.Empty;
  121. if (urlInfo.GetUpperBound(0) >= 1)
  122. {
  123. // They also passed in the original filename, so let's use it as our title
  124. title = urlInfo[1];
  125. }
  126. if (IsValidItem(type, uploadId))
  127. {
  128. ModifyVaultItemViewModel item = new ModifyVaultItemViewModel();
  129. item.isTemplate = false;
  130. item.index = index;
  131. item.title = title;
  132. item.url = uploadId;
  133. item.type = type;
  134. model.items.Add(item);
  135. index++;
  136. }
  137. }
  138. return View("~/Areas/Vault/Views/Vault/ModifyVault.cshtml", model);
  139. }
  140. [HttpGet]
  141. public IActionResult EditVault(string url, string type, string items)
  142. {
  143. ViewBag.Title = "Edit Vault";
  144. Vault.Models.Vault foundVault = _dbContext.Vaults.Where(v => v.Url == url).FirstOrDefault();
  145. if (foundVault != null)
  146. {
  147. if (foundVault.User.Username == User.Identity.Name)
  148. {
  149. ViewBag.Title = "Edit Vault - " + foundVault.Title;
  150. ModifyVaultViewModel model = new ModifyVaultViewModel();
  151. model.CurrentSub = Subdomain;
  152. model.isEdit = true;
  153. model.vaultId = foundVault.VaultId;
  154. model.title = foundVault.Title;
  155. model.description = foundVault.Description;
  156. int index = 0;
  157. // Add all their existing items for the vault
  158. foreach (VaultItem item in foundVault.VaultItems)
  159. {
  160. ModifyVaultItemViewModel itemModel = new ModifyVaultItemViewModel();
  161. itemModel.index = index;
  162. itemModel.isTemplate = false;
  163. if (item.GetType().BaseType == typeof(UploadVaultItem))
  164. {
  165. UploadVaultItem upload = (UploadVaultItem)item;
  166. itemModel.title = upload.Title;
  167. itemModel.description = upload.Description;
  168. itemModel.type = "Upload";
  169. itemModel.url = upload.Upload.Url;
  170. model.items.Add(itemModel);
  171. index++;
  172. }
  173. else if (item.GetType().BaseType == typeof(PasteVaultItem))
  174. {
  175. PasteVaultItem paste = (PasteVaultItem)item;
  176. itemModel.title = paste.Title;
  177. itemModel.description = paste.Description;
  178. itemModel.type = "Paste";
  179. itemModel.url = paste.Paste.Url;
  180. model.items.Add(itemModel);
  181. index++;
  182. }
  183. }
  184. // If they passed any new items in via the parameters, let's add them
  185. if (!string.IsNullOrEmpty(type) && !string.IsNullOrEmpty(items))
  186. {
  187. string decodedItems = HttpUtility.UrlDecode(items);
  188. string[] allItems = decodedItems.Split(',');
  189. foreach (string newItem in allItems)
  190. {
  191. string[] urlInfo = newItem.Split(':');
  192. string itemId = urlInfo[0];
  193. string title = string.Empty;
  194. if (urlInfo.GetUpperBound(0) >= 1)
  195. {
  196. // They also passed in the original filename, so let's use it as our title
  197. title = urlInfo[1];
  198. }
  199. if (IsValidItem(type, itemId))
  200. {
  201. ModifyVaultItemViewModel item = new ModifyVaultItemViewModel();
  202. item.isTemplate = false;
  203. item.index = index;
  204. item.title = title;
  205. item.url = itemId;
  206. item.type = type;
  207. model.items.Add(item);
  208. index++;
  209. }
  210. }
  211. }
  212. return View("~/Areas/Vault/Views/Vault/ModifyVault.cshtml", model);
  213. }
  214. return new StatusCodeResult(StatusCodes.Status403Forbidden);
  215. }
  216. return new StatusCodeResult(StatusCodes.Status404NotFound);
  217. }
  218. [HttpPost]
  219. [AllowAnonymous]
  220. [ValidateAntiForgeryToken]
  221. public IActionResult CreateVault(ModifyVaultViewModel model)
  222. {
  223. if (model != null)
  224. {
  225. if (!string.IsNullOrEmpty(model.title))
  226. {
  227. Models.Vault newVault = new Models.Vault();
  228. // Create a new ID
  229. string url = StringHelper.RandomString(_config.VaultConfig.UrlLength);
  230. while (_dbContext.Vaults.Where(v => v.Url == url).FirstOrDefault() != null)
  231. {
  232. url = StringHelper.RandomString(_config.VaultConfig.UrlLength);
  233. }
  234. newVault.Url = url;
  235. newVault.DateCreated = DateTime.Now;
  236. newVault.Title = model.title;
  237. newVault.Description = model.description;
  238. if (User.Identity.IsAuthenticated)
  239. {
  240. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  241. if (user != null)
  242. {
  243. newVault.UserId = user.UserId;
  244. }
  245. }
  246. // Add/Verify items
  247. if (model.items.Any())
  248. {
  249. foreach (ModifyVaultItemViewModel item in model.items)
  250. {
  251. if (IsValidItem(item.type, item.url))
  252. {
  253. switch (item.type.ToLower())
  254. {
  255. case "upload":
  256. UploadVaultItem newUpload = new UploadVaultItem();
  257. newUpload.DateAdded = DateTime.Now;
  258. newUpload.Title = item.title;
  259. newUpload.Description = item.description;
  260. newUpload.UploadId = _dbContext.Uploads.Where(u => u.Url == item.url).FirstOrDefault().UploadId;
  261. newVault.VaultItems.Add(newUpload);
  262. break;
  263. case "paste":
  264. PasteVaultItem newPaste = new PasteVaultItem();
  265. newPaste.DateAdded = DateTime.Now;
  266. newPaste.Title = item.title;
  267. newPaste.Description = item.description;
  268. newPaste.PasteId = _dbContext.Pastes.Where(p => p.Url == item.url).FirstOrDefault().PasteId;
  269. newVault.VaultItems.Add(newPaste);
  270. break;
  271. default:
  272. return Json(new { error = new { message = "You have an invalid item type: " + item.type } });
  273. }
  274. }
  275. else
  276. {
  277. return Json(new { error = new { message = "You have an invalid item URL: " + item.url } });
  278. }
  279. }
  280. }
  281. // Add and save the new vault
  282. _dbContext.Vaults.Add(newVault);
  283. _dbContext.SaveChanges();
  284. return Json(new { result = new { url = Url.SubRouteUrl("v", "Vault.ViewVault", new { id = url }) } });
  285. }
  286. return Json(new { error = new { message = "You must supply a Title" } });
  287. }
  288. return Json(new { error = new { message = "Invalid Parameters" } });
  289. }
  290. [HttpPost]
  291. [ValidateAntiForgeryToken]
  292. public IActionResult EditVault(ModifyVaultViewModel model)
  293. {
  294. if (model != null)
  295. {
  296. Vault.Models.Vault foundVault = _dbContext.Vaults.Where(v => v.VaultId == model.vaultId).FirstOrDefault();
  297. if (foundVault != null)
  298. {
  299. if (foundVault.User.Username == User.Identity.Name)
  300. {
  301. foundVault.DateEdited = DateTime.Now;
  302. foundVault.Title = model.title;
  303. foundVault.Description = model.description;
  304. // Clear previous items
  305. List<VaultItem> vaultItems = _dbContext.VaultItems.Where(v => v.VaultId == foundVault.VaultId).ToList();
  306. if (vaultItems != null)
  307. {
  308. foreach (VaultItem item in vaultItems)
  309. {
  310. _dbContext.VaultItems.Remove(item);
  311. }
  312. }
  313. foundVault.VaultItems.Clear();
  314. // Add/Verify items
  315. if (model.items.Any())
  316. {
  317. foreach (ModifyVaultItemViewModel item in model.items)
  318. {
  319. if (IsValidItem(item.type, item.url))
  320. {
  321. switch (item.type.ToLower())
  322. {
  323. case "upload":
  324. UploadVaultItem newUpload = new UploadVaultItem();
  325. newUpload.DateAdded = DateTime.Now;
  326. newUpload.Title = item.title;
  327. newUpload.Description = item.description;
  328. newUpload.UploadId = _dbContext.Uploads.Where(u => u.Url == item.url).FirstOrDefault().UploadId;
  329. foundVault.VaultItems.Add(newUpload);
  330. break;
  331. case "paste":
  332. PasteVaultItem newPaste = new PasteVaultItem();
  333. newPaste.DateAdded = DateTime.Now;
  334. newPaste.Title = item.title;
  335. newPaste.Description = item.description;
  336. newPaste.PasteId = _dbContext.Pastes.Where(p => p.Url == item.url).FirstOrDefault().PasteId;
  337. foundVault.VaultItems.Add(newPaste);
  338. break;
  339. default:
  340. return Json(new { error = new { message = "You have an invalid item type: " + item.type } });
  341. }
  342. }
  343. else
  344. {
  345. return Json(new { error = new { message = "You have an invalid item URL: " + item.url } });
  346. }
  347. }
  348. }
  349. _dbContext.Entry(foundVault).State = EntityState.Modified;
  350. _dbContext.SaveChanges();
  351. return Json(new { result = new { url = Url.SubRouteUrl("v", "Vault.ViewVault", new { id = foundVault.Url }) } });
  352. }
  353. return Json(new { error = new { message = "You do not have permission to edit this Vault" } });
  354. }
  355. return Json(new { error = new { message = "That Vault does not exist" } });
  356. }
  357. return Json(new { error = new { message = "Invalid Parameters" } });
  358. }
  359. [HttpPost]
  360. public IActionResult DeleteVault(string url)
  361. {
  362. Vault.Models.Vault foundVault = _dbContext.Vaults.Where(v => v.Url == url).FirstOrDefault();
  363. if (foundVault != null)
  364. {
  365. if (foundVault.User.Username == User.Identity.Name)
  366. {
  367. _dbContext.Vaults.Remove(foundVault);
  368. _dbContext.SaveChanges();
  369. return Json(new { result = new { url = Url.SubRouteUrl("vault", "Vault.CreateVault") } });
  370. }
  371. return Json(new { error = new { message = "You do not have permission to edit this Vault" } });
  372. }
  373. return Json(new { error = new { message = "That Vault does not exist" } });
  374. }
  375. [HttpPost]
  376. [AllowAnonymous]
  377. [ValidateAntiForgeryToken]
  378. public IActionResult ValidateItem(string type, string url)
  379. {
  380. if (IsValidItem(type, url))
  381. {
  382. return Json(new { result = new { valid = true } });
  383. }
  384. else
  385. {
  386. return Json(new { error = new { message = "Invalid URL Id for this Item" } });
  387. }
  388. }
  389. private bool IsValidItem(string type, string url)
  390. {
  391. bool valid = false;
  392. if (!string.IsNullOrEmpty(type) && !string.IsNullOrEmpty(url))
  393. {
  394. switch (type.ToLower())
  395. {
  396. case "upload":
  397. Upload.Models.Upload foundUpload = _dbContext.Uploads.Where(u => u.Url == url).FirstOrDefault();
  398. if (foundUpload != null)
  399. {
  400. valid = true;
  401. }
  402. break;
  403. case "paste":
  404. Paste.Models.Paste foundPaste = _dbContext.Pastes.Where(p => p.Url == url).FirstOrDefault();
  405. if (foundPaste != null)
  406. {
  407. valid = true;
  408. }
  409. break;
  410. }
  411. }
  412. return valid;
  413. }
  414. }
  415. }