diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/controller/handler/result/CommonResultCode.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/controller/handler/result/CommonResultCode.java index fa40aaa13a..94c4f99968 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/controller/handler/result/CommonResultCode.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/controller/handler/result/CommonResultCode.java @@ -7,7 +7,13 @@ package io.metersphere.sdk.controller.handler.result; */ public enum CommonResultCode implements IResultCode { - PLUGIN_GET_INSTANCE(100001, "get_plugin_instance_error"); + PLUGIN_GET_INSTANCE(100001, "get_plugin_instance_error"), + USER_ROLE_RELATION_EXIST(100002, "user_role_relation_exist_error"), + /** + * 调用获取全局用户组接口,如果操作的是内置的用户组,会返回该响应码 + */ + INTERNAL_USER_ROLE_PERMISSION(101003, "internal_user_role_permission_error"), + USER_ROLE_RELATION_REMOVE_ADMIN_USER_PERMISSION(100004, "user_role_relation_remove_admin_user_permission_error"); private int code; private String message; diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/request/PermissionSettingUpdateRequest.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/request/PermissionSettingUpdateRequest.java index 32231c8dde..c7d8688253 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/request/PermissionSettingUpdateRequest.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/request/PermissionSettingUpdateRequest.java @@ -1,6 +1,7 @@ package io.metersphere.sdk.dto.request; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.Data; @@ -17,6 +18,7 @@ public class PermissionSettingUpdateRequest { private String userRoleId; @NotNull @Schema(title = "菜单下的权限列表", requiredMode = Schema.RequiredMode.REQUIRED) + @Valid private List permissions; @Data diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/log/annotation/Log.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/log/annotation/Log.java index 237aeb26bc..d1c62377eb 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/log/annotation/Log.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/log/annotation/Log.java @@ -37,7 +37,7 @@ public @interface Log { /** * 资源ID */ - String sourceId() default "NONE"; + String sourceId() default ""; /** * 创建用户 diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/BaseUserRolePermissionService.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/BaseUserRolePermissionService.java index 495bdfe000..7306117f35 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/BaseUserRolePermissionService.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/BaseUserRolePermissionService.java @@ -75,4 +75,10 @@ public class BaseUserRolePermissionService { } }); } + + public void deleteByRoleId(String roleId) { + UserRolePermissionExample example = new UserRolePermissionExample(); + example.createCriteria().andRoleIdEqualTo(roleId); + userRolePermissionMapper.deleteByExample(example); + } } diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/BaseUserRoleRelationService.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/BaseUserRoleRelationService.java new file mode 100644 index 0000000000..d2c09b0cb1 --- /dev/null +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/BaseUserRoleRelationService.java @@ -0,0 +1,101 @@ +package io.metersphere.sdk.service; + +import io.metersphere.sdk.exception.MSException; +import io.metersphere.system.domain.UserRole; +import io.metersphere.system.domain.UserRoleRelation; +import io.metersphere.system.domain.UserRoleRelationExample; +import io.metersphere.system.mapper.UserRoleRelationMapper; +import jakarta.annotation.Resource; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.UUID; + +import static io.metersphere.sdk.constants.InternalUserRole.ADMIN; +import static io.metersphere.sdk.controller.handler.result.CommonResultCode.*; + +/** + * @author jianxing + */ +@Service +@Transactional(rollbackFor = Exception.class) +public class BaseUserRoleRelationService { + + @Resource + protected UserRoleRelationMapper userRoleRelationMapper; + @Resource + @Lazy + protected BaseUserRoleService baseUserRoleService; + + + protected UserRoleRelation add(UserRoleRelation userRoleRelation) { + checkExist(userRoleRelation); + userRoleRelation.setCreateTime(System.currentTimeMillis()); + userRoleRelation.setId(UUID.randomUUID().toString()); + userRoleRelationMapper.insert(userRoleRelation); + return userRoleRelation; + } + + /** + * 校验用户是否已在当前用户组 + */ + public void checkExist(UserRoleRelation userRoleRelation) { + UserRoleRelationExample example = new UserRoleRelationExample(); + example.createCriteria() + .andUserIdEqualTo(userRoleRelation.getUserId()) + .andRoleIdEqualTo(userRoleRelation.getRoleId()); + + List userRoleRelations = userRoleRelationMapper.selectByExample(example); + if (CollectionUtils.isNotEmpty(userRoleRelations)) { + throw new MSException(USER_ROLE_RELATION_EXIST); + } + } + + public UserRole getUserRole(String id) { + UserRoleRelation userRoleRelation = userRoleRelationMapper.selectByPrimaryKey(id); + return baseUserRoleService.get(userRoleRelation.getRoleId()); + } + + protected void delete(String id) { + UserRoleRelation userRoleRelation = userRoleRelationMapper.selectByPrimaryKey(id); + checkAdminPermissionRemove(userRoleRelation.getUserId(), userRoleRelation.getRoleId()); + userRoleRelationMapper.deleteByPrimaryKey(id); + } + + public void deleteByRoleId(String roleId) { + List userRoleRelations = getByRoleId(roleId); + userRoleRelations.forEach(userRoleRelation -> + checkAdminPermissionRemove(userRoleRelation.getUserId(), userRoleRelation.getRoleId())); + UserRoleRelationExample example = new UserRoleRelationExample(); + example.createCriteria().andRoleIdEqualTo(roleId); + userRoleRelationMapper.deleteByExample(example); + } + + public List getByRoleId(String roleId) { + UserRoleRelationExample example = new UserRoleRelationExample(); + example.createCriteria().andRoleIdEqualTo(roleId); + return userRoleRelationMapper.selectByExample(example); + } + + /** + * admin 不能从系统管理员用户组删除 + */ + private static void checkAdminPermissionRemove(String userId, String roleId) { + if (StringUtils.equals(roleId, ADMIN.getValue()) && StringUtils.equals(userId, ADMIN.getValue())) { + throw new MSException(USER_ROLE_RELATION_REMOVE_ADMIN_USER_PERMISSION); + } + } + + public String getLogDetails(String id) { + UserRoleRelation userRoleRelation = userRoleRelationMapper.selectByPrimaryKey(id); + if (userRoleRelation != null) { + UserRole userRole = baseUserRoleService.get(userRoleRelation.getRoleId()); + return userRole == null ? null : userRole.getName(); + } + return null; + } +} diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/BaseUserRoleService.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/BaseUserRoleService.java index b27f67d7a5..f82e88b416 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/BaseUserRoleService.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/BaseUserRoleService.java @@ -3,11 +3,13 @@ package io.metersphere.sdk.service; import io.metersphere.sdk.dto.Permission; import io.metersphere.sdk.dto.PermissionDefinitionItem; import io.metersphere.sdk.dto.request.PermissionSettingUpdateRequest; +import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.util.PermissionCache; import io.metersphere.system.domain.UserRole; import io.metersphere.system.mapper.UserRoleMapper; import jakarta.annotation.Resource; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -16,6 +18,8 @@ import java.util.List; import java.util.Set; import java.util.UUID; +import static io.metersphere.sdk.controller.handler.result.CommonResultCode.INTERNAL_USER_ROLE_PERMISSION; + /** * @author jianxing */ @@ -29,6 +33,8 @@ public class BaseUserRoleService { private UserRoleMapper userRoleMapper; @Resource private BaseUserRolePermissionService baseUserRolePermissionService; + @Resource + private BaseUserRoleRelationService baseUserRoleRelationService; /** * 根据用户组获取对应的权限配置项 @@ -100,4 +106,34 @@ public class BaseUserRoleService { userRoleMapper.updateByPrimaryKeySelective(userRole); return userRole; } + + /** + * 删除用户组,并且删除用户组与用户的关联关系,用户组与权限的关联关系 + * @param userRole + */ + public void delete(UserRole userRole) { + String id = userRole.getId(); + checkInternalUserRole(userRole); + baseUserRolePermissionService.deleteByRoleId(id); + baseUserRoleRelationService.deleteByRoleId(id); + userRoleMapper.deleteByPrimaryKey(id); + } + + /** + * 校验是否是内置用户组,是内置抛异常 + */ + public void checkInternalUserRole(UserRole userRole) { + if (BooleanUtils.isTrue(userRole.getInternal())) { + throw new MSException(INTERNAL_USER_ROLE_PERMISSION); + } + } + + public UserRole get(String id) { + return userRoleMapper.selectByPrimaryKey(id); + } + + public String getLogDetails(String id) { + UserRole userRole = userRoleMapper.selectByPrimaryKey(id); + return userRole == null ? null : userRole.getName(); + } } diff --git a/backend/framework/sdk/src/main/resources/i18n/commons_en_US.properties b/backend/framework/sdk/src/main/resources/i18n/commons_en_US.properties index 083fd2b520..93bb2fdeab 100644 --- a/backend/framework/sdk/src/main/resources/i18n/commons_en_US.properties +++ b/backend/framework/sdk/src/main/resources/i18n/commons_en_US.properties @@ -388,6 +388,10 @@ source_bug_template_is_empty=Copy error, source project is empty #plugin get_plugin_instance_error=Get the plugin instance error! +# userRole +user_role_relation_exist_error=The user is already in the current user group! +internal_user_role_permission_error=Internal user groups cannot be edited or deleted! +user_role_relation_remove_admin_user_permission_error=Unable to delete the admin user from the system administrator user group! #result message http_result_success=operate success diff --git a/backend/framework/sdk/src/main/resources/i18n/commons_zh_CN.properties b/backend/framework/sdk/src/main/resources/i18n/commons_zh_CN.properties index bab6ff54ac..dbb12b3ac5 100644 --- a/backend/framework/sdk/src/main/resources/i18n/commons_zh_CN.properties +++ b/backend/framework/sdk/src/main/resources/i18n/commons_zh_CN.properties @@ -387,6 +387,10 @@ source_bug_template_is_empty=复制错误,源项目为空 #plugin get_plugin_instance_error=获取插件接口实现类错误! +# userRole +user_role_relation_exist_error=用户已在当前用户组! +internal_user_role_permission_error=内置用户组无法编辑与删除! +user_role_relation_remove_admin_user_permission_error=无法将 admin 用户将系统管理员用户组删除! #result message http_result_success=操作成功 diff --git a/backend/framework/sdk/src/main/resources/i18n/commons_zh_TW.properties b/backend/framework/sdk/src/main/resources/i18n/commons_zh_TW.properties index a4eb93b3cf..72c106c098 100644 --- a/backend/framework/sdk/src/main/resources/i18n/commons_zh_TW.properties +++ b/backend/framework/sdk/src/main/resources/i18n/commons_zh_TW.properties @@ -385,6 +385,10 @@ source_bug_template_is_empty=複製錯誤,源項目為空 #plugin get_plugin_instance_error=獲取插件接口實現類錯誤! +# userRole +user_role_relation_exist_error=用戶已在當前用戶組! +internal_user_role_permission_error=內置用戶組無法編輯與刪除! +user_role_relation_remove_admin_user_permission_error=無法將 admin 用戶將系統管理員用戶組刪除! #result message http_result_success=操作成功 diff --git a/backend/framework/sdk/src/main/resources/i18n/system_zh_CN.properties b/backend/framework/sdk/src/main/resources/i18n/system_zh_CN.properties index 22b125541a..5b27499198 100644 --- a/backend/framework/sdk/src/main/resources/i18n/system_zh_CN.properties +++ b/backend/framework/sdk/src/main/resources/i18n/system_zh_CN.properties @@ -153,4 +153,9 @@ organization.create_user.length_range=工作空间创建人长度必须在{min} and_add_organization_admin=并添加组织管理员 organization_add_member_ids_empty=组织添加成员不能为空 organization_not_exist=组织不存在 -organization_member_not_exist=组织成员不存在 \ No newline at end of file +organization_member_not_exist=组织成员不存在 + +# userRole +global_user_role_permission_error=没有权限操作非全局用户组 +global_user_role_exist_error=全局用户组已存在 +global_user_role_relation_system_permission_error=没有权限操作非系统级别用户组 \ No newline at end of file diff --git a/backend/framework/sdk/src/test/java/base/BaseTest.java b/backend/framework/sdk/src/test/java/base/BaseTest.java index 517ff56a55..bde50bb328 100644 --- a/backend/framework/sdk/src/test/java/base/BaseTest.java +++ b/backend/framework/sdk/src/test/java/base/BaseTest.java @@ -1,13 +1,20 @@ package base; +import base.param.InvalidateParamInfo; +import base.param.ParamGeneratorFactory; import com.jayway.jsonpath.JsonPath; import io.metersphere.sdk.constants.SessionConstants; +import io.metersphere.sdk.controller.handler.result.IResultCode; +import io.metersphere.sdk.log.constants.OperationLogType; import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.Pager; import io.metersphere.system.domain.OperationLogExample; import io.metersphere.system.mapper.OperationLogMapper; +import io.metersphere.validation.groups.Created; +import io.metersphere.validation.groups.Updated; import jakarta.annotation.Resource; import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.TestMethodOrder; @@ -23,8 +30,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import java.util.List; import java.util.Map; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @SpringBootTest @AutoConfigureMockMvc @@ -77,8 +83,8 @@ public abstract class BaseTest { .andExpect(content().contentType(MediaType.APPLICATION_JSON)); } - protected MvcResult requestPostAndReturn(String url, Object... uriVariables) throws Exception { - return this.requestPost(url, uriVariables).andReturn(); + protected MvcResult requestPostAndReturn(String url, Object param, Object... uriVariables) throws Exception { + return this.requestPost(url, param, uriVariables).andReturn(); } protected ResultActions requestGet(String url, Object... uriVariables) throws Exception { @@ -120,6 +126,17 @@ public abstract class BaseTest { return JSON.parseArray(JSON.toJSONString(data), clazz); } + /** + * 校验错误响应码 + */ + protected void assertErrorCode(ResultActions resultActions, IResultCode resultCode) throws Exception { + resultActions + .andExpect( + jsonPath("$.code") + .value(resultCode.getCode()) + ); + } + protected Pager> getPageResult(MvcResult mvcResult, Class clazz) throws Exception { Map pagerResult = (Map) JSON.parseMap(mvcResult.getResponse().getContentAsString()).get("data"); List list = JSON.parseArray(JSON.toJSONString(pagerResult.get("list")), clazz); @@ -131,15 +148,64 @@ public abstract class BaseTest { return pager; } - protected void checkLog(String resourceId, String type) throws Exception { + protected void checkLog(String resourceId, OperationLogType operationLogType) throws Exception { OperationLogExample example = new OperationLogExample(); - example.createCriteria().andSourceIdEqualTo(resourceId).andTypeEqualTo(type); + example.createCriteria().andSourceIdEqualTo(resourceId).andTypeEqualTo(operationLogType.name()); operationLogMapper.selectByExample(example).stream() .filter(operationLog -> operationLog.getSourceId().equals(resourceId)) - .filter(operationLog -> operationLog.getType().equals(type)) + .filter(operationLog -> operationLog.getType().equals(operationLogType.name())) .filter(operationLog -> StringUtils.isNotBlank(operationLog.getProjectId())) .filter(operationLog -> StringUtils.isNotBlank(operationLog.getModule())) .findFirst() .orElseThrow(() -> new Exception("日志不存在,请补充操作日志")); } + + /** + * Created 分组参数校验 + */ + protected void createdGroupParamValidateTest(Class clazz, String path) throws Exception { + paramValidateTest(Created.class, clazz, path); + } + + /** + * Updated 分组参数校验 + */ + protected void updatedGroupParamValidateTest(Class clazz, String path) throws Exception { + paramValidateTest(Updated.class, clazz, path); + } + + /** + * 没有分组的参数校验 + */ + protected void paramValidateTest(Class clazz, String path) throws Exception { + paramValidateTest(null, clazz, path); + } + + /** + * 根据指定的参数定义,自动生成异常参数,进行参数校验的测试 + * + * @param group 分组 + * @param clazz 参数类名 + * @param path 请求路径 + * @param 参数类型 + * @throws Exception + */ + private void paramValidateTest(Class group, Class clazz, String path) throws Exception { + System.out.println("paramValidateTest-start: ===================================="); + System.out.println("url: " + getBasePath() + path); + + List invalidateParamInfos = ParamGeneratorFactory.generateInvalidateParams(group, clazz); + for (InvalidateParamInfo invalidateParamInfo : invalidateParamInfos) { + System.out.println("valid: " + invalidateParamInfo.getName() + " " + invalidateParamInfo.getAnnotation().getSimpleName()); + System.out.println("param: " + JSON.toJSONString(invalidateParamInfo.getValue())); + MvcResult mvcResult = this.requestPostAndReturn(path, invalidateParamInfo.getValue()); + // 校验错误是否是参数错误 + Assertions.assertEquals(400, mvcResult.getResponse().getStatus()); + Map resultData = getResultData(mvcResult, Map.class); + System.out.println("result: " + resultData); + // 校验错误信息中包含了该字段 + Assertions.assertTrue(resultData.containsKey(invalidateParamInfo.getName())); + } + System.out.println("paramValidateTest-end: ===================================="); + } } diff --git a/backend/framework/sdk/src/test/java/base/param/EmailParamGenerator.java b/backend/framework/sdk/src/test/java/base/param/EmailParamGenerator.java new file mode 100644 index 0000000000..1d5d1e050a --- /dev/null +++ b/backend/framework/sdk/src/test/java/base/param/EmailParamGenerator.java @@ -0,0 +1,18 @@ +package base.param; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; + +/** + * @author jianxing + */ +public class EmailParamGenerator extends ParamGenerator { + + /** + * 返回非邮件格式的字符串 + */ + @Override + public Object invalidGenerate(Annotation annotation, Field field) { + return "111111111"; + } +} diff --git a/backend/framework/sdk/src/test/java/base/param/EnumValueParamGenerator.java b/backend/framework/sdk/src/test/java/base/param/EnumValueParamGenerator.java new file mode 100644 index 0000000000..c3b1b77488 --- /dev/null +++ b/backend/framework/sdk/src/test/java/base/param/EnumValueParamGenerator.java @@ -0,0 +1,40 @@ +package base.param; + + +import io.metersphere.sdk.constants.ValueEnum; +import io.metersphere.sdk.valid.EnumValue; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; + +/** + * @author jianxing + */ +public class EnumValueParamGenerator extends ParamGenerator { + + /** + * 生成一个不在枚举值中的数值 + */ + @Override + public Object invalidGenerate(Annotation annotation, Field field) { + EnumValue enumValue = (EnumValue) annotation; + Class enumClass = enumValue.enumClass(); + String[] excludeValues = enumValue.excludeValues(); + // 获取枚举的所有实例 + Enum[] enums = enumClass.getEnumConstants(); + boolean isStr = true; + if (enums[0] instanceof ValueEnum) { + Object value = ((ValueEnum) enums[0]).getValue(); + // 获取枚举值,判断是否是字符串类型 + if (value != null && !(value instanceof String)) { + isStr = false; + } + } + // 如果有排除值,则返回排除值 + if (excludeValues != null && excludeValues.length > 0) { + return excludeValues[0]; + } + // 这里伪生成一个不在枚举值中的数值,仅支持字符串和整型 + return isStr ? "1" : Integer.MAX_VALUE; + } +} diff --git a/backend/framework/sdk/src/test/java/base/param/InvalidateParamInfo.java b/backend/framework/sdk/src/test/java/base/param/InvalidateParamInfo.java new file mode 100644 index 0000000000..16990ff130 --- /dev/null +++ b/backend/framework/sdk/src/test/java/base/param/InvalidateParamInfo.java @@ -0,0 +1,16 @@ +package base.param; + +import lombok.Data; + +@Data +public class InvalidateParamInfo { + private String name; + private Object value; + private Class annotation; + + public InvalidateParamInfo(String name, Object value, Class annotation) { + this.name = name; + this.value = value; + this.annotation = annotation; + } +} diff --git a/backend/framework/sdk/src/test/java/base/param/MaxParamGenerator.java b/backend/framework/sdk/src/test/java/base/param/MaxParamGenerator.java new file mode 100644 index 0000000000..cb2be7f17d --- /dev/null +++ b/backend/framework/sdk/src/test/java/base/param/MaxParamGenerator.java @@ -0,0 +1,24 @@ +package base.param; + +import jakarta.validation.constraints.Max; +import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; + +/** + * @author jianxing + */ +public class MaxParamGenerator extends ParamGenerator { + + @Override + public Object invalidGenerate(Annotation annotation, Field field) { + Max maxAnnotation = (Max) annotation; + if (isNumberType(field.getType())) { + return convertToNumberType(field.getType(), maxAnnotation.value() + 1); + } else { + // todo 做缓存优化 + return RandomStringUtils.random((int) (maxAnnotation.value() + 1)); + } + } +} diff --git a/backend/framework/sdk/src/test/java/base/param/MinParamGenerator.java b/backend/framework/sdk/src/test/java/base/param/MinParamGenerator.java new file mode 100644 index 0000000000..c884954772 --- /dev/null +++ b/backend/framework/sdk/src/test/java/base/param/MinParamGenerator.java @@ -0,0 +1,27 @@ +package base.param; + +import jakarta.validation.constraints.Min; +import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; + +/** + * @author jianxing + */ +public class MinParamGenerator extends ParamGenerator { + + /** + * 返回 null + */ + @Override + public Object invalidGenerate(Annotation annotation, Field field) { + Min minAnnotation = (Min) annotation; + if (isNumberType(field.getType())) { + return convertToNumberType(field.getType(), minAnnotation.value() - 1); + } else { + // todo 做缓存优化 + return RandomStringUtils.random((int) (minAnnotation.value() - 1)); + } + } +} diff --git a/backend/framework/sdk/src/test/java/base/param/NotBlankParamGenerator.java b/backend/framework/sdk/src/test/java/base/param/NotBlankParamGenerator.java new file mode 100644 index 0000000000..e45cbf7080 --- /dev/null +++ b/backend/framework/sdk/src/test/java/base/param/NotBlankParamGenerator.java @@ -0,0 +1,20 @@ +package base.param; + +import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; + +/** + * @author jianxing + */ +public class NotBlankParamGenerator extends ParamGenerator { + + /** + * 生成空字符串 + */ + @Override + public Object invalidGenerate(Annotation annotation, Field field) { + return StringUtils.EMPTY; + } +} diff --git a/backend/framework/sdk/src/test/java/base/param/NotNullParamGenerator.java b/backend/framework/sdk/src/test/java/base/param/NotNullParamGenerator.java new file mode 100644 index 0000000000..95696b62bc --- /dev/null +++ b/backend/framework/sdk/src/test/java/base/param/NotNullParamGenerator.java @@ -0,0 +1,18 @@ +package base.param; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; + +/** + * @author jianxing + */ +public class NotNullParamGenerator extends ParamGenerator { + + /** + * 返回 null + */ + @Override + public Object invalidGenerate(Annotation annotation, Field field) { + return null; + } +} diff --git a/backend/framework/sdk/src/test/java/base/param/ParamGenerator.java b/backend/framework/sdk/src/test/java/base/param/ParamGenerator.java new file mode 100644 index 0000000000..62081c5c96 --- /dev/null +++ b/backend/framework/sdk/src/test/java/base/param/ParamGenerator.java @@ -0,0 +1,75 @@ +package base.param; + +import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/** + * 单元测试参数生成器 + * @author jianxing + */ +public abstract class ParamGenerator { + + /** + * 生成非法参数 + * @param annotation 注解 + * @param field 字段 + * @return 非法参数 + */ + public abstract Object invalidGenerate(Annotation annotation, Field field); + + /** + * 通过反射获取注解上的分组信息,判断是否匹配 + * @param group 当前分组 + * @param annotation 注解 + * @return 是否匹配 + */ + public boolean isGroupMatch(Class group, Annotation annotation) { + Method[] methods = annotation.getClass().getDeclaredMethods(); + for (Method method : methods) { + if (StringUtils.equals(method.getName(), "groups")) { + try { + Class[] groups = (Class[]) method.invoke(annotation); + if (groups.length == 0) { + // 注解上没有分组,如果当前分组为空,则匹配,否则不匹配 + return group == null; + } + for (Class groupItem : groups) { + if (groupItem.equals(group)) { + // 有一个匹配成功则返回true + return true; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return false; + } + + protected boolean isNumberType(Class clazz) { + return (clazz.isPrimitive() && clazz != boolean.class && clazz != char.class) + || Number.class.isAssignableFrom(clazz); + } + + protected T convertToNumberType(Class clazz, long value) { + if (clazz == int.class || clazz == Integer.class) { + return (T) Integer.valueOf((int) value); + } else if (clazz == long.class || clazz == Long.class) { + return (T) Long.valueOf(value); + } else if (clazz == short.class || clazz == Short.class) { + return (T) Short.valueOf((short) value); + } else if (clazz == byte.class || clazz == Byte.class) { + return (T) Byte.valueOf((byte) value); + } else if (clazz == float.class || clazz == Float.class) { + return (T) Float.valueOf((float) value); + } else if (clazz == double.class || clazz == Double.class) { + return (T) Double.valueOf((double) value); + } else { + throw new IllegalArgumentException("不支持的类型:" + clazz); + } + } +} diff --git a/backend/framework/sdk/src/test/java/base/param/ParamGeneratorFactory.java b/backend/framework/sdk/src/test/java/base/param/ParamGeneratorFactory.java new file mode 100644 index 0000000000..4eacd33074 --- /dev/null +++ b/backend/framework/sdk/src/test/java/base/param/ParamGeneratorFactory.java @@ -0,0 +1,128 @@ +package base.param; + +import io.metersphere.sdk.util.BeanUtils; +import io.metersphere.sdk.valid.EnumValue; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; +import org.apache.commons.lang3.StringUtils; +import org.springframework.validation.annotation.Validated; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author jianxing + */ +public class ParamGeneratorFactory { + + private static final Map paramGeneratorMap = new HashMap<>() {{ + put(Size.class.getName(), new SizeParamGenerator()); + put(NotBlank.class.getName(), new NotBlankParamGenerator()); + put(NotNull.class.getName(), new NotNullParamGenerator()); + put(EnumValue.class.getName(), new EnumValueParamGenerator()); + put(Min.class.getName(), new MinParamGenerator()); + put(Max.class.getName(), new MaxParamGenerator()); + put(Email.class.getName(), new EmailParamGenerator()); + }}; + + public static ParamGenerator getParamGenerator(Annotation annotation) { + return paramGeneratorMap.get(annotation.annotationType().getName()); + } + + /** + * 根据指定的参数定义和分组,自动生成异常参数列表 + * @param group 接口分组 + * @param clazz 参数类型 + * @return 异常参数列表 + * @param 参数类型 + * @throws Exception + */ + public static List generateInvalidateParams(Class group, Class clazz) throws Exception { + List paramList = new ArrayList(); + // 通过反射获取当前类的所有属性 + Field[] fields = clazz.getDeclaredFields(); + // 遍历属性,获取每个属性上的所有注解 + for (Field field : fields) { + Annotation[] annotations = field.getAnnotations(); + // 遍历注解,获取注解的类型 + for (Annotation annotation : annotations) { + // 获取处理指定注解的生成器 + ParamGenerator paramGenerator = getParamGenerator(annotation); + // 生成器不为空,并且如果有指定 group 时,需要匹配 group + if (paramGenerator != null && paramGenerator.isGroupMatch(group, annotation)) { + T param = clazz.getConstructor().newInstance(); + // 生成异常数据 + Object invalidValue = paramGenerator.invalidGenerate(annotation, field); + // 将参数值赋为异常数据 + getSetMethod(clazz, field).invoke(param, invalidValue); + InvalidateParamInfo invalidateParamInfo = + new InvalidateParamInfo(field.getName(), param, annotation.annotationType()); + paramList.add(invalidateParamInfo); + } + // 如果是嵌套的校验注解,需要递归处理 + if (StringUtils.equalsAny(annotation.annotationType().getName(), Valid.class.getName(), Validated.class.getName())) { + Class fieldClazz = Class.forName(field.getType().getName()); + if (List.class.isAssignableFrom(fieldClazz)) { + // 如果是数组,解析数组里的泛型 + Class genericClazz = getaGenericClass(field, 0); + List genericParamList = generateInvalidateParams(group, genericClazz); + for (InvalidateParamInfo genericParam : genericParamList) { + List list = new ArrayList(1); + list.add(genericParam.getValue()); + T param = clazz.getConstructor().newInstance(); + getSetMethod(clazz, field).invoke(param, list); + InvalidateParamInfo invalidateParamInfo = new InvalidateParamInfo(field.getName() + "[0]" + "." + genericParam.getName(), + param, genericParam.getAnnotation()); + paramList.add(invalidateParamInfo); + } + } else if (Map.class.isAssignableFrom(fieldClazz)) { + // 如果是 Map,解析数组里的泛型 + Class genericClazz = getaGenericClass(field, 1); + List genericParamList = generateInvalidateParams(group, genericClazz); + for (InvalidateParamInfo genericParam : genericParamList) { + Map map = new HashMap(1); + map.put("key", genericParam.getValue()); + T param = clazz.getConstructor().newInstance(); + getSetMethod(clazz, field).invoke(param, map); + InvalidateParamInfo invalidateParamInfo = new InvalidateParamInfo(field.getName() + "[key]" + "." + genericParam.getName(), + param, genericParam.getAnnotation()); + paramList.add(invalidateParamInfo); + } + } else { + // 如果是对象,解析对象里的泛型 + List objParamList = generateInvalidateParams(group, field.getType()); + for (InvalidateParamInfo objParam : objParamList) { + T newParam = clazz.getConstructor().newInstance(); + BeanUtils.copyBean(newParam, newParam); + getSetMethod(clazz, field).invoke(newParam, objParam.getValue()); + InvalidateParamInfo invalidateParamInfo = new InvalidateParamInfo(field.getName() + "." + objParam.getName(), + newParam, objParam.getAnnotation()); + paramList.add(invalidateParamInfo); + } + } + } + } + } + return paramList; + } + + private static Class getaGenericClass(Field field, int index) throws ClassNotFoundException { + Class genericClazz = Class.forName( + ( + (Class) ((ParameterizedType) field.getGenericType()) + .getActualTypeArguments()[index] + ).getName() + ); + return genericClazz; + } + + private static Method getSetMethod(Class clazz, Field field) throws Exception { + return clazz.getMethod("set" + StringUtils.capitalize(field.getName()), field.getType()); + } +} diff --git a/backend/framework/sdk/src/test/java/base/param/SizeParamGenerator.java b/backend/framework/sdk/src/test/java/base/param/SizeParamGenerator.java new file mode 100644 index 0000000000..f3be300f56 --- /dev/null +++ b/backend/framework/sdk/src/test/java/base/param/SizeParamGenerator.java @@ -0,0 +1,28 @@ +package base.param; + +import jakarta.validation.constraints.Size; +import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; + +/** + * @author jianxing + */ +public class SizeParamGenerator extends ParamGenerator { + + /** + * 生成超过指定长度的字符串 + */ + @Override + public Object invalidGenerate(Annotation annotation, Field field) { + Size sizeAnnotation = (Size) annotation; + int max = sizeAnnotation.max(); + if (isNumberType(field.getType())) { + return max + 1; + } else { + // todo 做缓存优化 + return RandomStringUtils.random(max + 1); + } + } +} diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/controller/GlobalUserRoleController.java b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/GlobalUserRoleController.java index 2d79c2dc7f..c905083828 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/controller/GlobalUserRoleController.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/GlobalUserRoleController.java @@ -51,7 +51,7 @@ public class GlobalUserRoleController { @PostMapping("/permission/update") @Operation(summary = "编辑全局用户组对应的权限配置") @RequiresPermissions(PermissionConstants.SYSTEM_USER_ROLE_UPDATE) - @Log(isBefore = true, type = OperationLogType.UPDATE, module = OperationLogModule.SYSTEM_USER_ROLE, + @Log(type = OperationLogType.UPDATE, module = OperationLogModule.SYSTEM_USER_ROLE, details = "#msClass.getLogDetails(#request.userRoleId)", msClass = GlobalUserRoleService.class) public void updatePermissionSetting(@Validated @RequestBody PermissionSettingUpdateRequest request) { globalUserRoleService.updatePermissionSetting(request); @@ -60,8 +60,7 @@ public class GlobalUserRoleController { @PostMapping("/add") @Operation(summary = "添加自定义全局用户组") @RequiresPermissions(PermissionConstants.SYSTEM_USER_ROLE_ADD) - @Log(type = OperationLogType.ADD, module = OperationLogModule.SYSTEM_USER_ROLE, - sourceId = "#request.id", details = "#request.name") + @Log(type = OperationLogType.ADD, module = OperationLogModule.SYSTEM_USER_ROLE, details = "#request.name") public UserRole add(@Validated({Created.class}) @RequestBody UserRoleUpdateRequest request) { UserRole userRole = new UserRole(); userRole.setCreateUser(SessionUtils.getUserId()); @@ -72,7 +71,7 @@ public class GlobalUserRoleController { @PostMapping("/update") @Operation(summary = "更新自定义全局用户组") @RequiresPermissions(PermissionConstants.SYSTEM_USER_ROLE_UPDATE) - @Log(isBefore = true, type = OperationLogType.UPDATE, module = OperationLogModule.SYSTEM_USER_ROLE, + @Log(type = OperationLogType.UPDATE, module = OperationLogModule.SYSTEM_USER_ROLE, sourceId = "#request.id", details = "#request.name") public UserRole update(@Validated({Updated.class}) @RequestBody UserRoleUpdateRequest request) { UserRole userRole = new UserRole(); @@ -84,7 +83,7 @@ public class GlobalUserRoleController { @Operation(summary = "删除自定义全局用户组") @RequiresPermissions(PermissionConstants.SYSTEM_USER_ROLE_DELETE) @Log(isBefore = true, type = OperationLogType.DELETE, module = OperationLogModule.SYSTEM_USER_ROLE, - details = "#msClass.getLogDetails(#id)", msClass = GlobalUserRoleService.class) + sourceId = "#id", details = "#msClass.getLogDetails(#id)", msClass = GlobalUserRoleService.class) public void delete(@PathVariable String id) { globalUserRoleService.delete(id); } diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/controller/GlobalUserRoleRelationController.java b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/GlobalUserRoleRelationController.java index 2821da8b18..1d1682ff2f 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/controller/GlobalUserRoleRelationController.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/GlobalUserRoleRelationController.java @@ -48,8 +48,7 @@ public class GlobalUserRoleRelationController { @PostMapping("/add") @Operation(summary = "创建全局用户组和用户的关联关系") @RequiresPermissions(PermissionConstants.SYSTEM_USER_ROLE_RELATION_ADD) - @Log(isBefore = true, type = OperationLogType.ADD, module = OperationLogModule.SYSTEM_USER_ROLE_RELATION, - details = "#msClass.getLogDetails(#id)", msClass = GlobalUserRoleRelationService.class) + @Log(type = OperationLogType.ADD, module = OperationLogModule.SYSTEM_USER_ROLE_RELATION, details = "#request.name") public UserRoleRelation add(@Validated({Created.class}) @RequestBody GlobalUserRoleRelationUpdateRequest request) { UserRoleRelation userRoleRelation = new UserRoleRelation(); BeanUtils.copyBean(userRoleRelation, request); @@ -60,7 +59,7 @@ public class GlobalUserRoleRelationController { @GetMapping("/delete/{id}") @Operation(summary = "删除全局用户组和用户的关联关系") @RequiresPermissions(PermissionConstants.SYSTEM_USER_ROLE_RELATION_DELETE) - @Log(isBefore = true, type = OperationLogType.DELETE, module = OperationLogModule.SYSTEM_USER_ROLE_RELATION, + @Log(isBefore = true, type = OperationLogType.DELETE, sourceId = "#id", module = OperationLogModule.SYSTEM_USER_ROLE_RELATION, details = "#msClass.getLogDetails(#id)", msClass = GlobalUserRoleRelationService.class) public void delete(@PathVariable String id) { globalUserRoleRelationService.delete(id); diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/controller/result/SystemResultCode.java b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/result/SystemResultCode.java index 933be8f69a..a30c5e4d28 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/controller/result/SystemResultCode.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/result/SystemResultCode.java @@ -10,15 +10,9 @@ public enum SystemResultCode implements IResultCode { /** * 调用获取全局用户组接口,如果操作的是非全局的用户组,会返回该响应码 */ - GLOBAL_USER_ROLE_PERMISSION(101001, "没有权限操作非全局用户组"), - /** - * 调用获取全局用户组接口,如果操作的是内置的用户组,会返回该响应码 - */ - INTERNAL_USER_ROLE_PERMISSION(101002, "内置用户组无法编辑与删除"), - GLOBAL_USER_ROLE_EXIST(101003, "全局用户组已存在"), - GLOBAL_USER_ROLE_RELATION_EXIST(101004, "用户已在当前用户组"), - GLOBAL_USER_ROLE_RELATION_SYSTEM_PERMISSION(101005, "没有权限操作非系统级别用户组"), - GLOBAL_USER_ROLE_RELATION_REMOVE_ADMIN_USER_PERMISSION(101005, "无法将 admin 用户将系统管理员用户组删除") + GLOBAL_USER_ROLE_PERMISSION(101001, "global_user_role_permission_error"), + GLOBAL_USER_ROLE_EXIST(101002, "global_user_role_exist_error"), + GLOBAL_USER_ROLE_RELATION_SYSTEM_PERMISSION(101003, "global_user_role_relation_system_permission_error") ; private final int code; diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/GlobalUserRoleRelationService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/GlobalUserRoleRelationService.java index 8b8321543b..7c1e010471 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/service/GlobalUserRoleRelationService.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/GlobalUserRoleRelationService.java @@ -1,30 +1,23 @@ package io.metersphere.system.service; -import io.metersphere.sdk.exception.MSException; +import io.metersphere.sdk.dto.UserRoleRelationUserDTO; +import io.metersphere.sdk.service.BaseUserRoleRelationService; import io.metersphere.system.domain.UserRole; import io.metersphere.system.domain.UserRoleRelation; -import io.metersphere.system.domain.UserRoleRelationExample; -import io.metersphere.sdk.dto.UserRoleRelationUserDTO; +import io.metersphere.system.dto.request.GlobalUserRoleRelationQueryRequest; import io.metersphere.system.mapper.ExtUserRoleRelationMapper; import io.metersphere.system.mapper.UserRoleRelationMapper; -import java.util.List; -import java.util.UUID; - import jakarta.annotation.Resource; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; -import io.metersphere.system.dto.request.GlobalUserRoleRelationQueryRequest; -import static io.metersphere.sdk.constants.InternalUserRole.ADMIN; -import static io.metersphere.system.controller.result.SystemResultCode.*; +import java.util.List; /** * @author jianxing * @date : 2023-6-12 */ @Service -public class GlobalUserRoleRelationService { +public class GlobalUserRoleRelationService extends BaseUserRoleRelationService { @Resource private UserRoleRelationMapper userRoleRelationMapper; @@ -40,58 +33,20 @@ public class GlobalUserRoleRelationService { return extUserRoleRelationMapper.listGlobal(request); } + @Override public UserRoleRelation add(UserRoleRelation userRoleRelation) { UserRole userRole = globalUserRoleService.get(userRoleRelation.getRoleId()); - checkExist(userRoleRelation); globalUserRoleService.checkSystemUserGroup(userRole); globalUserRoleService.checkGlobalUserRole(userRole); - userRoleRelation.setSourceId(GlobalUserRoleService.SYSTEM_TYPE); - userRoleRelation.setCreateTime(System.currentTimeMillis()); - userRoleRelation.setId(UUID.randomUUID().toString()); - userRoleRelationMapper.insert(userRoleRelation); - return userRoleRelation; - } - - /** - * 校验用户是否已在当前用户组 - */ - public void checkExist(UserRoleRelation userRoleRelation) { - UserRoleRelationExample example = new UserRoleRelationExample(); - example.createCriteria() - .andUserIdEqualTo(userRoleRelation.getUserId()) - .andRoleIdEqualTo(userRoleRelation.getRoleId()); - - List userRoleRelations = userRoleRelationMapper.selectByExample(example); - if (CollectionUtils.isNotEmpty(userRoleRelations)) { - throw new MSException(GLOBAL_USER_ROLE_RELATION_EXIST); - } + return super.add(userRoleRelation); } + @Override public void delete(String id) { - UserRoleRelation userRoleRelation = userRoleRelationMapper.selectByPrimaryKey(id); - UserRole userRole = globalUserRoleService.get(userRoleRelation.getRoleId()); - checkAdminPermissionRemove(userRoleRelation, userRole); + UserRole userRole = getUserRole(id); globalUserRoleService.checkSystemUserGroup(userRole); globalUserRoleService.checkGlobalUserRole(userRole); - userRoleRelationMapper.deleteByPrimaryKey(id); - } - - /** - * admin 不能从系统管理员用户组删除 - */ - private static void checkAdminPermissionRemove(UserRoleRelation userRoleRelation, UserRole userRole) { - if (StringUtils.equals(userRole.getId(), ADMIN.getValue()) && StringUtils.equals(userRoleRelation.getUserId(), ADMIN.getValue())) { - throw new MSException(GLOBAL_USER_ROLE_RELATION_REMOVE_ADMIN_USER_PERMISSION); - } - } - - public String getLogDetails(String id) { - UserRoleRelation userRoleRelation = userRoleRelationMapper.selectByPrimaryKey(id); - if (userRoleRelation != null) { - UserRole userRole = globalUserRoleService.get(userRoleRelation.getRoleId()); - return userRole == null ? null : userRole.getName(); - } - return null; + super.delete(id); } } diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/GlobalUserRoleService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/GlobalUserRoleService.java index 4651a95270..fd600627ac 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/service/GlobalUserRoleService.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/GlobalUserRoleService.java @@ -14,7 +14,6 @@ import jakarta.annotation.Resource; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -55,15 +54,6 @@ public class GlobalUserRoleService extends BaseUserRoleService { } } - /** - * 校验是否是内置用户组,是内置抛异常 - */ - public void checkInternalUserRole(UserRole userRole) { - if (BooleanUtils.isTrue(userRole.getInternal())) { - throw new MSException(INTERNAL_USER_ROLE_PERMISSION); - } - } - /** * 校验用户是否是系统用户组 */ @@ -105,15 +95,10 @@ public class GlobalUserRoleService extends BaseUserRoleService { return super.update(userRole); } - public UserRole get(String id) { - return userRoleMapper.selectByPrimaryKey(id); - } - public void delete(String id) { UserRole userRole = get(id); checkGlobalUserRole(userRole); - checkInternalUserRole(userRole); - userRoleMapper.deleteByPrimaryKey(id); + delete(userRole); } public void checkRoleIsGlobalAndHaveMember(@Valid @NotEmpty List roleIdList, boolean isSystem) { @@ -155,9 +140,4 @@ public class GlobalUserRoleService extends BaseUserRoleService { checkInternalUserRole(userRole); super.updatePermissionSetting(request); } - - public String getLogDetails(String id) { - UserRole userRole = userRoleMapper.selectByPrimaryKey(id); - return userRole == null ? null : userRole.getName(); - } } diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/CommonParamTest.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/CommonParamTest.java new file mode 100644 index 0000000000..26fd87f7c0 --- /dev/null +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/CommonParamTest.java @@ -0,0 +1,42 @@ +package io.metersphere.system.controller; + +import base.BaseTest; +import io.metersphere.system.controller.param.BasePageRequestDefinition; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MvcResult; + +import java.util.HashMap; +import java.util.Map; + +@SpringBootTest +@AutoConfigureMockMvc +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +class CommonParamTest extends BaseTest { + + /** + * 校验 BasePageRequestDefinition 参数 + * @throws Exception + */ + @Test + void testBasePageRequestDefinition() throws Exception { + String url = GlobalUserRoleRelationControllerTest.BASE_URL + GlobalUserRoleRelationControllerTest.LIST; + paramValidateTest(BasePageRequestDefinition.class, url); + BasePageRequestDefinition basePageRequestDefinition = new BasePageRequestDefinition(); + // @@校验 sort 字段 sql 防注入,有点复杂,手动写校验 + String sortName = "SELECT * FROM user"; + basePageRequestDefinition.setSort(new HashMap<>() {{ + put(sortName, "asc"); + }}); + MvcResult mvcResult = this.requestPostAndReturn(url, basePageRequestDefinition); + // 校验错误是否是参数错误 + Assertions.assertEquals(400, mvcResult.getResponse().getStatus()); + Map resultData = getResultData(mvcResult, Map.class); + // 校验错误信息中包含了该字段 + Assertions.assertTrue(resultData.containsKey(String.format("sort[%s]", sortName))); + } +} \ No newline at end of file diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/GlobalUserRoleControllerTest.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/GlobalUserRoleControllerTest.java index 4bf5ce14c1..91d2822ed2 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/GlobalUserRoleControllerTest.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/GlobalUserRoleControllerTest.java @@ -8,8 +8,12 @@ import io.metersphere.sdk.dto.Permission; import io.metersphere.sdk.dto.PermissionDefinitionItem; import io.metersphere.sdk.dto.request.PermissionSettingUpdateRequest; import io.metersphere.sdk.dto.request.UserRoleUpdateRequest; +import io.metersphere.sdk.log.constants.OperationLogType; import io.metersphere.sdk.service.BaseUserRolePermissionService; +import io.metersphere.sdk.service.BaseUserRoleRelationService; import io.metersphere.sdk.util.BeanUtils; +import io.metersphere.system.controller.param.PermissionSettingUpdateRequestDefinition; +import io.metersphere.system.controller.param.UserRoleUpdateRequestDefinition; import io.metersphere.system.domain.UserRole; import io.metersphere.system.mapper.UserRoleMapper; import jakarta.annotation.Resource; @@ -24,9 +28,9 @@ import java.util.*; import java.util.stream.Collectors; import static io.metersphere.sdk.constants.InternalUserRole.ADMIN; +import static io.metersphere.sdk.controller.handler.result.CommonResultCode.INTERNAL_USER_ROLE_PERMISSION; import static io.metersphere.system.controller.result.SystemResultCode.*; import static io.metersphere.system.service.GlobalUserRoleService.GLOBAL_SCOPE; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @SpringBootTest @AutoConfigureMockMvc @@ -36,7 +40,8 @@ class GlobalUserRoleControllerTest extends BaseTest { private UserRoleMapper userRoleMapper; @Resource private BaseUserRolePermissionService baseUserRolePermissionService; - + @Resource + private BaseUserRoleRelationService baseUserRoleRelationService; private static final String BASE_PATH = "/user/role/global/"; private static final String LIST = "list"; private static final String ADD = "add"; @@ -54,7 +59,6 @@ class GlobalUserRoleControllerTest extends BaseTest { @Test void list() throws Exception { - // @@请求成功 MvcResult mvcResult = this.requestGetWithOk(LIST) .andReturn(); @@ -74,7 +78,6 @@ class GlobalUserRoleControllerTest extends BaseTest { @Test @Order(0) void add() throws Exception { - // @@请求成功 UserRoleUpdateRequest request = new UserRoleUpdateRequest(); request.setName("test"); @@ -84,23 +87,23 @@ class GlobalUserRoleControllerTest extends BaseTest { UserRole resultData = getResultData(mvcResult, UserRole.class); UserRole userRole = userRoleMapper.selectByPrimaryKey(resultData.getId()); // 校验请求成功数据 + this.addUserRole = userRole; Assertions.assertEquals(request.getName(), userRole.getName()); Assertions.assertEquals(request.getType(), userRole.getType()); Assertions.assertEquals(request.getDescription(), userRole.getDescription()); - this.addUserRole = userRole; + // @@校验日志 + checkLog(this.addUserRole.getId(), OperationLogType.ADD); // @@重名校验异常 - this.requestPost(ADD, request) - .andExpect( - jsonPath("$.code") - .value(GLOBAL_USER_ROLE_EXIST.getCode()) - ); + assertErrorCode(this.requestPost(ADD, request), GLOBAL_USER_ROLE_EXIST); + + // @@异常参数校验 + createdGroupParamValidateTest(UserRoleUpdateRequestDefinition.class, ADD); } @Test @Order(1) void update() throws Exception { - // @@请求成功 UserRoleUpdateRequest request = new UserRoleUpdateRequest(); request.setId(addUserRole.getId()); @@ -114,23 +117,25 @@ class GlobalUserRoleControllerTest extends BaseTest { Assertions.assertEquals(request.getType(), userRoleResult.getType()); Assertions.assertEquals(request.getDescription(), userRoleResult.getDescription()); + // @@校验日志 + checkLog(request.getId(), OperationLogType.UPDATE); + // @@操作非全局用户组异常 BeanUtils.copyBean(request, getNonGlobalUserRole()); - this.requestPost(UPDATE, request) - .andExpect(jsonPath("$.code").value(GLOBAL_USER_ROLE_PERMISSION.getCode())); + assertErrorCode(this.requestPost(UPDATE, request), GLOBAL_USER_ROLE_PERMISSION); // @@操作内置用户组异常 request.setId(ADMIN.getValue()); request.setName(ADMIN.getValue()); - this.requestPost(UPDATE, request) - .andExpect(jsonPath("$.code").value(INTERNAL_USER_ROLE_PERMISSION.getCode())); + assertErrorCode(this.requestPost(UPDATE, request), INTERNAL_USER_ROLE_PERMISSION); // @@重名校验异常 request.setId(addUserRole.getId()); request.setName("系统管理员"); - this.requestPost(UPDATE, request) - .andExpect(jsonPath("$.code").value(GLOBAL_USER_ROLE_EXIST.getCode())); - this.requestPost(UPDATE, new UserRole()); + assertErrorCode(this.requestPost(UPDATE, request), GLOBAL_USER_ROLE_EXIST); + + // @@异常参数校验 + updatedGroupParamValidateTest(UserRoleUpdateRequestDefinition.class, UPDATE); } @Test @@ -176,15 +181,13 @@ class GlobalUserRoleControllerTest extends BaseTest { Assertions.assertTrue(CollectionUtils.isEmpty(permissionIds)); // @@操作非全局用户组异常 - this.requestGet(PERMISSION_SETTING, getNonGlobalUserRole().getId()) - .andExpect(jsonPath("$.code").value(GLOBAL_USER_ROLE_PERMISSION.getCode())); + assertErrorCode(this.requestGet(PERMISSION_SETTING, getNonGlobalUserRole().getId()), GLOBAL_USER_ROLE_PERMISSION); } @Test @Order(2) void updatePermissionSetting() throws Exception { - PermissionSettingUpdateRequest request = new PermissionSettingUpdateRequest(); request.setPermissions(new ArrayList<>() {{ PermissionSettingUpdateRequest.PermissionUpdateRequest permission1 @@ -211,15 +214,19 @@ class GlobalUserRoleControllerTest extends BaseTest { // 校验请求成功数据 Assertions.assertEquals(requestPermissionIds, permissionIds); + // @@校验日志 + checkLog(request.getUserRoleId(), OperationLogType.UPDATE); + // @@操作非全局用户组异常 request.setUserRoleId(getNonGlobalUserRole().getId()); - this.requestPost(PERMISSION_UPDATE, request) - .andExpect(jsonPath("$.code").value(GLOBAL_USER_ROLE_PERMISSION.getCode())); + assertErrorCode(this.requestPost(PERMISSION_UPDATE, request), GLOBAL_USER_ROLE_PERMISSION); // @@操作内置用户组异常 request.setUserRoleId(ADMIN.getValue()); - this.requestPost(PERMISSION_UPDATE, request) - .andExpect(jsonPath("$.code").value(INTERNAL_USER_ROLE_PERMISSION.getCode())); + assertErrorCode(this.requestPost(PERMISSION_UPDATE, request), INTERNAL_USER_ROLE_PERMISSION); + + // @@异常参数校验 + paramValidateTest(PermissionSettingUpdateRequestDefinition.class, PERMISSION_UPDATE); } @Test @@ -229,21 +236,25 @@ class GlobalUserRoleControllerTest extends BaseTest { this.requestGet(DELETE, addUserRole.getId()); // 校验请求成功数据 Assertions.assertNull(userRoleMapper.selectByPrimaryKey(addUserRole.getId())); + // 校验用户组与权限的关联关系是否删除 + Assertions.assertTrue(CollectionUtils.isEmpty(baseUserRolePermissionService.getByRoleId(addUserRole.getId()))); + // 校验用户组与用户的关联关系是否删除 + Assertions.assertTrue(CollectionUtils.isEmpty(baseUserRoleRelationService.getByRoleId(addUserRole.getId()))); + + // @@校验日志 + checkLog(addUserRole.getId(), OperationLogType.DELETE); // @@操作非全局用户组异常 - this.requestGet(DELETE, getNonGlobalUserRole().getId()) - .andExpect(jsonPath("$.code").value(GLOBAL_USER_ROLE_PERMISSION.getCode())); + assertErrorCode(this.requestGet(DELETE, getNonGlobalUserRole().getId()), GLOBAL_USER_ROLE_PERMISSION); // @@操作内置用户组异常 - this.requestGet(DELETE, ADMIN.getValue()) - .andExpect(jsonPath("$.code").value(INTERNAL_USER_ROLE_PERMISSION.getCode())); - + assertErrorCode(this.requestGet(DELETE, ADMIN.getValue()), INTERNAL_USER_ROLE_PERMISSION); } /** * 插入一条非全局用户组,并返回 */ - private UserRole getNonGlobalUserRole() { + protected UserRole getNonGlobalUserRole() { // 插入一条非全局用户组数据 UserRole nonGlobalUserRole = userRoleMapper.selectByPrimaryKey(ADMIN.getValue()); nonGlobalUserRole.setName("非全局用户组"); diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/GlobalUserRoleRelationControllerTest.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/GlobalUserRoleRelationControllerTest.java index e4ba188925..688460971e 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/GlobalUserRoleRelationControllerTest.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/GlobalUserRoleRelationControllerTest.java @@ -3,7 +3,10 @@ package io.metersphere.system.controller; import base.BaseTest; import io.metersphere.sdk.dto.UserRoleRelationUserDTO; import io.metersphere.sdk.dto.request.GlobalUserRoleRelationUpdateRequest; +import io.metersphere.sdk.log.constants.OperationLogType; import io.metersphere.sdk.util.Pager; +import io.metersphere.system.controller.param.GlobalUserRoleRelationQueryRequestDefinition; +import io.metersphere.system.controller.param.GlobalUserRoleRelationUpdateRequestDefinition; import io.metersphere.system.domain.UserRole; import io.metersphere.system.domain.UserRoleRelation; import io.metersphere.system.domain.UserRoleRelationExample; @@ -24,17 +27,18 @@ import java.util.stream.Collectors; import static io.metersphere.sdk.constants.InternalUserRole.ADMIN; import static io.metersphere.sdk.constants.InternalUserRole.ORG_ADMIN; +import static io.metersphere.sdk.controller.handler.result.CommonResultCode.USER_ROLE_RELATION_EXIST; +import static io.metersphere.sdk.controller.handler.result.CommonResultCode.USER_ROLE_RELATION_REMOVE_ADMIN_USER_PERMISSION; import static io.metersphere.system.controller.result.SystemResultCode.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @SpringBootTest @AutoConfigureMockMvc @TestMethodOrder(MethodOrderer.OrderAnnotation.class) class GlobalUserRoleRelationControllerTest extends BaseTest { - private static final String BASE_URL = "/user/role/relation/global/"; - private static final String LIST = "list"; - private static final String ADD = "add"; - private static final String DELETE = "delete/{0}"; + public static final String BASE_URL = "/user/role/relation/global/"; + public static final String LIST = "list"; + public static final String ADD = "add"; + public static final String DELETE = "delete/{0}"; // 保存创建的数据,方便之后的修改和删除测试使用 private static UserRoleRelation addUserRoleRelation; @Resource @@ -70,18 +74,17 @@ class GlobalUserRoleRelationControllerTest extends BaseTest { // 检查查询结果和数据库结果是否一致 Assertions.assertEquals(userIdSet, dbUserIdSet); - // @@操作非系统级别用户组异常 request.setRoleId(ORG_ADMIN.getValue()); - this.requestPost(LIST, request) - .andExpect(jsonPath("$.code").value(GLOBAL_USER_ROLE_RELATION_SYSTEM_PERMISSION.getCode())); + assertErrorCode(this.requestPost(LIST, request), GLOBAL_USER_ROLE_RELATION_SYSTEM_PERMISSION); // @@操作非全局用户组异常 UserRole nonGlobalUserRole = getNonGlobalUserRole(); request.setRoleId(nonGlobalUserRole.getId()); - this.requestPost(LIST, request) - .andExpect(jsonPath("$.code").value(GLOBAL_USER_ROLE_PERMISSION.getCode())); + assertErrorCode(this.requestPost(LIST, request), GLOBAL_USER_ROLE_PERMISSION); + // @@异常参数校验 + paramValidateTest(GlobalUserRoleRelationQueryRequestDefinition.class, LIST); } @Test @@ -103,33 +106,27 @@ class GlobalUserRoleRelationControllerTest extends BaseTest { Assertions.assertTrue(CollectionUtils.isNotEmpty(userRoleRelationMapper.selectByExample(example))); addUserRoleRelation = userRoleRelationMapper.selectByExample(example).get(0); + // @@校验日志 + checkLog(addUserRoleRelation.getId(), OperationLogType.ADD); + // @@重复添加校验 request.setUserId(ADMIN.getValue()); request.setRoleId(ADMIN.getValue()); - this.requestPost(ADD, request) - .andExpect( - jsonPath("$.code") - .value(GLOBAL_USER_ROLE_RELATION_EXIST.getCode()) - ); + assertErrorCode(this.requestPost(ADD, request), USER_ROLE_RELATION_EXIST); // @@操作非系统用户组异常 request.setUserId(ADMIN.getValue()); request.setRoleId(ORG_ADMIN.getValue()); - this.requestPost(ADD, request) - .andExpect( - jsonPath("$.code") - .value(GLOBAL_USER_ROLE_RELATION_SYSTEM_PERMISSION.getCode()) - ); + assertErrorCode(this.requestPost(ADD, request), GLOBAL_USER_ROLE_RELATION_SYSTEM_PERMISSION); // @@操作非全局用户组异常 UserRole nonGlobalUserRole = getNonGlobalUserRole(); request.setUserId(ADMIN.getValue()); request.setRoleId(nonGlobalUserRole.getId()); - this.requestPost(ADD, request) - .andExpect( - jsonPath("$.code") - .value(GLOBAL_USER_ROLE_PERMISSION.getCode()) - ); + assertErrorCode(this.requestPost(ADD, request), GLOBAL_USER_ROLE_PERMISSION); + + // @@异常参数校验 + createdGroupParamValidateTest(GlobalUserRoleRelationUpdateRequestDefinition.class, ADD); } @Test @@ -140,13 +137,15 @@ class GlobalUserRoleRelationControllerTest extends BaseTest { UserRoleRelation userRoleRelation = userRoleRelationMapper.selectByPrimaryKey(addUserRoleRelation.getId()); Assertions.assertNull(userRoleRelation); + // @@校验日志 + checkLog(addUserRoleRelation.getId(), OperationLogType.DELETE); + // @@操作非系统级别用户组异常 - this.requestGet(DELETE, getNonSystemUserRoleRelation().getId()) - .andExpect(jsonPath("$.code").value(GLOBAL_USER_ROLE_RELATION_SYSTEM_PERMISSION.getCode())); + assertErrorCode(this.requestGet(DELETE, getNonSystemUserRoleRelation().getId()), + GLOBAL_USER_ROLE_RELATION_SYSTEM_PERMISSION); // @@操作非全局用户组异常 - this.requestGet(DELETE, getNonGlobalUserRoleRelation().getId()) - .andExpect(jsonPath("$.code").value(GLOBAL_USER_ROLE_PERMISSION.getCode())); + assertErrorCode(this.requestGet(DELETE, getNonGlobalUserRoleRelation().getId()), GLOBAL_USER_ROLE_PERMISSION); // @@删除admin系统管理员用户组异常 UserRoleRelationExample example = new UserRoleRelationExample(); @@ -154,8 +153,8 @@ class GlobalUserRoleRelationControllerTest extends BaseTest { .andRoleIdEqualTo(ADMIN.getValue()) .andUserIdEqualTo(ADMIN.getValue()); List userRoleRelations = userRoleRelationMapper.selectByExample(example); - this.requestGet(DELETE, userRoleRelations.get(0).getId()) - .andExpect(jsonPath("$.code").value(GLOBAL_USER_ROLE_RELATION_REMOVE_ADMIN_USER_PERMISSION.getCode())); + assertErrorCode(this.requestGet(DELETE, userRoleRelations.get(0).getId()), + USER_ROLE_RELATION_REMOVE_ADMIN_USER_PERMISSION); } /** diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/SystemProjectControllerTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/SystemProjectControllerTests.java index e0e14f0e61..08ae8dcdd0 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/SystemProjectControllerTests.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/SystemProjectControllerTests.java @@ -169,7 +169,7 @@ public class SystemProjectControllerTests extends BaseTest { List projects = projectMapper.selectByExample(projectExample); projectId = result.getId(); // 校验日志 - checkLog(projectId, OperationLogType.ADD.name()); + checkLog(projectId, OperationLogType.ADD); this.compareProjectDTO(projects.get(0), result); UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample(); diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/UserControllerTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/UserControllerTests.java index 0a4e1c7267..007c125cb8 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/UserControllerTests.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/UserControllerTests.java @@ -95,7 +95,7 @@ public class UserControllerTests extends BaseTest { UserBatchCreateDTO userMaintainRequest = UserTestUtils.parseObjectFromMvcResult(mvcResult, UserBatchCreateDTO.class); userMaintainRequest.getUserInfoList().forEach(item ->{ try { - checkLog(item.getId(), OperationLogType.ADD.name()); + checkLog(item.getId(), OperationLogType.ADD); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/param/BasePageRequestDefinition.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/param/BasePageRequestDefinition.java new file mode 100644 index 0000000000..39f6e9a3b9 --- /dev/null +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/param/BasePageRequestDefinition.java @@ -0,0 +1,26 @@ +package io.metersphere.system.controller.param; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import lombok.Data; + +import java.util.Map; + +/** + * BasePageRequest 约束定义 + * @author jianxing + */ +@Data +public class BasePageRequestDefinition { + @Min(value = 1) + private int current; + + @Min(value = 5) + @Max(value = 100) + private int pageSize; + + private Map<@Valid @Pattern(regexp = "^[A-Za-z]+$") String, @Valid @NotBlank String> sort; +} diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/param/GlobalUserRoleRelationQueryRequestDefinition.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/param/GlobalUserRoleRelationQueryRequestDefinition.java new file mode 100644 index 0000000000..399fb0f059 --- /dev/null +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/param/GlobalUserRoleRelationQueryRequestDefinition.java @@ -0,0 +1,15 @@ +package io.metersphere.system.controller.param; + +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +/** + * @author : jianxing + */ +@Getter +@Setter +public class GlobalUserRoleRelationQueryRequestDefinition { + @NotBlank + private String roleId; +} diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/param/GlobalUserRoleRelationUpdateRequestDefinition.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/param/GlobalUserRoleRelationUpdateRequestDefinition.java new file mode 100644 index 0000000000..93711d59e2 --- /dev/null +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/param/GlobalUserRoleRelationUpdateRequestDefinition.java @@ -0,0 +1,22 @@ +package io.metersphere.system.controller.param; + +import io.metersphere.validation.groups.Created; +import io.metersphere.validation.groups.Updated; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; +import lombok.Data; + +/** + * @author jianxing + */ +@Data +public class GlobalUserRoleRelationUpdateRequestDefinition { + + @NotBlank(groups = {Created.class}) + @Size(min = 1, max = 50, groups = {Created.class, Updated.class}) + private String userId; + + @NotBlank(groups = {Created.class}) + @Size(min = 1, max = 50, groups = {Created.class, Updated.class}) + private String roleId; +} diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/param/PermissionSettingUpdateRequestDefinition.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/param/PermissionSettingUpdateRequestDefinition.java new file mode 100644 index 0000000000..f2bae7554f --- /dev/null +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/param/PermissionSettingUpdateRequestDefinition.java @@ -0,0 +1,30 @@ +package io.metersphere.system.controller.param; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.util.List; + +/** + * PermissionSettingUpdateRequest 约束定义 + * 基于该定义生成非法参数进行参数校验 + * 相对 PermissionSettingUpdateRequest 不需要写 swagger 的注解,也不用写 massage + * 有继承通用的参数的话,可以单独针对通用参数写一次校验就行,就不继承了,例如 BasePageRequestDefinition + * @author jianxing + */ +@Data +public class PermissionSettingUpdateRequestDefinition { + @NotBlank + private String userRoleId; + @NotNull + @Valid + private List permissions; + + @Data + public static class PermissionUpdateRequest { + @NotBlank + private String id; + } +} diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/param/UserRoleUpdateRequestDefinition.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/param/UserRoleUpdateRequestDefinition.java new file mode 100644 index 0000000000..0c75bd699c --- /dev/null +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/param/UserRoleUpdateRequestDefinition.java @@ -0,0 +1,29 @@ +package io.metersphere.system.controller.param; + +import io.metersphere.sdk.constants.UserRoleType; +import io.metersphere.sdk.valid.EnumValue; +import io.metersphere.validation.groups.Created; +import io.metersphere.validation.groups.Updated; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; +import lombok.Data; + +/** + * UserRoleUpdateRequest 约束定义 + * @author jianxing + */ +@Data +public class UserRoleUpdateRequestDefinition { + @NotBlank(groups = {Updated.class}) + @Size(min = 1, max = 50, groups = {Created.class, Updated.class}) + private String id; + + @NotBlank(groups = {Created.class}) + @Size(min = 1, max = 255, groups = {Created.class, Updated.class}) + private String name; + + @NotBlank(groups = {Created.class}) + @EnumValue(enumClass = UserRoleType.class, groups = {Created.class}) + @Size(min = 1, max = 20, groups = {Created.class, Updated.class}) + private String type; +}