using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.StaticFiles; using Org.BouncyCastle.Ocsp; 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 readonly ILogger _logger; private readonly IMessageService _messageService; private readonly IModelFactory _modelFactory; private readonly IWebHostEnvironment _webHostEnvironment; private const string DefaultPath = "files"; private const string DefaultPathTmp = "filestmp"; public HomeController(ILogger logger, IMessageService messageService, IModelFactory modelFactory, IWebHostEnvironment webHostEnvironment) { _logger = logger; _messageService = messageService; _modelFactory = modelFactory; _webHostEnvironment = webHostEnvironment; } public IActionResult Index() { return View(); } 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 (string.IsNullOrWhiteSpace(model.Text) && model.Files.Count == 0 && string.IsNullOrEmpty(model.FilesAsText)) { return Redirect("/"); } var message = new MessageDto { Text = model.Text }; await UploadFiles(model, message); var code = await _messageService.Create(message, model.ChosenPeriod); return RedirectToAction("Link", "Home", new { code = code, share = true }); } 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 }); } } 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); return contentType is null ? null : File(memory, contentType,Path.GetFileName(path)); } [HttpGet] public async Task Link(Guid code, bool? share) { var model = await _modelFactory.PrepareLinkVM(code, share); return View(model); } public IActionResult Privacy() { return View(); } }