From 400c1270614f8463d2e6bd160712249bf5bbff76 Mon Sep 17 00:00:00 2001 From: song-tianyang Date: Tue, 30 Jan 2024 15:03:21 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E7=B3=BB=E7=BB=9F=E8=AE=BE=E7=BD=AE):=20?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86=E9=A1=B5=E9=9D=A2=EF=BC=8C?= =?UTF-8?q?=E7=A6=81=E7=94=A8=E5=92=8C=E5=88=A0=E9=99=A4=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=97=B6=E5=A6=82=E6=9E=9C=E7=9B=B8=E5=85=B3=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=AD=A3=E5=9C=A8=E7=99=BB=E5=BD=95=E4=B8=AD=EF=BC=8C=E5=88=99?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E8=B8=A2=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --bug=1034777 --user=宋天阳 [系统设置]操作-如果用户登录系统中,删除和禁用该用户,不会立即生效。 https://www.tapd.cn/55049933/s/1456050 --- .../system/service/UserService.java | 11 +++ .../controller/user/UserControllerTests.java | 72 ++++++++++++++++++- 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/UserService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/UserService.java index afcbbf520b..906d36fb6b 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/service/UserService.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/UserService.java @@ -31,6 +31,7 @@ import io.metersphere.system.log.service.OperationLogService; import io.metersphere.system.mapper.*; import io.metersphere.system.notice.sender.impl.MailNoticeSender; import io.metersphere.system.uid.IDGenerator; +import io.metersphere.system.utils.SessionUtils; import io.metersphere.system.utils.UserImportEventListener; import jakarta.annotation.Resource; import jakarta.mail.internet.InternetAddress; @@ -40,6 +41,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.SqlSession; @@ -227,11 +229,18 @@ public class UserService { userExample.createCriteria().andIdIn( request.getSelectIds() ); + User updateUser = new User(); updateUser.setEnable(request.isEnable()); updateUser.setUpdateUser(operatorId); updateUser.setUpdateTime(System.currentTimeMillis()); response.setSuccessCount(userMapper.updateByExampleSelective(updateUser, userExample)); + + if (BooleanUtils.isFalse(request.isEnable())) { + //如果是禁用,批量踢出用户 + request.getSelectIds().forEach(SessionUtils::kickOutUser); + } + return response; } @@ -316,6 +325,8 @@ public class UserService { response.setSuccessCount(this.deleteUserByList(userIdList, operatorId)); //删除用户角色关系 userRoleRelationService.deleteByUserIdList(userIdList); + //批量踢出用户 + userIdList.forEach(SessionUtils::kickOutUser); return response; } diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/user/UserControllerTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/user/UserControllerTests.java index eebdefbf20..f6049f4d74 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/user/UserControllerTests.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/user/UserControllerTests.java @@ -1,7 +1,9 @@ package io.metersphere.system.controller.user; +import com.jayway.jsonpath.JsonPath; import io.metersphere.project.domain.Project; import io.metersphere.project.mapper.ProjectMapper; +import io.metersphere.sdk.constants.SessionConstants; import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.CodingUtils; import io.metersphere.sdk.util.JSON; @@ -46,6 +48,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpHeaders; import org.junit.jupiter.api.*; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; 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.web.servlet.MvcResult; 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.util.*; 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; @@ -439,8 +445,29 @@ public class UserControllerTests extends BaseTest { @Order(6) public void testUserChangeEnableSuccess() throws Exception { 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()); + + //修改状态关闭 UserChangeEnableRequest userChangeEnableRequest = new UserChangeEnableRequest(); userChangeEnableRequest.setSelectIds(new ArrayList<>() {{ this.add(userInfo.getId()); @@ -452,10 +479,19 @@ public class UserControllerTests extends BaseTest { new CheckLogModel(item, OperationLogType.UPDATE, UserRequestUtils.URL_USER_UPDATE_ENABLE) ); } - UserDTO userDTO = this.getUserByEmail(userInfo.getEmail()); 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); this.requestPost(UserRequestUtils.URL_USER_UPDATE_ENABLE, userChangeEnableRequest, status().isOk()); @@ -1064,6 +1100,27 @@ public class UserControllerTests extends BaseTest { @Order(99) public void testUserDeleteSuccess() throws Exception { 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用户 TableBatchProcessDTO request = new TableBatchProcessDTO(); 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); Assertions.assertEquals(request.getSelectIds().size(), response.getTotalCount()); 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 removeList = new ArrayList<>(); for (UserCreateInfo deleteUser : USER_LIST) {