using System; using System.Threading.Tasks; using System.Collections.Generic; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Serilog; using LCU.Library.Internal.FileOperationsModels.Models; using LCU.Library.Internal.Exceptions; using LCU.Library.Internal.ApiResponse.Models; using LCU.Api.Internal.FileOperations.Services.QueueServices; using LCU.Api.Internal.FileOperations.Extensions; using LCU.Api.Internal.FileOperations.Services; using LCU.Api.Internal.FileOperations.Services.FileActionServices; namespace LCU.Api.Internal.FileOperations.Controllers; [Route("api/[controller]")] [ApiController] public class FileOperationsController : ControllerBase { private readonly IQueueFileOperationsService _queueFileOperationsService; private readonly IActionService _moveFileService; private readonly IActionService _copyFileService; private readonly IActionService _deleteFileService; private readonly IActionService _modifyFileService; private readonly IActionService _renameFileService; private readonly IActionService _zipDirectoryService; private readonly IActionService _unzipFileService; private readonly IActionService _unzipPasswordProtectedFileService; private readonly IActionService _createDirectoryService; private readonly IActionService _renameDirectoryService; private readonly IActionService> _bulkMoveFileService; private readonly IActionService _encryptFileDataService; private readonly IActionService _decryptFileDataService; private readonly IActionService _writeFileDataService; private readonly IActionService _deleteDirectoryService; private readonly IActionService _deleteEmptyDirectoryService; private readonly IDirectFileService _directFileService; public FileOperationsController(IQueueFileOperationsService fileOperationsService, IActionService moveFileService, IActionService copyFileService, IActionService modifyFileService, IActionService deleteFileService, IActionService renameFileService, IActionService zipDirectoryService, IActionService unzipFileService, IActionService unzipPasswordProtectedFileService, IActionService createDirectoryService, IActionService renameDirectoryService, IActionService> bulkMoveFileService, IActionService encryptFileDataService, IActionService decryptFileDataService, IActionService writeFileDataService, IActionService deleteDirectoryService, IActionService deleteEmptyDirectoryService, IDirectFileService directFileService) { _queueFileOperationsService = fileOperationsService; _moveFileService = moveFileService; _copyFileService = copyFileService; _modifyFileService = modifyFileService; _deleteFileService = deleteFileService; _renameFileService = renameFileService; _zipDirectoryService = zipDirectoryService; _unzipFileService = unzipFileService; _unzipPasswordProtectedFileService = unzipPasswordProtectedFileService; _createDirectoryService = createDirectoryService; _renameDirectoryService = renameDirectoryService; _bulkMoveFileService = bulkMoveFileService; _encryptFileDataService = encryptFileDataService; _decryptFileDataService = decryptFileDataService; _directFileService = directFileService; _writeFileDataService = writeFileDataService; _deleteDirectoryService = deleteDirectoryService; _deleteEmptyDirectoryService = deleteEmptyDirectoryService; } // Get api/{file} [HttpGet("{filename}")] [ProducesResponseType(200)] [ProducesResponseType(400)] public IActionResult GetFile([FromRoute] string filename) { if (string.IsNullOrWhiteSpace(filename)) { return BadRequest("filename is required"); } try { var result = _directFileService.GetFileBytes(filename); return new FileContentResult(result, "application/octet-stream"); } catch (ArgumentException ae) { Log.Error(ae, $"Request for bad file path {filename}"); return BadRequest("File path not found"); } catch (Exception ex) { Log.Error(ex, $"Unexpected error retrieving file path {filename}"); return StatusCode(StatusCodes.Status500InternalServerError); } } // POST api/MoveFile [HttpPost("MoveFile")] [ProducesResponseType(201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task MoveFile([FromBody] MoveFileRequest request) { return await HandleRequestResponse(request, FileOperationType.Move, _moveFileService); } // POST api/CopyFile [HttpPost("CopyFile")] [ProducesResponseType(201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task CopyFile([FromBody] CopyFileRequest request) { return await HandleRequestResponse(request, FileOperationType.Copy, _copyFileService); } // POST api/ModifyFile [HttpPost("ModifyFile")] [ProducesResponseType(201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task ModifyFile([FromBody] ModifyFileRequest request) { return await HandleRequestResponse(request, FileOperationType.Modify, _modifyFileService); } // POST api/DeleteFile [HttpPost("DeleteFile")] [ProducesResponseType(201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task DeleteFile([FromBody] DeleteFileRequest request) { return await HandleRequestResponse(request, FileOperationType.Delete, _deleteFileService); } // POST api/RenameFile [HttpPost("RenameFile")] [ProducesResponseType(201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task RenameFile([FromBody] RenameFileRequest request) { return await HandleRequestResponse(request, FileOperationType.Rename, _renameFileService); } // POST api/ZipDirectory [HttpPost("ZipDirectory")] [ProducesResponseType(201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task ZipDirectory([FromBody] ZipDirectoryRequest request) { return await HandleRequestResponse(request, FileOperationType.ZipDirectory, _zipDirectoryService); } // POST api/UnzipFile [HttpPost("UnzipFile")] [ProducesResponseType(201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task UnzipFile([FromBody] UnzipFileRequest request) { return await HandleRequestResponse(request, FileOperationType.UnzipFile, _unzipFileService); } // POST api/UnzipPasswordProtectedFile [HttpPost("UnzipPasswordProtectedFile")] [ProducesResponseType(201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task UnzipPasswordProtectedFile([FromBody] UnzipPasswordProtectedFileRequest request) { return await HandleRequestResponse(request, FileOperationType.UnzipPasswordProtectedFile, _unzipPasswordProtectedFileService); } // POST api/CreateDirectory [HttpPost("CreateDirectory")] [ProducesResponseType(201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task CreateDirectory([FromBody] CreateDirectoryRequest request) { return await HandleRequestResponse(request, FileOperationType.CreateDirectory, _createDirectoryService); } // POST api/RenameDirectory [HttpPost("RenameDirectory")] [ProducesResponseType(201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task RenameDirectory([FromBody] RenameDirectoryRequest request) { return await HandleRequestResponse(request, FileOperationType.RenameDirectory, _renameDirectoryService); } // POST api/BulkMoveFile [HttpPost("BulkMoveFile")] [ProducesResponseType(201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task BulkMoveFile([FromBody] BulkOperationRequest request) { return await HandleRequestResponse(request, FileOperationType.BulkMoveFile, _bulkMoveFileService); } // POST api/EncryptFileData [HttpPost("EncryptFileData")] [ProducesResponseType(201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task EncryptFileData([FromBody] EncryptFileDataRequest request) { return await HandleRequestResponse(request, FileOperationType.EncryptFileData, _encryptFileDataService); } // POST api/DecryptFileData [HttpPost("DecryptFileData")] [ProducesResponseType(201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task DecryptFileData([FromBody] DecryptFileDataRequest request) { return await HandleRequestResponse(request, FileOperationType.DecryptFileData, _decryptFileDataService); } // POST api/WriteFileData [HttpPost("WriteFileData")] [ProducesResponseType(201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task WriteFileData([FromBody] WriteFileRequest request) { return await HandleRequestResponse(request, FileOperationType.WriteFile, _writeFileDataService); } [HttpPost("DeleteDirectory")] [ProducesResponseType(201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task DeleteDirectory([FromBody] DeleteDirectoryRequest request) { return await HandleRequestResponse(request, FileOperationType.DeleteDirectory, _deleteDirectoryService); } [HttpPost("DeleteEmptyDirectory")] [ProducesResponseType(201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task DeleteEmptyDirectory([FromBody] DeleteEmptyDirectoryRequest request) { return await HandleRequestResponse(request, FileOperationType.DeleteEmptyDirectory, _deleteEmptyDirectoryService); } public async Task HandleRequestResponse(TRequest originalRequest, FileOperationType operationType, IActionService service) where TRequest : ReturnResponse { try { if (!ModelState.IsValid) { return BadRequest(ModelState.GetErrorMessages()); } var validateResponse = service.PreQueueValidation(originalRequest); if (!validateResponse.IsSuccessful) { return BadRequest($"Request is invalid. Response: {String.Join("\n ", validateResponse.MessageStack.ToArray())}"); } await _queueFileOperationsService.QueueFileOperations(originalRequest, operationType); return Ok(); } catch (ServiceException) { return StatusCode(StatusCodes.Status500InternalServerError); } catch (Exception exception) { Log.Error(exception, "Unexpected Exception"); return StatusCode(StatusCodes.Status500InternalServerError); } } }