Files
hermione/src/main/java/com/olympus/hermione/services/FileService.java
dalia.florinda c5ccf97ff7 fix upload file
2026-01-15 13:34:43 +01:00

229 lines
8.8 KiB
Java

package com.olympus.hermione.services;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;
import com.olympus.hermione.dto.FileDeleteRequest;
@Service
public class FileService {
private Logger logger = LoggerFactory.getLogger(FileService.class);
@Value("${file.upload-dir}")
private String uploadDir;
public ResponseEntity<String> uploadFiles(String folderName, List<MultipartFile> files, String type) {
File folder = new File(uploadDir + folderName);
if (!folder.exists()) {
folder.mkdirs(); // Crea la cartella se non esiste
}
logger.info("path folder:", folder.getAbsolutePath().toString());
File emailFolder = new File(folder, "email");
if (!emailFolder.exists()) {
emailFolder.mkdirs();
}
try {
if (type.equals("PR")) {
for (MultipartFile file : files) {
String fileName = file.getOriginalFilename();
File destFile = new File(folder, fileName);
file.transferTo(destFile);
}
} else {
// Creazione delle sottocartelle "email" e "other" se non esistono
File otherFolder = new File(folder, "other");
for (MultipartFile file : files) {
String fileName = file.getOriginalFilename();
if (fileName != null && fileName.endsWith(".msg")) {
// Salva il file nella cartella "email"
File destFile = new File(emailFolder, fileName);
file.transferTo(destFile);
} else {
if (!otherFolder.exists()) {
otherFolder.mkdirs();
}
// Salva il file nella cartella "other"
File destFile = new File(otherFolder, fileName);
file.transferTo(destFile);
}
}
}
return ResponseEntity.ok(folderName);
} catch (Exception e) {
logger.error("Error uploading files: {}", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Error uploading files: " + e.getMessage());
}
}
public ResponseEntity<String> deleteFile(FileDeleteRequest request) {
String fileName = request.getFileName();
String folderPath = uploadDir + request.getFolderName();
File folder = new File(folderPath);
// Verifica che la directory esista
if (!folder.exists() || !folder.isDirectory()) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Folder not found");
}
// Cerca il file nelle sottocartelle
File fileToDelete = findFileInSubdirectories(folder, fileName);
if (fileToDelete != null) {
if (fileToDelete.delete()) {
return ResponseEntity.ok("File deleted successfully");
} else {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to delete file");
}
} else {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("File not found");
}
}
/**
* Metodo helper per cercare un file nelle sottocartelle.
*
* @param folder La directory di partenza
* @param fileName Il nome del file da cercare
* @return Il file trovato oppure null se non trovato
*/
private File findFileInSubdirectories(File folder, String fileName) {
File[] files = folder.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
// Ricorsione per cercare nelle sottocartelle
File found = findFileInSubdirectories(file, fileName);
if (found != null) {
return found;
}
} else if (file.getName().equals(fileName)) {
// File trovato
return file;
}
}
}
// File non trovato
return null;
}
/**
* Scarica un file dal path specificato
*
* @param filePath Il path relativo del file da scaricare
* @param executionId L'ID dell'esecuzione per il logging
* @return ResponseEntity con il file come Resource
*/
public ResponseEntity<Resource> downloadFile(String filePath, String executionId) {
try {
logger.info("Downloading file: {} for execution: {}", filePath, executionId);
// Normalizza il path rimuovendo eventuali separatori doppi o tripli
String normalizedPath = filePath.replaceAll("[\\\\/]+", "/");
// Check if path is absolute (starts with drive letter or uploadDir)
// If absolute, use it directly; otherwise, combine with uploadDir
Path file;
if (normalizedPath.matches("^[A-Za-z]:/.*") || normalizedPath.startsWith(uploadDir)) {
// Already absolute path - use directly (backward compatibility)
file = Paths.get(normalizedPath);
} else {
// Relative path - combine with uploadDir
file = Paths.get(uploadDir, normalizedPath);
}
logger.info("Upload directory: {}", uploadDir);
logger.info("Normalized relative path: {}", normalizedPath);
logger.info("Full file path: {}", file.toAbsolutePath());
// Verifica che il file esista e sia leggibile
if (!Files.exists(file)) {
logger.error("File not found: {}", file.toAbsolutePath());
return ResponseEntity.notFound().build();
}
if (!Files.isReadable(file)) {
logger.error("File not readable: {}", file.toAbsolutePath());
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
// Verifica che il file sia all'interno della directory di upload (security check)
Path uploadPath = Paths.get(uploadDir).toAbsolutePath().normalize();
Path filePath_abs = file.toAbsolutePath().normalize();
if (!filePath_abs.startsWith(uploadPath)) {
logger.error("Security violation: attempting to access file outside upload directory: {}", filePath_abs);
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
// Crea la risorsa file
Resource resource = new FileSystemResource(file);
// Determina il content type
String contentType = Files.probeContentType(file);
if (contentType == null) {
contentType = "application/octet-stream";
}
// Estrai il nome del file
String fileName = file.getFileName().toString();
// Costruisci gli header per il download
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"");
headers.add(HttpHeaders.CONTENT_TYPE, contentType);
headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(resource.contentLength()));
logger.info("File downloaded successfully: {} (size: {} bytes)", fileName, resource.contentLength());
return ResponseEntity.ok()
.headers(headers)
.contentType(MediaType.parseMediaType(contentType))
.body(resource);
} catch (IOException e) {
logger.error("Error downloading file: {} - {}", filePath, e.getMessage(), e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
} catch (Exception e) {
logger.error("Unexpected error downloading file: {} - {}", filePath, e.getMessage(), e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
}