fix(系统设置): 用户管理页面,禁用和删除用户时如果相关用户正在登录中,则同步踢出
--bug=1034777 --user=宋天阳 [系统设置]操作-如果用户登录系统中,删除和禁用该用户,不会立即生效。 https://www.tapd.cn/55049933/s/1456050
This commit is contained in:
parent
bad97e06e4
commit
400c127061
|
@ -31,6 +31,7 @@ import io.metersphere.system.log.service.OperationLogService;
|
||||||
import io.metersphere.system.mapper.*;
|
import io.metersphere.system.mapper.*;
|
||||||
import io.metersphere.system.notice.sender.impl.MailNoticeSender;
|
import io.metersphere.system.notice.sender.impl.MailNoticeSender;
|
||||||
import io.metersphere.system.uid.IDGenerator;
|
import io.metersphere.system.uid.IDGenerator;
|
||||||
|
import io.metersphere.system.utils.SessionUtils;
|
||||||
import io.metersphere.system.utils.UserImportEventListener;
|
import io.metersphere.system.utils.UserImportEventListener;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.mail.internet.InternetAddress;
|
import jakarta.mail.internet.InternetAddress;
|
||||||
|
@ -40,6 +41,7 @@ import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotEmpty;
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.ibatis.session.ExecutorType;
|
import org.apache.ibatis.session.ExecutorType;
|
||||||
import org.apache.ibatis.session.SqlSession;
|
import org.apache.ibatis.session.SqlSession;
|
||||||
|
@ -227,11 +229,18 @@ public class UserService {
|
||||||
userExample.createCriteria().andIdIn(
|
userExample.createCriteria().andIdIn(
|
||||||
request.getSelectIds()
|
request.getSelectIds()
|
||||||
);
|
);
|
||||||
|
|
||||||
User updateUser = new User();
|
User updateUser = new User();
|
||||||
updateUser.setEnable(request.isEnable());
|
updateUser.setEnable(request.isEnable());
|
||||||
updateUser.setUpdateUser(operatorId);
|
updateUser.setUpdateUser(operatorId);
|
||||||
updateUser.setUpdateTime(System.currentTimeMillis());
|
updateUser.setUpdateTime(System.currentTimeMillis());
|
||||||
response.setSuccessCount(userMapper.updateByExampleSelective(updateUser, userExample));
|
response.setSuccessCount(userMapper.updateByExampleSelective(updateUser, userExample));
|
||||||
|
|
||||||
|
if (BooleanUtils.isFalse(request.isEnable())) {
|
||||||
|
//如果是禁用,批量踢出用户
|
||||||
|
request.getSelectIds().forEach(SessionUtils::kickOutUser);
|
||||||
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,6 +325,8 @@ public class UserService {
|
||||||
response.setSuccessCount(this.deleteUserByList(userIdList, operatorId));
|
response.setSuccessCount(this.deleteUserByList(userIdList, operatorId));
|
||||||
//删除用户角色关系
|
//删除用户角色关系
|
||||||
userRoleRelationService.deleteByUserIdList(userIdList);
|
userRoleRelationService.deleteByUserIdList(userIdList);
|
||||||
|
//批量踢出用户
|
||||||
|
userIdList.forEach(SessionUtils::kickOutUser);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package io.metersphere.system.controller.user;
|
package io.metersphere.system.controller.user;
|
||||||
|
|
||||||
|
import com.jayway.jsonpath.JsonPath;
|
||||||
import io.metersphere.project.domain.Project;
|
import io.metersphere.project.domain.Project;
|
||||||
import io.metersphere.project.mapper.ProjectMapper;
|
import io.metersphere.project.mapper.ProjectMapper;
|
||||||
|
import io.metersphere.sdk.constants.SessionConstants;
|
||||||
import io.metersphere.sdk.util.BeanUtils;
|
import io.metersphere.sdk.util.BeanUtils;
|
||||||
import io.metersphere.sdk.util.CodingUtils;
|
import io.metersphere.sdk.util.CodingUtils;
|
||||||
import io.metersphere.sdk.util.JSON;
|
import io.metersphere.sdk.util.JSON;
|
||||||
|
@ -46,6 +48,7 @@ import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.http.HttpHeaders;
|
||||||
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.api.*;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
@ -55,11 +58,14 @@ import org.springframework.test.context.jdbc.Sql;
|
||||||
import org.springframework.test.context.jdbc.SqlConfig;
|
import org.springframework.test.context.jdbc.SqlConfig;
|
||||||
import org.springframework.test.web.servlet.MvcResult;
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
import org.springframework.test.web.servlet.ResultMatcher;
|
import org.springframework.test.web.servlet.ResultMatcher;
|
||||||
|
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
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.status;
|
||||||
|
|
||||||
|
|
||||||
|
@ -439,8 +445,29 @@ public class UserControllerTests extends BaseTest {
|
||||||
@Order(6)
|
@Order(6)
|
||||||
public void testUserChangeEnableSuccess() throws Exception {
|
public void testUserChangeEnableSuccess() throws Exception {
|
||||||
this.checkUserList();
|
this.checkUserList();
|
||||||
//修改状态关闭
|
|
||||||
UserCreateInfo userInfo = USER_LIST.get(0);
|
UserCreateInfo userInfo = USER_LIST.get(0);
|
||||||
|
|
||||||
|
//先使用要操作的用户登录,用于检查会不会把账户踢出
|
||||||
|
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/login")
|
||||||
|
.content(String.format("{\"username\":\"%s\",\"password\":\"%s\"}", userInfo.getEmail(), userInfo.getEmail()))
|
||||||
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andReturn();
|
||||||
|
String sessionId = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.sessionId");
|
||||||
|
String csrfToken = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.csrfToken");
|
||||||
|
//检查该用户状态登录中
|
||||||
|
MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get("/is-login");
|
||||||
|
requestBuilder
|
||||||
|
.header(SessionConstants.HEADER_TOKEN, sessionId)
|
||||||
|
.header(SessionConstants.CSRF_TOKEN, csrfToken)
|
||||||
|
.header(HttpHeaders.ACCEPT_LANGUAGE, "zh-CN");
|
||||||
|
MvcResult loginResult = mockMvc.perform(requestBuilder).andReturn();
|
||||||
|
ResultHolder checkLoginHolder = JSON.parseObject(loginResult.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class);
|
||||||
|
Assertions.assertNotNull(checkLoginHolder.getData());
|
||||||
|
|
||||||
|
//修改状态关闭
|
||||||
UserChangeEnableRequest userChangeEnableRequest = new UserChangeEnableRequest();
|
UserChangeEnableRequest userChangeEnableRequest = new UserChangeEnableRequest();
|
||||||
userChangeEnableRequest.setSelectIds(new ArrayList<>() {{
|
userChangeEnableRequest.setSelectIds(new ArrayList<>() {{
|
||||||
this.add(userInfo.getId());
|
this.add(userInfo.getId());
|
||||||
|
@ -452,10 +479,19 @@ public class UserControllerTests extends BaseTest {
|
||||||
new CheckLogModel(item, OperationLogType.UPDATE, UserRequestUtils.URL_USER_UPDATE_ENABLE)
|
new CheckLogModel(item, OperationLogType.UPDATE, UserRequestUtils.URL_USER_UPDATE_ENABLE)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
UserDTO userDTO = this.getUserByEmail(userInfo.getEmail());
|
UserDTO userDTO = this.getUserByEmail(userInfo.getEmail());
|
||||||
Assertions.assertEquals(userDTO.getEnable(), userChangeEnableRequest.isEnable());
|
Assertions.assertEquals(userDTO.getEnable(), userChangeEnableRequest.isEnable());
|
||||||
|
|
||||||
|
//检查该用户被踢出
|
||||||
|
requestBuilder = MockMvcRequestBuilders.get("/is-login");
|
||||||
|
requestBuilder
|
||||||
|
.header(SessionConstants.HEADER_TOKEN, sessionId)
|
||||||
|
.header(SessionConstants.CSRF_TOKEN, csrfToken)
|
||||||
|
.header(HttpHeaders.ACCEPT_LANGUAGE, "zh-CN");
|
||||||
|
loginResult = mockMvc.perform(requestBuilder).andReturn();
|
||||||
|
checkLoginHolder = JSON.parseObject(loginResult.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class);
|
||||||
|
Assertions.assertNull(checkLoginHolder.getData());
|
||||||
|
|
||||||
//修改状态开启
|
//修改状态开启
|
||||||
userChangeEnableRequest.setEnable(true);
|
userChangeEnableRequest.setEnable(true);
|
||||||
this.requestPost(UserRequestUtils.URL_USER_UPDATE_ENABLE, userChangeEnableRequest, status().isOk());
|
this.requestPost(UserRequestUtils.URL_USER_UPDATE_ENABLE, userChangeEnableRequest, status().isOk());
|
||||||
|
@ -1064,6 +1100,27 @@ public class UserControllerTests extends BaseTest {
|
||||||
@Order(99)
|
@Order(99)
|
||||||
public void testUserDeleteSuccess() throws Exception {
|
public void testUserDeleteSuccess() throws Exception {
|
||||||
this.checkUserList();
|
this.checkUserList();
|
||||||
|
|
||||||
|
//先使用要操作的用户登录,用于检查会不会把账户踢出
|
||||||
|
UserCreateInfo userInfo = USER_LIST.get(0);
|
||||||
|
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/login")
|
||||||
|
.content(String.format("{\"username\":\"%s\",\"password\":\"%s\"}", userInfo.getEmail(), userInfo.getEmail()))
|
||||||
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andReturn();
|
||||||
|
String sessionId = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.sessionId");
|
||||||
|
String csrfToken = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.csrfToken");
|
||||||
|
//检查该用户状态登录中
|
||||||
|
MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get("/is-login");
|
||||||
|
requestBuilder
|
||||||
|
.header(SessionConstants.HEADER_TOKEN, sessionId)
|
||||||
|
.header(SessionConstants.CSRF_TOKEN, csrfToken)
|
||||||
|
.header(HttpHeaders.ACCEPT_LANGUAGE, "zh-CN");
|
||||||
|
MvcResult loginResult = mockMvc.perform(requestBuilder).andReturn();
|
||||||
|
ResultHolder checkLoginHolder = JSON.parseObject(loginResult.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class);
|
||||||
|
Assertions.assertNotNull(checkLoginHolder.getData());
|
||||||
|
|
||||||
//删除USER_LIST用户
|
//删除USER_LIST用户
|
||||||
TableBatchProcessDTO request = new TableBatchProcessDTO();
|
TableBatchProcessDTO request = new TableBatchProcessDTO();
|
||||||
request.setSelectIds(USER_LIST.stream().map(UserCreateInfo::getId).toList());
|
request.setSelectIds(USER_LIST.stream().map(UserCreateInfo::getId).toList());
|
||||||
|
@ -1071,6 +1128,17 @@ public class UserControllerTests extends BaseTest {
|
||||||
userRequestUtils.responsePost(UserRequestUtils.URL_USER_DELETE, request), TableBatchProcessResponse.class);
|
userRequestUtils.responsePost(UserRequestUtils.URL_USER_DELETE, request), TableBatchProcessResponse.class);
|
||||||
Assertions.assertEquals(request.getSelectIds().size(), response.getTotalCount());
|
Assertions.assertEquals(request.getSelectIds().size(), response.getTotalCount());
|
||||||
Assertions.assertEquals(request.getSelectIds().size(), response.getSuccessCount());
|
Assertions.assertEquals(request.getSelectIds().size(), response.getSuccessCount());
|
||||||
|
|
||||||
|
//检查该用户被踢出
|
||||||
|
requestBuilder = MockMvcRequestBuilders.get("/is-login");
|
||||||
|
requestBuilder
|
||||||
|
.header(SessionConstants.HEADER_TOKEN, sessionId)
|
||||||
|
.header(SessionConstants.CSRF_TOKEN, csrfToken)
|
||||||
|
.header(HttpHeaders.ACCEPT_LANGUAGE, "zh-CN");
|
||||||
|
loginResult = mockMvc.perform(requestBuilder).andReturn();
|
||||||
|
checkLoginHolder = JSON.parseObject(loginResult.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class);
|
||||||
|
Assertions.assertNull(checkLoginHolder.getData());
|
||||||
|
|
||||||
//检查数据库
|
//检查数据库
|
||||||
List<UserCreateInfo> removeList = new ArrayList<>();
|
List<UserCreateInfo> removeList = new ArrayList<>();
|
||||||
for (UserCreateInfo deleteUser : USER_LIST) {
|
for (UserCreateInfo deleteUser : USER_LIST) {
|
||||||
|
|
Loading…
Reference in New Issue