test(系统设置): 用户管理增加权限校验的测试用例

This commit is contained in:
song-tianyang 2023-06-15 14:40:34 +08:00 committed by f2c-ci-robot[bot]
parent 7b5afe5337
commit 88250f7797
11 changed files with 231 additions and 30 deletions

View File

@ -37,7 +37,7 @@ public class UserController {
private GlobalUserRoleService globalUserRoleService;
@GetMapping("/get/{email}")
@RequiresPermissions(PermissionConstants.SYSTEM_USER_READ)
@RequiresPermissions(PermissionConstants.SYSTEM_USER_ROLE_READ)
public UserDTO getUser(@PathVariable String email) {
return userService.getUserDTOByEmail(email);
}
@ -58,10 +58,10 @@ public class UserController {
@PostMapping("/update")
@RequiresPermissions(PermissionConstants.SYSTEM_USER_READ_UPDATE)
@RequestLog(type = OperationLogType.UPDATE, module = OperationLogModule.SYSTEM_USER,
sourceId = "#request.id", projectId = "#request.projectId", details = "#request.name")
public UserEditRequest updateUser(@Validated({Updated.class}) @RequestBody UserEditRequest userEditRequest) {
userEditRequest.setUpdateUser(SessionUtils.getSessionId());
return userService.updateUser(userEditRequest);
sourceId = "#request.id", details = "#request.name")
public UserEditRequest updateUser(@Validated({Updated.class}) @RequestBody UserEditRequest request) {
request.setUpdateUser(SessionUtils.getSessionId());
return userService.updateUser(request);
}
@PostMapping("/page")

View File

@ -7,9 +7,11 @@ import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
@EqualsAndHashCode(callSuper = true)
@Data
public class UserEditRequest extends UserInfo {
@Schema(title = "用户组", requiredMode = Schema.RequiredMode.REQUIRED)

View File

@ -1,6 +1,7 @@
package io.metersphere.system.service;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.domain.UserRole;
import io.metersphere.system.domain.UserRoleExample;
import io.metersphere.system.dto.UserRoleOption;
@ -66,7 +67,7 @@ public class GlobalUserRoleService {
throw new MSException("role.not.global");
}
if (!globalRoleList.contains("member")) {
throw new MSException("role.not.contains.member");
throw new MSException(Translator.get("role.not.contains.member"));
}
}

View File

@ -152,7 +152,7 @@ public class UserRoleRelationService {
return extUserRoleRelationMapper.selectGlobalRoleByUserId(userId);
}
public void updateUserSystemGlobalRole(@Valid User user, @Valid @NotEmpty List<String> roleList) {
public void updateUserSystemGlobalRole(@Valid User user, @Valid @NotEmpty String operator, @Valid @NotEmpty List<String> roleList) {
//更新用户权限
List<String> deleteRoleList = new ArrayList<>();
List<UserRoleRelation> saveList = new ArrayList<>();
@ -173,7 +173,7 @@ public class UserRoleRelationService {
userRoleRelation.setRoleId(roleId);
userRoleRelation.setSourceId("system");
userRoleRelation.setCreateTime(System.currentTimeMillis());
userRoleRelation.setCreateUser(user.getCreateUser());
userRoleRelation.setCreateUser(operator);
saveList.add(userRoleRelation);
}
}
@ -189,14 +189,14 @@ public class UserRoleRelationService {
deleteExample.createCriteria().andIdIn(deleteIdList);
userRoleRelationMapper.deleteByExample(deleteExample);
//记录删除日志
operationLogService.batchAdd(this.getBatchLogs(deleteRoleList, user, "updateUser", user.getCreateUser(), OperationLogType.DELETE.name()));
operationLogService.batchAdd(this.getBatchLogs(deleteRoleList, user, "updateUser", operator, OperationLogType.DELETE.name()));
}
if (CollectionUtils.isNotEmpty(saveList)) {
//系统级权限不会太多所以暂时不分批处理
saveList.forEach(item -> userRoleRelationMapper.insert(item));
//记录添加日志
operationLogService.batchAdd(this.getBatchLogs(saveList.stream().map(UserRoleRelation::getRoleId).toList(),
user, "updateUser", user.getCreateUser(), OperationLogType.ADD.name()));
user, "updateUser", operator, OperationLogType.ADD.name()));
}
}

View File

@ -147,12 +147,13 @@ public class UserService {
public UserEditRequest updateUser(UserEditRequest userEditRequest) {
//检查用户组合法性
globalUserRoleService.checkRoleIsGlobalAndHaveMember(userEditRequest.getUserRoleIdList(), true);
User user = new User();
BeanUtils.copyBean(user, userEditRequest);
user.setUpdateTime(System.currentTimeMillis());
user.setCreateUser(null);
user.setCreateTime(null);
userMapper.updateByPrimaryKeySelective(user);
userRoleRelationService.updateUserSystemGlobalRole(user, userEditRequest.getUserRoleIdList());
userRoleRelationService.updateUserSystemGlobalRole(user, user.getUpdateUser(), userEditRequest.getUserRoleIdList());
return userEditRequest;
}
}

View File

@ -85,7 +85,7 @@ public class SystemParameterControllerTest {
@Test
@Order(3)
public void testGetEmailInfo()throws Exception {
public void testGetEmailInfo() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/system/parameter/get/emailInfo")
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken))
@ -95,7 +95,7 @@ public class SystemParameterControllerTest {
@Test
@Order(4)
public void testEditEmailInfo()throws Exception {
public void testEditEmailInfo() throws Exception {
List<SystemParameter> systemParameters = new ArrayList<>();
SystemParameter systemParameter1 = new SystemParameter();
@ -121,8 +121,8 @@ public class SystemParameterControllerTest {
mockMvc.perform(MockMvcRequestBuilders.post("/system/parameter/edit/emailInfo")
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.content(JSON.toJSONString(systemParameters))
.contentType(MediaType.APPLICATION_JSON))
.content(JSON.toJSONString(systemParameters))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andDo(print());
@ -130,16 +130,16 @@ public class SystemParameterControllerTest {
@Test
@Order(4)
public void testEmailConnec()throws Exception {
public void testEmailConnect() throws Exception {
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("smtp.host","xx");
hashMap.put("smtp.port","xx");
hashMap.put("smtp.account","xx");
hashMap.put("smtp.password","xx");
hashMap.put("smtp.from","xx");
hashMap.put("smtp.recipient","xx");
hashMap.put("smtp.ssl","ture");
hashMap.put("smtp.tls","false");
hashMap.put("smtp.host", "xx");
hashMap.put("smtp.port", "xx");
hashMap.put("smtp.account", "xx");
hashMap.put("smtp.password", "xx");
hashMap.put("smtp.from", "xx");
hashMap.put("smtp.recipient", "xx");
hashMap.put("smtp.ssl", "ture");
hashMap.put("smtp.tls", "false");
mockMvc.perform(MockMvcRequestBuilders.post("/system/parameter/test/email")
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)

View File

@ -0,0 +1,125 @@
package io.metersphere.system.controller;
import com.jayway.jsonpath.JsonPath;
import io.metersphere.sdk.constants.SessionConstants;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.dto.UserInfo;
import io.metersphere.system.dto.UserRoleOption;
import io.metersphere.system.utils.UserTestUtils;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.*;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import java.util.ArrayList;
import java.util.List;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureMockMvc
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@Sql(scripts = {"/dml/init_user_controller_none_permission_test.sql"},
config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED),
executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
public class UserControllerNonePermissionTests {
@Resource
private MockMvc mockMvc;
//涉及到的url
private static final String URL_USER_CREATE = "/system/user/add";
private static final String URL_USER_UPDATE = "/system/user/update";
private static final String URL_USER_GET = "/system/user/get/%s";
private static final String URL_USER_PAGE = "/system/user/page";
private static final String URL_GET_GLOBAL_SYSTEM = "/system/user/get/global/system/role";
protected static String sessionId;
protected static String csrfToken;
private static final String NONE_ROLE_USERNAME = "tianyang.member@163.com";
private static final String NONE_ROLE_PASSWORD = "tianyang.member@163.com";
private static final ResultMatcher CHECK_RESULT_MATHER = status().isForbidden();
/**
* 用户创建接口判断无权限用户是否可以访问
* 接口参数校验优先级大于操作用户权限校验所以参数要保证合法化
*/
@Test
@Order(0)
public void testGetGlobalSystemUserRoleSuccess() throws Exception {
UserInfo paramUserInfo = new UserInfo() {{
setId("testId");
setName("tianyang.no.permission.email");
setEmail("tianyang.no.permission.email@126.com");
setSource("LOCAL");
}};
List<UserRoleOption> paramRoleList = new ArrayList<>() {{
this.add(
new UserRoleOption() {{
this.setId("member");
this.setName("member");
}});
}};
this.requestGet(String.format(URL_USER_GET, NONE_ROLE_USERNAME), CHECK_RESULT_MATHER);
//校验权限系统全局用户组获取
this.requestGet(URL_GET_GLOBAL_SYSTEM, CHECK_RESULT_MATHER);
//校验权限用户创建
this.requestPost(URL_USER_CREATE,
UserTestUtils.getUserCreateDTO(
paramRoleList,
new ArrayList<>() {{
add(paramUserInfo);
}}
),
CHECK_RESULT_MATHER);
//校验权限分页查询用户列表
this.requestPost(URL_USER_PAGE, UserTestUtils.getDefaultPageRequest(), CHECK_RESULT_MATHER);
//校验权限修改用户
this.requestPost(URL_USER_UPDATE,
UserTestUtils.getUserUpdateDTO(paramUserInfo, paramRoleList), CHECK_RESULT_MATHER);
}
@BeforeEach
public void login() throws Exception {
if (StringUtils.isAnyBlank(sessionId, csrfToken)) {
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/login")
.content("{\"username\":\"" + NONE_ROLE_USERNAME + "\",\"password\":\"" + NONE_ROLE_PASSWORD + "\"}")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn();
sessionId = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.sessionId");
csrfToken = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.csrfToken");
}
}
private void requestPost(String url, Object param, ResultMatcher resultMatcher) throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post(url)
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.content(JSON.toJSONString(param))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(resultMatcher).andDo(print())
.andExpect(content().contentType(MediaType.APPLICATION_JSON));
}
private void requestGet(String url, ResultMatcher resultMatcher) throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get(url)
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(resultMatcher).andDo(print())
.andExpect(content().contentType(MediaType.APPLICATION_JSON));
}
}

View File

@ -6,6 +6,7 @@ import io.metersphere.sdk.constants.SessionConstants;
import io.metersphere.sdk.controller.handler.ResultHolder;
import io.metersphere.sdk.dto.BasePageRequest;
import io.metersphere.sdk.dto.UserDTO;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.Pager;
import io.metersphere.system.dto.UserBatchCreateDTO;
@ -21,6 +22,8 @@ import org.junit.jupiter.api.*;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultMatcher;
@ -59,6 +62,7 @@ public class UserControllerTests extends BaseTest {
//默认数据
public static final String USER_DEFAULT_NAME = "tianyang.no.1";
public static final String USER_DEFAULT_EMAIL = "tianyang.no.1@126.com";
public static final String USER_NONE_ROLE_EMAIL = "tianyang.none.role@163.com";
//记录查询到的组织信息
private void setDefaultUserRoleList(MvcResult mvcResult) throws Exception {
@ -298,6 +302,9 @@ public class UserControllerTests extends BaseTest {
@Test
@Order(2)
@Sql(scripts = {"/dml/init_user_controller_test.sql"},
config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED),
executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
public void testGetByEmailSuccess() throws Exception {
this.checkUserList();
UserDTO userDTO = this.getUserByEmail(USER_DEFAULT_EMAIL);
@ -306,6 +313,14 @@ public class UserControllerTests extends BaseTest {
//返回邮箱等于参数邮箱且用户名合法
Assertions.assertEquals(userDTO.getEmail(), USER_DEFAULT_EMAIL);
Assertions.assertNotNull(userDTO.getName());
//查询脏数据没有关联任何组织的用户也应该正常查询出来
userDTO = this.getUserByEmail(USER_NONE_ROLE_EMAIL);
//返回值不为空
Assertions.assertNotNull(userDTO);
//返回邮箱等于参数邮箱且用户名合法
Assertions.assertEquals(userDTO.getEmail(), USER_NONE_ROLE_EMAIL);
Assertions.assertNotNull(userDTO.getName());
}
private UserDTO getUserByEmail(String email) throws Exception {
@ -386,10 +401,11 @@ public class UserControllerTests extends BaseTest {
}
@Test
@Order(3)
@Order(4)
public void testUserUpdateSuccess() throws Exception {
this.checkUserList();
UserInfo user = USER_LIST.get(0);
UserInfo user = new UserInfo();
BeanUtils.copyBean(user, USER_LIST.get(0));
UserEditRequest userMaintainRequest;
UserEditRequest response;
UserDTO checkDTO;
@ -419,11 +435,57 @@ public class UserControllerTests extends BaseTest {
checkDTO = this.getUserByEmail(user.getEmail());
UserTestUtils.compareUserDTO(response, checkDTO);
//更改用户组(把上面的情况添加别的权限)
userMaintainRequest = UserTestUtils.getUserUpdateDTO(user,
defaultUserRoleList
);
userMaintainRequest = UserTestUtils.getUserUpdateDTO(user, defaultUserRoleList);
response = UserTestUtils.parseObjectFromMvcResult(this.responsePost(URL_USER_UPDATE, userMaintainRequest), UserEditRequest.class);
checkDTO = this.getUserByEmail(user.getEmail());
UserTestUtils.compareUserDTO(response, checkDTO);
//用户信息复原
user = new UserInfo();
BeanUtils.copyBean(user, USER_LIST.get(0));
userMaintainRequest = UserTestUtils.getUserUpdateDTO(user, defaultUserRoleList);
response = UserTestUtils.parseObjectFromMvcResult(this.responsePost(URL_USER_UPDATE, userMaintainRequest), UserEditRequest.class);
checkDTO = this.getUserByEmail(user.getEmail());
UserTestUtils.compareUserDTO(response, checkDTO);
}
@Test
@Order(5)
public void testUserUpdateError() throws Exception {
// 4xx 验证
UserInfo user = new UserInfo();
UserEditRequest userMaintainRequest;
//更改名字
BeanUtils.copyBean(user, USER_LIST.get(0));
user.setName("");
userMaintainRequest = UserTestUtils.getUserUpdateDTO(user, defaultUserRoleList);
this.requestPost(URL_USER_UPDATE, userMaintainRequest, BAD_REQUEST_MATCHER);
//email为空
BeanUtils.copyBean(user, USER_LIST.get(0));
user.setEmail("");
userMaintainRequest = UserTestUtils.getUserUpdateDTO(user, defaultUserRoleList);
this.requestPost(URL_USER_UPDATE, userMaintainRequest, BAD_REQUEST_MATCHER);
//手机号为空
BeanUtils.copyBean(user, USER_LIST.get(0));
user.setEmail("");
userMaintainRequest = UserTestUtils.getUserUpdateDTO(user, defaultUserRoleList);
this.requestPost(URL_USER_UPDATE, userMaintainRequest, BAD_REQUEST_MATCHER);
//用户组为空
BeanUtils.copyBean(user, USER_LIST.get(0));
userMaintainRequest = UserTestUtils.getUserUpdateDTO(user, new ArrayList<>());
userMaintainRequest.setUserRoleList(new ArrayList<>());
this.requestPost(URL_USER_UPDATE, userMaintainRequest, BAD_REQUEST_MATCHER);
// 500验证
//邮箱重复
BeanUtils.copyBean(user, USER_LIST.get(0));
user.setEmail(USER_LIST.get(USER_LIST.size() - 1).getEmail());
userMaintainRequest = UserTestUtils.getUserUpdateDTO(user, defaultUserRoleList);
this.requestPost(URL_USER_UPDATE, userMaintainRequest, ERROR_REQUEST_MATCHER);
//用户组不包含系统成员
BeanUtils.copyBean(user, USER_LIST.get(0));
userMaintainRequest = UserTestUtils.getUserUpdateDTO(user,
defaultUserRoleList.stream().filter(item -> !StringUtils.equals(item.getId(), "member")).toList()
);
this.requestPost(URL_USER_UPDATE, userMaintainRequest, ERROR_REQUEST_MATCHER);
}
}

View File

@ -48,6 +48,9 @@ public class UserTestUtils {
public static UserEditRequest getUserUpdateDTO(UserInfo user, List<UserRoleOption> userRoleList) {
UserEditRequest returnDTO = new UserEditRequest();
if (user.getPhone() == null) {
user.setPhone("");
}
BeanUtils.copyBean(returnDTO, user);
if (CollectionUtils.isNotEmpty(userRoleList)) {
returnDTO.setUserRoleIdList(

View File

@ -0,0 +1,4 @@
-- 初始化一个没有任何权限的用户
insert into user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source, last_project_id, create_user, update_user)
VALUES ('tianyang.member.id', 'tianyang.member', 'tianyang.member@163.com', MD5('tianyang.member@163.com'), UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin');
INSERT INTO user_role_relation (id, user_id, role_id, source_id, create_time, create_user) VALUES (uuid(), 'tianyang.member.id', 'member', 'system', 1684747668375, 'admin');

View File

@ -0,0 +1,3 @@
-- 初始化一个没有任何权限的用户
insert into user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source, last_project_id, create_user, update_user)
VALUES (uuid(), 'tianyang.none.role', 'tianyang.none.role@163.com', MD5('tianyang.none.role'), UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin');