From 4e93ac86d4891c59ecfcd27c051de9b3c5379315 Mon Sep 17 00:00:00 2001 From: Grimm Date: Fri, 14 Mar 2025 22:19:02 +0800 Subject: [PATCH] add file extention check for upload --- .../common/core/utils/file/FileUtils.java | 40 +++++++++++++++++++ .../common/core/utils/file/MimeTypeUtils.java | 26 +++++++----- .../system/service/impl/SseServiceImpl.java | 11 +++++ 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/file/FileUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/file/FileUtils.java index 9c6f2650..c8cc119f 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/file/FileUtils.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/file/FileUtils.java @@ -4,9 +4,13 @@ import cn.hutool.core.io.FileUtil; import jakarta.servlet.http.HttpServletResponse; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.multipart.MultipartFile; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.UUID; /** * 文件处理工具类 @@ -16,6 +20,8 @@ import java.nio.charset.StandardCharsets; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class FileUtils extends FileUtil { + private static final String FILE_EXTENTION_SPLIT = "."; + /** * 下载文件名重新编码 * @@ -40,4 +46,38 @@ public class FileUtils extends FileUtil { String encode = URLEncoder.encode(s, StandardCharsets.UTF_8); return encode.replaceAll("\\+", "%20"); } + + /** + * 检查文件扩展名是否符合要求 + * + * @param file + * @return + */ + public static boolean isValidFileExtention(MultipartFile file, String[] ALLOWED_EXTENSIONS) { + if (file == null || file.isEmpty()) { + return false; + } + final String filename = file.getOriginalFilename(); + if (StringUtils.isBlank(filename) || !filename.contains(FILE_EXTENTION_SPLIT)) { + return false; + } + // 获取文件后缀 + String fileExtension = filename.substring(filename.lastIndexOf('.') + 1).toLowerCase(); + + return Arrays.asList(ALLOWED_EXTENSIONS).contains(fileExtension); + } + + /** + * 获取安全的文件路径 + * + * @param originalFilename 原始文件名 + * @param secureFilePath 安全路径 + * @return 安全文件路径 + */ + public static String getSecureFilePathForUpload(final String originalFilename, final String secureFilePath) { + String extension = originalFilename.substring(originalFilename.lastIndexOf(FILE_EXTENTION_SPLIT)); + String newFileName = UUID.randomUUID() + extension; + + return secureFilePath + newFileName; // 预定义安全路径 + } } diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/file/MimeTypeUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/file/MimeTypeUtils.java index 9e39699b..c82aebec 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/file/MimeTypeUtils.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/file/MimeTypeUtils.java @@ -24,17 +24,23 @@ public class MimeTypeUtils { "asf", "rm", "rmvb"}; public static final String[] VIDEO_EXTENSION = {"mp4", "avi", "rmvb"}; + /** + * 音频扩展名 + */ + public static final String[] AUDIO__EXTENSION = {"mp3", "mp4", "mpeg", "mpga", "m4a", "wav", "webm"}; public static final String[] DEFAULT_ALLOWED_EXTENSION = { - // 图片 - "bmp", "gif", "jpg", "jpeg", "png", - // word excel powerpoint - "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt", - // 压缩文件 - "rar", "zip", "gz", "bz2", - // 视频格式 - "mp4", "avi", "rmvb", - // pdf - "pdf"}; + // 图片 + "bmp", "gif", "jpg", "jpeg", "png", + // word excel powerpoint + "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt", + // 压缩文件 + "rar", "zip", "gz", "bz2", + // 视频格式 + "mp4", "avi", "rmvb", + // 音频格式 + "mp3", "mp4", "mpeg", "mpga", "m4a", "wav", "webm", + // pdf + "pdf"}; } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/SseServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/SseServiceImpl.java index d7cc3e35..40d598d8 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/SseServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/SseServiceImpl.java @@ -37,6 +37,8 @@ import org.ruoyi.common.core.domain.model.LoginUser; import org.ruoyi.common.core.exception.base.BaseException; import org.ruoyi.common.core.service.ConfigService; import org.ruoyi.common.core.utils.StringUtils; +import org.ruoyi.common.core.utils.file.FileUtils; +import org.ruoyi.common.core.utils.file.MimeTypeUtils; import org.ruoyi.common.satoken.utils.LoginHelper; import org.ruoyi.system.domain.SysModel; import org.ruoyi.system.domain.bo.ChatMessageBo; @@ -333,6 +335,9 @@ public class SseServiceImpl implements ISseService { if (file.isEmpty()) { throw new IllegalStateException("Cannot convert an empty MultipartFile"); } + if (!FileUtils.isValidFileExtention(file, MimeTypeUtils.AUDIO__EXTENSION)) { + throw new IllegalStateException("File Extention not supported"); + } // 创建一个文件对象 File fileA = new File(System.getProperty("java.io.tmpdir") + File.separator + file.getOriginalFilename()); try { @@ -422,6 +427,12 @@ public class SseServiceImpl implements ISseService { @Override public UploadFileResponse upload(MultipartFile file) { + if (file.isEmpty()) { + throw new IllegalStateException("Cannot upload an empty MultipartFile"); + } + if (!FileUtils.isValidFileExtention(file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION)) { + throw new IllegalStateException("File Extention not supported"); + } openAiStreamClient = chatConfig.getOpenAiStreamClient(); return openAiStreamClient.uploadFile("fine-tune", convertMultiPartToFile(file)); }