浏览代码

增加文件上传限制

zhou-hao 4 年之前
父节点
当前提交
af59d21303

+ 45 - 1
hsweb-system/hsweb-system-file/src/main/java/org/hswebframework/web/file/FileUploadProperties.java

@@ -2,12 +2,15 @@ package org.hswebframework.web.file;
 
 import lombok.Getter;
 import lombok.Setter;
+import org.apache.commons.collections.CollectionUtils;
 import org.hswebframework.utils.time.DateFormatter;
 import org.hswebframework.web.id.IDGenerator;
 import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.http.MediaType;
 
 import java.io.File;
 import java.util.Date;
+import java.util.Set;
 
 @Getter
 @Setter
@@ -18,6 +21,47 @@ public class FileUploadProperties {
 
     private String staticLocation = "/static";
 
+    private Set<String> allowFiles;
+
+    private Set<String> denyFiles;
+
+    private Set<String> allowMediaType;
+
+    private Set<String> denyMediaType;
+
+    public boolean denied(String name, MediaType mediaType) {
+        String suffix = name.contains(".") ? name.substring(name.lastIndexOf(".") + 1) : "";
+        boolean defaultDeny = false;
+        if (CollectionUtils.isNotEmpty(denyFiles)) {
+            if (denyFiles.contains(suffix)) {
+                return true;
+            }
+            defaultDeny = false;
+        }
+
+        if (CollectionUtils.isNotEmpty(allowFiles)) {
+            if (allowFiles.contains(suffix)) {
+                return false;
+            }
+            defaultDeny = true;
+        }
+
+        if (CollectionUtils.isNotEmpty(denyMediaType)) {
+            if (denyMediaType.contains(mediaType.toString())) {
+                return true;
+            }
+            defaultDeny =  false;
+        }
+
+        if (CollectionUtils.isNotEmpty(allowMediaType)) {
+            if (allowMediaType.contains(mediaType.toString())) {
+                return false;
+            }
+            defaultDeny = true;
+        }
+
+        return defaultDeny;
+    }
 
     public StaticFileInfo createStaticSavePath(String name) {
         String fileName = IDGenerator.SNOW_FLAKE_STRING.generate();
@@ -38,7 +82,7 @@ public class FileUploadProperties {
 
     @Getter
     @Setter
-    public class StaticFileInfo {
+    public static class StaticFileInfo {
         private String savePath;
 
         private String location;

+ 11 - 6
hsweb-system/hsweb-system-file/src/main/java/org/hswebframework/web/file/web/ReactiveFileController.java

@@ -4,6 +4,7 @@ import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.hswebframework.web.authorization.annotation.Resource;
 import org.hswebframework.web.authorization.annotation.ResourceAction;
+import org.hswebframework.web.authorization.exception.AccessDenyException;
 import org.hswebframework.web.file.FileUploadProperties;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.codec.multipart.FilePart;
@@ -29,14 +30,18 @@ public class ReactiveFileController {
     @PostMapping("/static")
     @SneakyThrows
     public Mono<String> uploadStatic(@RequestPart("file") Part part) {
-        FileUploadProperties.StaticFileInfo name ;
-        if(part instanceof FilePart){
-            name = properties.createStaticSavePath(((FilePart)part).filename());
-            return ((FilePart)part)
+        FileUploadProperties.StaticFileInfo name;
+        if (part instanceof FilePart) {
+            FilePart filePart = ((FilePart) part);
+            if (properties.denied(filePart.filename(), filePart.headers().getContentType())) {
+                throw new AccessDenyException();
+            }
+            name = properties.createStaticSavePath(filePart.filename());
+            return ((FilePart) part)
                     .transferTo(new File(name.getSavePath()))
                     .thenReturn(name.getLocation());
-        }else{
-           return Mono.error(()->new IllegalArgumentException("[file] part is not a file"));
+        } else {
+            return Mono.error(() -> new IllegalArgumentException("[file] part is not a file"));
         }
 
     }

+ 66 - 0
hsweb-system/hsweb-system-file/src/test/java/org/hswebframework/web/file/FileUploadPropertiesTest.java

@@ -0,0 +1,66 @@
+package org.hswebframework.web.file;
+
+import org.junit.Test;
+import org.springframework.http.MediaType;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+import static org.junit.Assert.*;
+
+public class FileUploadPropertiesTest {
+
+
+    @Test
+    public void testNoSet(){
+        FileUploadProperties uploadProperties=new FileUploadProperties();
+        assertFalse(uploadProperties.denied("test.xls", MediaType.ALL));
+
+        assertFalse(uploadProperties.denied("test.exe", MediaType.ALL));
+    }
+
+    @Test
+    public void testDenyWithAllow(){
+        FileUploadProperties uploadProperties=new FileUploadProperties();
+        uploadProperties.setAllowFiles(new HashSet<>(Arrays.asList("xls","json")));
+
+        assertFalse(uploadProperties.denied("test.xls", MediaType.ALL));
+
+        assertTrue(uploadProperties.denied("test.exe", MediaType.ALL));
+    }
+
+    @Test
+    public void testDenyWithAllowMediaType(){
+        FileUploadProperties uploadProperties=new FileUploadProperties();
+        uploadProperties.setAllowMediaType(new HashSet<>(Arrays.asList("application/xls","application/json")));
+
+        assertFalse(uploadProperties.denied("test.json", MediaType.APPLICATION_JSON));
+
+        assertTrue(uploadProperties.denied("test.exe", MediaType.ALL));
+    }
+
+
+
+    @Test
+    public void testDenyWithDenyMediaType(){
+        FileUploadProperties uploadProperties=new FileUploadProperties();
+        uploadProperties.setDenyMediaType(new HashSet<>(Arrays.asList("application/json")));
+
+        assertFalse(uploadProperties.denied("test.xls", MediaType.ALL));
+
+        assertTrue(uploadProperties.denied("test.exe", MediaType.APPLICATION_JSON));
+
+    }
+    @Test
+    public void testDenyWithDeny(){
+        FileUploadProperties uploadProperties=new FileUploadProperties();
+        uploadProperties.setDenyFiles(new HashSet<>(Arrays.asList("exe")));
+
+        assertFalse(uploadProperties.denied("test.xls", MediaType.ALL));
+
+        assertTrue(uploadProperties.denied("test.exe", MediaType.ALL));
+
+    }
+
+
+}