Przeglądaj źródła

add file extention check for upload

Grimm 1 miesiąc temu
rodzic
commit
4e93ac86d4

+ 40 - 0
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; // 预定义安全路径
+    }
 }

+ 16 - 10
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"};
 
 }

+ 11 - 0
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));
     }