diff --git a/backend/framework/sdk/src/main/resources/i18n/project.properties b/backend/framework/sdk/src/main/resources/i18n/project.properties index 4922fe343f..e8adb80470 100644 --- a/backend/framework/sdk/src/main/resources/i18n/project.properties +++ b/backend/framework/sdk/src/main/resources/i18n/project.properties @@ -443,6 +443,7 @@ change.jar.enable=修改了jar文件的启用状态 file.name.exist=文件名已存在 file.log.delete_module=模块下的所有数据全部被删除 file.module.root=根目录 +file.folder.error=文件夹不合法 file.log.move_to=移动到 file.log.change_file_module=文件进行了移动 file.log.next=之后 diff --git a/backend/framework/sdk/src/main/resources/i18n/project_en_US.properties b/backend/framework/sdk/src/main/resources/i18n/project_en_US.properties index c0132412c2..e80480d371 100644 --- a/backend/framework/sdk/src/main/resources/i18n/project_en_US.properties +++ b/backend/framework/sdk/src/main/resources/i18n/project_en_US.properties @@ -479,6 +479,7 @@ change.jar.enable=Change jar file enable file.name.exist=File name already exists file.log.delete_module=has be deleted file.module.root=root module +file.folder.error=File folder error file.log.move_to=move to file.log.change_file_module=File has be moved file.log.next=next diff --git a/backend/framework/sdk/src/main/resources/i18n/project_zh_CN.properties b/backend/framework/sdk/src/main/resources/i18n/project_zh_CN.properties index c864069029..0d0f1af11f 100644 --- a/backend/framework/sdk/src/main/resources/i18n/project_zh_CN.properties +++ b/backend/framework/sdk/src/main/resources/i18n/project_zh_CN.properties @@ -478,6 +478,7 @@ change.jar.enable=修改了jar文件的启用状态 file.name.exist=文件名已存在 file.log.delete_module=模块下的所有数据全部被删除 file.module.root=根目录 +file.folder.error=文件夹不合法 file.log.move_to=移动到 file.log.change_file_module=文件进行了移动 file.log.next=之后 diff --git a/backend/framework/sdk/src/main/resources/i18n/project_zh_TW.properties b/backend/framework/sdk/src/main/resources/i18n/project_zh_TW.properties index 48c1deca12..48a851b7e8 100644 --- a/backend/framework/sdk/src/main/resources/i18n/project_zh_TW.properties +++ b/backend/framework/sdk/src/main/resources/i18n/project_zh_TW.properties @@ -479,6 +479,7 @@ change.jar.enable=修改了jar文件的啟用狀態 file.name.exist=文件名已存在 file.log.delete_module=模塊下的所有數據全部被刪除 file.module.root=根目錄 +file.folder.error=文件夾不合法 file.log.move_to=移動到 file.log.change_file_module=文件進行了移動 file.log.next=之後 diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/service/FileAssociationService.java b/backend/services/project-management/src/main/java/io/metersphere/project/service/FileAssociationService.java index e17e453f76..15149a71d6 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/service/FileAssociationService.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/service/FileAssociationService.java @@ -230,7 +230,7 @@ public class FileAssociationService { } FileAssociationExample example = new FileAssociationExample(); example.createCriteria().andIdIn(idList); - return this.deleteAndSelectExample(example, logRecord); + return this.deleteAndSaveLog(example, logRecord); } /** @@ -246,10 +246,27 @@ public class FileAssociationService { } FileAssociationExample example = new FileAssociationExample(); example.createCriteria().andSourceIdIn(sourceIds); - return this.deleteAndSelectExample(example, logRecord); + return this.deleteAndSaveLog(example, logRecord); } - private int deleteAndSelectExample(FileAssociationExample example, FileLogRecord logRecord) { + /** + * 取消关联 + * + * @param sourceId 资源ID + * @param fileIds 文件ID + * @param logRecord 日志记录相关 + * @return + */ + public int deleteBySourceIdAndFileIds(String sourceId, List fileIds, @Validated FileLogRecord logRecord) { + if (CollectionUtils.isEmpty(fileIds)) { + return 0; + } + FileAssociationExample example = new FileAssociationExample(); + example.createCriteria().andSourceIdEqualTo(sourceId).andFileIdIn(fileIds); + return this.deleteAndSaveLog(example, logRecord); + } + + private int deleteAndSaveLog(FileAssociationExample example, FileLogRecord logRecord) { List fileAssociationList = fileAssociationMapper.selectByExample(example); Map> sourceToFileNameMap = this.genSourceNameFileNameMap(fileAssociationList); int deleteCount = fileAssociationMapper.deleteByExample(example); diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/service/FileManagementService.java b/backend/services/project-management/src/main/java/io/metersphere/project/service/FileManagementService.java index 9eb9649ba9..dc4c0c5e20 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/service/FileManagementService.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/service/FileManagementService.java @@ -68,7 +68,6 @@ public class FileManagementService { deleteList.forEach(fileMetadata -> { FileRequest fileRequest = new FileRequest(); fileRequest.setFileName(fileMetadata.getId()); - fileRequest.setProjectId(fileMetadata.getProjectId()); fileRequest.setStorage(fileMetadata.getStorage()); try { //删除存储容器中的文件 @@ -139,7 +138,6 @@ public class FileManagementService { deleteList.forEach(fileMetadata -> { FileRequest fileRequest = new FileRequest(); fileRequest.setFileName(fileMetadata.getId()); - fileRequest.setProjectId(fileMetadata.getProjectId()); fileRequest.setStorage(fileMetadata.getStorage()); try { fileService.deleteFile(fileRequest); diff --git a/backend/services/project-management/src/test/java/io/metersphere/project/controller/filemanagement/FileManagementControllerTests.java b/backend/services/project-management/src/test/java/io/metersphere/project/controller/filemanagement/FileManagementControllerTests.java index 8d41831511..f2bb548380 100644 --- a/backend/services/project-management/src/test/java/io/metersphere/project/controller/filemanagement/FileManagementControllerTests.java +++ b/backend/services/project-management/src/test/java/io/metersphere/project/controller/filemanagement/FileManagementControllerTests.java @@ -11,6 +11,7 @@ import io.metersphere.project.mapper.FileMetadataMapper; import io.metersphere.project.mapper.FileModuleMapper; import io.metersphere.project.service.FileAssociationService; import io.metersphere.project.service.FileModuleService; +import io.metersphere.project.service.FileService; import io.metersphere.project.utils.FileManagementBaseUtils; import io.metersphere.project.utils.FileManagementRequestUtils; import io.metersphere.project.utils.FileMetadataUtils; @@ -23,6 +24,7 @@ import io.metersphere.system.controller.handler.ResultHolder; import io.metersphere.system.dto.AddProjectRequest; import io.metersphere.system.dto.sdk.BaseTreeNode; import io.metersphere.system.dto.sdk.request.NodeMoveRequest; +import io.metersphere.system.file.FileRequest; import io.metersphere.system.log.constants.OperationLogModule; import io.metersphere.system.log.constants.OperationLogType; import io.metersphere.system.service.CommonProjectService; @@ -1719,6 +1721,10 @@ public class FileManagementControllerTests extends BaseTest { //参数测试 Assertions.assertEquals(fileAssociationService.deleteBySourceIds(null, fileLogRecord), 0); + Assertions.assertEquals(fileAssociationService.deleteBySourceIdAndFileIds(null, new ArrayList<>(), fileLogRecord), 0); + Assertions.assertEquals(fileAssociationService.deleteBySourceIdAndFileIds(IDGenerator.nextStr(), new ArrayList<>() {{ + this.add(IDGenerator.nextStr()); + }}, fileLogRecord), 0); //重新关联,用来测试文件删除是否会级联删除。使用bug-3 fileAssociationService.association("sty-file-association-bug-id-3", FileAssociationSourceUtil.SOURCE_TYPE_BUG, bug2IdList, fileLogRecord); fileAssociationService.association("sty-file-association-bug-id-2", FileAssociationSourceUtil.SOURCE_TYPE_BUG, bug2IdList, fileLogRecord); @@ -2326,10 +2332,27 @@ public class FileManagementControllerTests extends BaseTest { Assertions.assertEquals(fileMetadataMapper.countByExample(example), 0); } + @Resource + private FileService fileService; + @Test @Order(91) public void testQuery() throws Exception { fileAssociationService.getFiles("TEST", FileAssociationSourceUtil.SOURCE_TYPE_FUNCTIONAL_CASE); fileAssociationService.getFileAssociations(Collections.singletonList("TEST"), FileAssociationSourceUtil.SOURCE_TYPE_FUNCTIONAL_CASE); + + + //测试FileRequest的folder判断 + FileRequest fileRequest = new FileRequest(); + fileRequest.setFileName(IDGenerator.nextStr()); + fileRequest.setStorage(StorageType.MINIO.name()); + fileRequest.setFolder(IDGenerator.nextStr()); + boolean error = false; + try { + fileService.deleteFile(fileRequest); + } catch (Exception e) { + error = true; + } + Assertions.assertTrue(error); } } diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/file/FileRequest.java b/backend/services/system-setting/src/main/java/io/metersphere/system/file/FileRequest.java index a0dd1671ac..bff52673c2 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/file/FileRequest.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/file/FileRequest.java @@ -10,21 +10,9 @@ public class FileRequest { private String folder; - /** - * @Deprecated 月底移除 - */ - @Deprecated(since="3.x", forRemoval=true) - private String projectId; - // 存储类型 private String storage; - /** - * @Deprecated 月底移除 - */ - @Deprecated(since="3.x", forRemoval=true) - private String resourceId; - // 文件名称 private String fileName; diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/file/MinioRepository.java b/backend/services/system-setting/src/main/java/io/metersphere/system/file/MinioRepository.java index b525fa5bcc..f96c46a8fc 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/file/MinioRepository.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/file/MinioRepository.java @@ -1,5 +1,6 @@ package io.metersphere.system.file; +import io.metersphere.sdk.exception.MSException; import io.metersphere.system.config.MinioConfig; import io.minio.*; import io.minio.messages.Item; @@ -24,8 +25,10 @@ public class MinioRepository implements FileRepository { private static final int BUFFER_SIZE = 8192; private String getPath(FileRequest request) { - String folder = StringUtils.isNotEmpty(request.getFolder()) ? request.getFolder() : request.getProjectId(); - //todo 后续要增加对folder起始路径的校验: system / project / organization + String folder = request.getFolder(); + if (!StringUtils.startsWithAny(folder, "system", "project", "organization")) { + throw new MSException("file.folder.error"); + } return StringUtils.join(folder, "/", request.getFileName()); } diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/FileCenterTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/FileCenterTests.java index 784e6852da..659fc8a181 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/FileCenterTests.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/FileCenterTests.java @@ -45,7 +45,7 @@ public class FileCenterTests { private static FileRequest getFileRequest() { FileRequest request = new FileRequest(); request.setFileName("test.txt"); - request.setFolder("test-project/test-resource-id"); + request.setFolder("system/test-project/test-resource-id"); return request; } @@ -77,7 +77,7 @@ public class FileCenterTests { // 创建一个FileRequest对象作为测试用的请求参数 FileRequest request = new FileRequest(); request.setFileName("test.txt"); - request.setFolder("test-project"); + request.setFolder("system/test-project"); repository.saveFile(mockFile, request); Assertions.assertTrue(repository.saveFile(mockFile, request) != null); Assertions.assertTrue(repository.saveFile("Hello, World!".getBytes(), request) != null);