using AutoMapper; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.StaticFiles; using SecureSharing.Business.Dtos; using SecureSharing.Business.Interfaces; using SecureSharing.Data.Data; using SecureSharing.Infrastructure; using SecureSharing.Models; namespace SecureSharing.Controllers; [Authorize] public sealed class HomeController : Controller { private const string DefaultPath = "files"; private const string DefaultPathTmp = "filestmp"; private readonly ILogger _logger; private readonly IMessageService _messageService; private readonly IModelFactory _modelFactory; private readonly IWebHostEnvironment _webHostEnvironment; private readonly IMapper _mapper; public HomeController(ILogger logger, IMessageService messageService, IModelFactory modelFactory, IWebHostEnvironment webHostEnvironment, IMapper mapper) { _logger = logger; _messageService = messageService; _modelFactory = modelFactory; _webHostEnvironment = webHostEnvironment; _mapper = mapper; } public IActionResult Index() { return View(); } [AllowAnonymous] public async Task UploadTemporaryFile() { var code = Guid.NewGuid().ToString(); var files = Request.Form.Files.ToList(); var basePath = Path.Combine(_webHostEnvironment.WebRootPath.Split('/')[0], DefaultPathTmp, code); Directory.CreateDirectory(basePath); foreach (var formFile in files) { if (formFile.Length <= 0) continue; var filePath = Path.Combine(basePath, formFile.FileName); await using var stream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite); await formFile.CopyToAsync(stream); } return code; } [HttpPost] public async Task CreateMessage(MessageModel model) { if (!model.AllowEditing && string.IsNullOrWhiteSpace(model.Text) && model.Files.Count == 0 && model.FilesAsText == "978682e8-3ce7-4258-b731-d027b5b213aa") { return Redirect("/"); } model.FilesAsText = model.FilesAsText != "978682e8-3ce7-4258-b731-d027b5b213aa" ? model.FilesAsText.Split("978682e8-3ce7-4258-b731-d027b5b213aa")[1] : ""; var message = new MessageDto { Text = model.Text, Anonymous = model.AllowEditing || model.Anonymous, AllowEditing = model.AllowEditing}; await UploadFiles(model, message); var code = await _messageService.Create(message, model.ChosenPeriod); return RedirectToAction("Link", "Home", new { code, share = true }); } [HttpPost] [AllowAnonymous] public async Task UpdateMessage(MessageModel model) { if (string.IsNullOrWhiteSpace(model.Text) && model.Files.Count == 0 && model.FilesAsText == "978682e8-3ce7-4258-b731-d027b5b213aa") { return Redirect("/"); } model.FilesAsText = model.FilesAsText != "978682e8-3ce7-4258-b731-d027b5b213aa" ? model.FilesAsText.Split("978682e8-3ce7-4258-b731-d027b5b213aa")[1] : ""; var message = new MessageDto { Text = model.Text, Anonymous = model.Anonymous, Id = model.Id, Code = model.Code}; // var messageDto = _mapper.Map(model); await UploadFiles(model, message); await _messageService.Update(message); return RedirectToAction("LinkAnonymous", "Home", new { model.Code, share = true, edit = true }); } [AllowAnonymous] private async Task UploadFiles(MessageModel model, MessageDto message) { var basePath = Path.Combine(_webHostEnvironment.WebRootPath.Split('/')[0], DefaultPath, message.Code.ToString()); var basePathTemporary = Path.Combine(_webHostEnvironment.WebRootPath.Split('/')[0], DefaultPathTmp); Directory.CreateDirectory(basePath); var directoryNames = model.FilesAsText .Split(';') .Select(x => x.Split(':')[0]) .Where(x => !string.IsNullOrEmpty(x)) .Distinct() .ToList(); var fileNamesTmp = model.FilesAsText .Split(';') .Where(x => !string.IsNullOrEmpty(x)) .ToList(); var fileNames = fileNamesTmp.Select(x => x.Split(':')[1]).ToList(); foreach (var file in fileNames) message.FileNames.Add(new FileModel { Name = file }); for (var ind = 0; ind < directoryNames.Count; ind++) { var directoryName = directoryNames[ind]; var directoryPath = Path.Combine(basePathTemporary, directoryName); var files = Directory.GetFiles(directoryPath); for (var i = 0; i < files.Length; i++) { // var file = files[i]; var file = fileNames[ind + i]; var filePath = Path.Combine(directoryPath, file); var newFilePath = Path.Combine(basePath, file); System.IO.File.Move(filePath, newFilePath); } } foreach (var directory in directoryNames) Directory.Delete(Path.Combine(basePathTemporary, directory), true); foreach (var formFile in model.Files) { if (formFile.Length <= 0) continue; var filePath = Path.Combine(basePath, formFile.FileName); await using var stream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite); await formFile.CopyToAsync(stream); message.FileNames.Add(new FileModel { Name = formFile.FileName }); } } [AllowAnonymous] public async Task Download(string filename, Guid code) { var path = Path.Combine(_webHostEnvironment.WebRootPath.Split('/')[0], DefaultPath, code.ToString(), filename); var memory = new MemoryStream(); await using var stream = new FileStream(path, FileMode.Open); await stream.CopyToAsync(memory); memory.Position = 0; new FileExtensionContentTypeProvider().TryGetContentType(filename, out var contentType); if(contentType is null && filename.EndsWith(".7z")) contentType = "application/octet-stream"; return contentType is null ? null : File(memory, contentType, Path.GetFileName(path)); } [HttpGet] public async Task Link(Guid code, bool? share, bool? edit) { var model = await _modelFactory.PrepareLinkVM(code, share, edit); return View(model); } [AllowAnonymous] [HttpGet] public async Task LinkAnonymous(Guid code, bool? edit) { var model = await _modelFactory.PrepareLinkAnonymous(code, edit); return View(model); } [AllowAnonymous] [HttpGet] public async Task LinkEdit(Guid code, bool? edit) { var model = await _modelFactory.PrepareLinkEdit(code, edit); return View(model.MessageModel); } public IActionResult Privacy() { return View(); } }