feat(系统设置): 部分接口添加文件上传大小限制
This commit is contained in:
parent
748b4e93e4
commit
bb2a6ab074
|
@ -68,8 +68,8 @@ spring.flyway.validate-on-migrate=false
|
|||
# jmeter
|
||||
jmeter.home=/opt/jmeter
|
||||
# file upload
|
||||
spring.servlet.multipart.max-file-size=500MB
|
||||
spring.servlet.multipart.max-request-size=500MB
|
||||
spring.servlet.multipart.max-file-size=1024MB
|
||||
spring.servlet.multipart.max-request-size=1024MB
|
||||
# i18n
|
||||
spring.messages.basename=i18n/commons,i18n/api,i18n/bug,i18n/case,i18n/plan,i18n/project,i18n/system
|
||||
# actuator
|
||||
|
|
|
@ -5,3 +5,6 @@ SET SESSION innodb_lock_wait_timeout = 7200;
|
|||
-- 组织管理员增加权限
|
||||
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'org_admin', 'ORGANIZATION_PROJECT_MEMBER_UPDATE');
|
||||
|
||||
-- 初始化默认参数文件上传大小
|
||||
INSERT INTO system_parameter (param_key, param_value, type) VALUES ('upload.file.size', '50', 'text');
|
||||
|
||||
|
|
|
@ -328,6 +328,8 @@ operation_history.version_id.length_range=变更记录版本 ID 长度必须在{
|
|||
user_open_source_max=系统用户数超额({num}人),继续添加用户可申请企业版适用
|
||||
user_dept_max=系统用户数超额({num}人),继续添加用户可申请企业版扩容
|
||||
|
||||
# file_upload
|
||||
file_upload.size_limit=上传文件大小超过系统限制
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -332,3 +332,5 @@ permission.organization_task_center.stop=Stop task
|
|||
user_open_source_max=There are too many users({num}),please apply for the enterprise version to use
|
||||
user_dept_max=There are too many users({num}),please apply for enterprise version expansion
|
||||
|
||||
# file_upload
|
||||
file_upload.size_limit=Upload file size exceeds system limit
|
|
@ -333,3 +333,6 @@ permission.organization_task_center.name=任务中心
|
|||
permission.organization_task_center.stop=停止
|
||||
user_open_source_max=系统用户数超额({0}人),继续添加用户可申请企业版适用
|
||||
user_dept_max=系统用户数超额({0}人),继续添加用户可申请企业版扩容
|
||||
|
||||
# file_upload
|
||||
file_upload.size_limit=上传文件大小超过系统限制
|
||||
|
|
|
@ -332,3 +332,6 @@ permission.organization_task_center.name=任務中心
|
|||
permission.organization_task_center.stop=停止
|
||||
user_open_source_max=系統用戶數超額({num}人),繼續添加用戶可申請企業版適用
|
||||
user_dept_max=系統用戶數超額({num}人),繼續添加用戶可申請企業版擴容
|
||||
|
||||
# file_upload
|
||||
file_upload.size_limit=上傳文件大小超過系統限制
|
|
@ -14,8 +14,8 @@ import io.metersphere.project.service.FileModuleService;
|
|||
import io.metersphere.sdk.constants.DefaultRepositoryDir;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.sdk.dto.api.task.TaskRequestDTO;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
||||
import io.metersphere.system.file.annotation.FileLimit;
|
||||
import io.metersphere.system.log.annotation.Log;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.security.CheckOwner;
|
||||
|
@ -69,6 +69,7 @@ public class ApiDebugController {
|
|||
return apiDebugService.add(request, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
@FileLimit
|
||||
@PostMapping("/upload/temp/file")
|
||||
@Operation(summary = "上传接口调试所需的文件资源,并返回文件ID")
|
||||
@RequiresPermissions(logical = Logical.OR, value = {PermissionConstants.PROJECT_API_DEBUG_ADD, PermissionConstants.PROJECT_API_DEBUG_UPDATE})
|
||||
|
|
|
@ -21,6 +21,7 @@ import io.metersphere.system.dto.OperationHistoryDTO;
|
|||
import io.metersphere.system.dto.request.OperationHistoryRequest;
|
||||
import io.metersphere.system.dto.request.OperationHistoryVersionRequest;
|
||||
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
||||
import io.metersphere.system.file.annotation.FileLimit;
|
||||
import io.metersphere.system.log.annotation.Log;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.notice.annotation.SendNotice;
|
||||
|
@ -203,6 +204,7 @@ public class ApiDefinitionController {
|
|||
return PageUtils.setPageInfo(page, apiDefinitionService.getDocPage(request, SessionUtils.getUserId()));
|
||||
}
|
||||
|
||||
@FileLimit
|
||||
@PostMapping("/upload/temp/file")
|
||||
@Operation(summary = "上传接口定义所需的文件资源,并返回文件ID")
|
||||
@RequiresPermissions(logical = Logical.OR, value = {PermissionConstants.PROJECT_API_DEFINITION_ADD, PermissionConstants.PROJECT_API_DEFINITION_UPDATE})
|
||||
|
|
|
@ -24,6 +24,7 @@ import io.metersphere.sdk.constants.PermissionConstants;
|
|||
import io.metersphere.system.dto.OperationHistoryDTO;
|
||||
import io.metersphere.system.dto.request.OperationHistoryRequest;
|
||||
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
||||
import io.metersphere.system.file.annotation.FileLimit;
|
||||
import io.metersphere.system.log.annotation.Log;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.notice.annotation.SendNotice;
|
||||
|
@ -136,6 +137,7 @@ public class ApiDefinitionMockController {
|
|||
return apiDefinitionMockService.copy(request, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
@FileLimit
|
||||
@PostMapping("/upload/temp/file")
|
||||
@Operation(summary = "上传接口 Mock 所需的文件资源,并返回文件ID")
|
||||
@RequiresPermissions(logical = Logical.OR, value = {PermissionConstants.PROJECT_API_DEFINITION_MOCK_ADD, PermissionConstants.PROJECT_API_DEFINITION_MOCK_UPDATE})
|
||||
|
|
|
@ -20,6 +20,7 @@ import io.metersphere.system.dto.OperationHistoryDTO;
|
|||
import io.metersphere.system.dto.request.OperationHistoryRequest;
|
||||
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
||||
import io.metersphere.system.dto.sdk.request.PosRequest;
|
||||
import io.metersphere.system.file.annotation.FileLimit;
|
||||
import io.metersphere.system.log.annotation.Log;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.notice.annotation.SendNotice;
|
||||
|
@ -225,6 +226,7 @@ public class ApiTestCaseController {
|
|||
apiTestCaseService.moveNode(request);
|
||||
}
|
||||
|
||||
@FileLimit
|
||||
@PostMapping("/upload/temp/file")
|
||||
@Operation(summary = "上传接口调试所需的文件资源,并返回文件ID")
|
||||
@RequiresPermissions(logical = Logical.OR, value = {PermissionConstants.PROJECT_API_DEFINITION_CASE_ADD, PermissionConstants.PROJECT_API_DEFINITION_CASE_UPDATE})
|
||||
|
|
|
@ -23,6 +23,7 @@ import io.metersphere.system.dto.OperationHistoryDTO;
|
|||
import io.metersphere.system.dto.request.OperationHistoryRequest;
|
||||
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
||||
import io.metersphere.system.dto.sdk.request.PosRequest;
|
||||
import io.metersphere.system.file.annotation.FileLimit;
|
||||
import io.metersphere.system.log.annotation.Log;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.notice.annotation.SendNotice;
|
||||
|
@ -96,6 +97,7 @@ public class ApiScenarioController {
|
|||
return apiScenarioService.add(request, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
@FileLimit
|
||||
@PostMapping("/upload/temp/file")
|
||||
@Operation(summary = "接口测试-接口场景管理-上传场景所需的文件资源,并返回文件ID")
|
||||
@RequiresPermissions(logical = Logical.OR, value = {PermissionConstants.PROJECT_API_SCENARIO_ADD, PermissionConstants.PROJECT_API_SCENARIO_UPDATE})
|
||||
|
|
|
@ -22,6 +22,7 @@ import io.metersphere.sdk.util.Translator;
|
|||
import io.metersphere.system.dto.sdk.TemplateCustomFieldDTO;
|
||||
import io.metersphere.system.dto.sdk.TemplateDTO;
|
||||
import io.metersphere.system.dto.sdk.request.PosRequest;
|
||||
import io.metersphere.system.file.annotation.FileLimit;
|
||||
import io.metersphere.system.log.annotation.Log;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.notice.annotation.SendNotice;
|
||||
|
@ -97,6 +98,7 @@ public class BugController {
|
|||
return PageUtils.setPageInfo(page, bugService.list(request));
|
||||
}
|
||||
|
||||
@FileLimit
|
||||
@PostMapping("/add")
|
||||
@Operation(summary = "缺陷管理-列表-创建缺陷")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_BUG_ADD)
|
||||
|
@ -108,6 +110,7 @@ public class BugController {
|
|||
return bugService.addOrUpdate(request, files, SessionUtils.getUserId(), SessionUtils.getCurrentOrganizationId(), false);
|
||||
}
|
||||
|
||||
@FileLimit
|
||||
@PostMapping("/update")
|
||||
@Operation(summary = "缺陷管理-列表-编辑缺陷")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_BUG_UPDATE)
|
||||
|
|
|
@ -21,6 +21,7 @@ import io.metersphere.system.dto.request.OperationHistoryRequest;
|
|||
import io.metersphere.system.dto.sdk.SessionUser;
|
||||
import io.metersphere.system.dto.sdk.TemplateDTO;
|
||||
import io.metersphere.system.dto.sdk.request.PosRequest;
|
||||
import io.metersphere.system.file.annotation.FileLimit;
|
||||
import io.metersphere.system.log.annotation.Log;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.notice.annotation.SendNotice;
|
||||
|
@ -74,6 +75,7 @@ public class FunctionalCaseController {
|
|||
}
|
||||
|
||||
|
||||
@FileLimit
|
||||
@PostMapping("/add")
|
||||
@Operation(summary = "用例管理-功能用例-新增用例")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_ADD)
|
||||
|
@ -95,7 +97,7 @@ public class FunctionalCaseController {
|
|||
return functionalCaseService.getFunctionalCaseDetail(id, userId, true);
|
||||
}
|
||||
|
||||
|
||||
@FileLimit
|
||||
@PostMapping("/update")
|
||||
@Operation(summary = "用例管理-功能用例-更新用例")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE)
|
||||
|
|
|
@ -7,6 +7,7 @@ import io.metersphere.project.service.FileManagementService;
|
|||
import io.metersphere.project.service.FileMetadataService;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.sdk.constants.StorageType;
|
||||
import io.metersphere.system.file.annotation.FileLimit;
|
||||
import io.metersphere.system.security.CheckOwner;
|
||||
import io.metersphere.system.utils.Pager;
|
||||
import io.metersphere.system.utils.SessionUtils;
|
||||
|
@ -66,6 +67,7 @@ public class FileManagementController {
|
|||
return fileMetadataService.moduleCount(request, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
@FileLimit
|
||||
@PostMapping("/upload")
|
||||
@Operation(summary = "项目管理-文件管理-上传文件")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_FILE_MANAGEMENT_READ_ADD)
|
||||
|
@ -74,6 +76,7 @@ public class FileManagementController {
|
|||
return fileMetadataService.upload(request, SessionUtils.getUserId(), uploadFile);
|
||||
}
|
||||
|
||||
@FileLimit
|
||||
@PostMapping("/re-upload")
|
||||
@Operation(summary = "项目管理-文件管理-重新上传文件")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_FILE_MANAGEMENT_READ_UPDATE)
|
||||
|
|
|
@ -7,6 +7,7 @@ import io.metersphere.system.domain.Plugin;
|
|||
import io.metersphere.system.dto.PluginDTO;
|
||||
import io.metersphere.system.dto.request.PlatformOptionRequest;
|
||||
import io.metersphere.system.dto.request.PluginUpdateRequest;
|
||||
import io.metersphere.system.file.annotation.FileLimit;
|
||||
import io.metersphere.system.log.annotation.Log;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.service.PluginLogService;
|
||||
|
@ -46,6 +47,7 @@ public class PluginController {
|
|||
return pluginService.list();
|
||||
}
|
||||
|
||||
@FileLimit
|
||||
@PostMapping("/add")
|
||||
@Operation(summary = "系统设置-系统-插件管理-创建插件")
|
||||
@RequiresPermissions(PermissionConstants.SYSTEM_PLUGIN_ADD)
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package io.metersphere.system.file.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface FileLimit {
|
||||
|
||||
/**
|
||||
* 文件大小限制 (单位: MB)
|
||||
*/
|
||||
long maxSize() default 0;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package io.metersphere.system.file.aspect;
|
||||
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.domain.SystemParameter;
|
||||
import io.metersphere.system.domain.SystemParameterExample;
|
||||
import io.metersphere.system.file.annotation.FileLimit;
|
||||
import io.metersphere.system.mapper.SystemParameterMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class FileLimitAspect {
|
||||
|
||||
@Resource
|
||||
private SystemParameterMapper systemParameterMapper;
|
||||
|
||||
@Pointcut("@annotation(io.metersphere.system.file.annotation.FileLimit)")
|
||||
public void limitPointCut() {
|
||||
|
||||
}
|
||||
|
||||
@Before("limitPointCut()")
|
||||
public void before(JoinPoint joinPoint) {
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
FileLimit limit = method.getAnnotation(FileLimit.class);
|
||||
// 获取方法参数
|
||||
Object[] args = joinPoint.getArgs();
|
||||
// 获取文件大小限制 (默认使用系统参数中的文件限制大小, 如果注解中有配置则使用注解中的配置)
|
||||
long fileMaxSize = limit.maxSize() != 0 ? limit.maxSize() : getFileMaxSize();
|
||||
for (Object arg : args) {
|
||||
// 单个文件
|
||||
if (arg instanceof MultipartFile file) {
|
||||
// 判断文件大小是否超过限制
|
||||
if (file.getSize() > fileMaxSize * 1024 * 1024) {
|
||||
throw new MSException(Translator.get("file_upload.size_limit"));
|
||||
}
|
||||
}
|
||||
// 多个文件
|
||||
if (arg instanceof List<?> files) {
|
||||
// 非 List<MultipartFile> 类型参数跳过
|
||||
if (CollectionUtils.isEmpty(files) || !(files.getFirst() instanceof MultipartFile)) {
|
||||
continue;
|
||||
}
|
||||
files.forEach(f -> {
|
||||
if (f instanceof MultipartFile file) {
|
||||
// 判断文件大小是否超过限制
|
||||
if (file.getSize() > fileMaxSize * 1024 * 1024) {
|
||||
throw new MSException(Translator.get("file_upload.size_limit"));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Long getFileMaxSize() {
|
||||
SystemParameterExample example = new SystemParameterExample();
|
||||
example.createCriteria().andParamKeyEqualTo("upload.file.size");
|
||||
List<SystemParameter> systemParameters = systemParameterMapper.selectByExample(example);
|
||||
return Long.parseLong(systemParameters.getFirst().getParamValue());
|
||||
}
|
||||
}
|
|
@ -4,6 +4,8 @@ import io.metersphere.plugin.platform.spi.Platform;
|
|||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.sdk.constants.PluginScenarioType;
|
||||
import io.metersphere.sdk.constants.SessionConstants;
|
||||
import io.metersphere.sdk.file.FileRequest;
|
||||
import io.metersphere.sdk.file.LocalFileRepository;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.system.base.BasePluginTestService;
|
||||
|
@ -12,15 +14,14 @@ import io.metersphere.system.controller.param.PluginUpdateRequestDefinition;
|
|||
import io.metersphere.system.domain.*;
|
||||
import io.metersphere.system.dto.OrganizationDTO;
|
||||
import io.metersphere.system.dto.PluginDTO;
|
||||
import io.metersphere.system.dto.request.PlatformOptionRequest;
|
||||
import io.metersphere.system.dto.request.PluginUpdateRequest;
|
||||
import io.metersphere.system.dto.sdk.OptionDTO;
|
||||
import io.metersphere.sdk.file.FileRequest;
|
||||
import io.metersphere.sdk.file.LocalFileRepository;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.mapper.PluginMapper;
|
||||
import io.metersphere.system.mapper.PluginOrganizationMapper;
|
||||
import io.metersphere.system.mapper.PluginScriptMapper;
|
||||
import io.metersphere.system.dto.request.PlatformOptionRequest;
|
||||
import io.metersphere.system.dto.request.PluginUpdateRequest;
|
||||
import io.metersphere.system.mapper.SystemParameterMapper;
|
||||
import io.metersphere.system.service.*;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -75,6 +76,8 @@ public class PluginControllerTests extends BaseTest {
|
|||
private PluginScriptService pluginScriptService;
|
||||
@Resource
|
||||
private LocalFileRepository localFileRepository;
|
||||
@Resource
|
||||
private SystemParameterMapper systemParameterMapper;
|
||||
private static Plugin addPlugin;
|
||||
private static Plugin anotherAddPlugin;
|
||||
|
||||
|
@ -186,7 +189,6 @@ public class PluginControllerTests extends BaseTest {
|
|||
getDefaultMultiPartParam(request, myDriver));
|
||||
Assertions.assertEquals(jdbcDriverPluginService.getJdbcDriverClass(DEFAULT_ORGANIZATION_ID), Arrays.asList("io.jianxing.MyDriver", "com.mysql.cj.jdbc.Driver"));
|
||||
|
||||
|
||||
// 校验QUOTA动上传成功
|
||||
request.setName("cloud-quota-plugin");
|
||||
request.setOrganizationIds(Arrays.asList(org.getId()));
|
||||
|
@ -196,6 +198,9 @@ public class PluginControllerTests extends BaseTest {
|
|||
);
|
||||
this.requestMultipartWithOkAndReturn(DEFAULT_ADD,
|
||||
getDefaultMultiPartParam(request, quota));
|
||||
// 设置文件限制为1M
|
||||
setMaxFileSizeTo1M();
|
||||
this.requestMultipart(DEFAULT_ADD, getDefaultMultiPartParam(request, quota), status().is5xxServerError());
|
||||
// 清理掉
|
||||
this.requestGetWithOk(DEFAULT_DELETE, "cloud-quota-plugin");
|
||||
|
||||
|
@ -458,4 +463,15 @@ public class PluginControllerTests extends BaseTest {
|
|||
.content(JSON.toJSONString(param))
|
||||
.contentType(MediaType.APPLICATION_JSON));
|
||||
}
|
||||
|
||||
private void setMaxFileSizeTo1M() {
|
||||
// 设置文件限制为1M
|
||||
SystemParameterExample example = new SystemParameterExample();
|
||||
example.createCriteria().andParamKeyEqualTo("upload.file.size");
|
||||
SystemParameter systemParameter = new SystemParameter();
|
||||
systemParameter.setParamKey("upload.file.size");
|
||||
systemParameter.setParamValue("1");
|
||||
systemParameter.setType("text");
|
||||
systemParameterMapper.updateByExample(systemParameter, example);
|
||||
}
|
||||
}
|
|
@ -45,11 +45,21 @@
|
|||
select brc.case_id as id, fc.num as num, 'FUNCTIONAL' as type, brc.bug_id as bugId, fc.name as name
|
||||
from bug_relation_case brc
|
||||
join functional_case fc on brc.case_id = fc.id
|
||||
union
|
||||
where brc.test_plan_id = #{planId}
|
||||
and brc.bug_id in
|
||||
<foreach collection="ids" item="id" separator="," open="(" close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
union all
|
||||
select brc.case_id as id, atc.num as num, 'API' as type, brc.bug_id as bugId, atc.name as name
|
||||
from bug_relation_case brc
|
||||
join api_test_case atc on brc.case_id = atc.id
|
||||
union
|
||||
where brc.test_plan_id = #{planId}
|
||||
and brc.bug_id in
|
||||
<foreach collection="ids" item="id" separator="," open="(" close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
union all
|
||||
select brc.case_id as id, asi.num as num, 'SCENARIO' as type, brc.bug_id as bugId, asi.name as name
|
||||
from bug_relation_case brc
|
||||
join api_scenario asi on brc.case_id = asi.id
|
||||
|
|
Loading…
Reference in New Issue