修复系统管理后台权限配置校验
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package cn.nianxx.thhotel.platform.access.service.impl;
|
||||
|
||||
import cn.nianxx.thhotel.platform.access.common.enums.PlatformPermissionStatus;
|
||||
import cn.nianxx.thhotel.platform.access.common.enums.PlatformRoleStatus;
|
||||
import cn.nianxx.thhotel.platform.access.common.request.AdminRoleCreateRequest;
|
||||
import cn.nianxx.thhotel.platform.access.common.request.AdminRolePermissionAssignmentRequest;
|
||||
@@ -315,12 +316,13 @@ public class AdminAccessManagementServiceImpl implements AdminAccessManagementSe
|
||||
if (permissionIds == null || permissionIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Set<Long> existingPermissionIds = accessRepository.listAllPermissions().stream()
|
||||
Set<Long> activePermissionIds = accessRepository.listAllPermissions().stream()
|
||||
.filter(permission -> PlatformPermissionStatus.ACTIVE.name().equals(permission.getPermissionStatus()))
|
||||
.map(PlatformPermissionEntity::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
if (!existingPermissionIds.containsAll(permissionIds)) {
|
||||
throw invalidRequest("存在不存在的权限 ID。");
|
||||
if (!activePermissionIds.containsAll(permissionIds)) {
|
||||
throw invalidRequest("存在不存在或未启用的权限 ID。");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.nianxx.thhotel.platform.identity.service.impl;
|
||||
|
||||
import cn.nianxx.thhotel.platform.access.common.enums.PlatformRoleStatus;
|
||||
import cn.nianxx.thhotel.platform.access.domain.PlatformRoleEntity;
|
||||
import cn.nianxx.thhotel.platform.access.domain.PlatformUserRoleEntity;
|
||||
import cn.nianxx.thhotel.platform.access.repository.PlatformAccessRepository;
|
||||
@@ -479,11 +480,12 @@ public class AdminUserManagementServiceImpl implements AdminUserManagementServic
|
||||
if (roleIds == null || roleIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Set<Long> existingRoleIds = accessRepository.listRolesByIds(roleIds).stream()
|
||||
Set<Long> activeRoleIds = accessRepository.listRolesByIds(roleIds).stream()
|
||||
.filter(role -> PlatformRoleStatus.ACTIVE.name().equals(role.getRoleStatus()))
|
||||
.map(PlatformRoleEntity::getId)
|
||||
.collect(Collectors.toSet());
|
||||
if (!existingRoleIds.containsAll(roleIds)) {
|
||||
throw invalidRequest("存在不存在的角色 ID。");
|
||||
if (!activeRoleIds.containsAll(roleIds)) {
|
||||
throw invalidRequest("存在不存在或未启用的角色 ID。");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.nianxx.thhotel.platform.navigation.service.impl;
|
||||
|
||||
import cn.nianxx.thhotel.platform.access.common.enums.PlatformPermissionStatus;
|
||||
import cn.nianxx.thhotel.platform.access.repository.PlatformAccessRepository;
|
||||
import cn.nianxx.thhotel.platform.audit.common.dto.PlatformAdminAuditLogDraft;
|
||||
import cn.nianxx.thhotel.platform.audit.service.PlatformAdminAuditLogService;
|
||||
@@ -44,7 +45,8 @@ public class AdminMenuManagementServiceImpl implements AdminMenuManagementServic
|
||||
"/system/users",
|
||||
"/system/roles",
|
||||
"/system/menus",
|
||||
"/system/hotels");
|
||||
"/system/hotels",
|
||||
"/system/audits");
|
||||
|
||||
private final PlatformNavigationRepository navigationRepository;
|
||||
private final PlatformAccessRepository accessRepository;
|
||||
@@ -231,8 +233,10 @@ public class AdminMenuManagementServiceImpl implements AdminMenuManagementServic
|
||||
menu.setIconKey(trimToNull(iconKey));
|
||||
String normalizedPermissionCode = trimToNull(permissionCode);
|
||||
if (normalizedPermissionCode != null
|
||||
&& accessRepository.findPermissionByCode(normalizedPermissionCode).isEmpty()) {
|
||||
throw invalidRequest("菜单绑定的权限码不存在。");
|
||||
&& accessRepository.findPermissionByCode(normalizedPermissionCode)
|
||||
.filter(permission -> PlatformPermissionStatus.ACTIVE.name().equals(permission.getPermissionStatus()))
|
||||
.isEmpty()) {
|
||||
throw invalidRequest("菜单绑定的权限码不存在或未启用。");
|
||||
}
|
||||
menu.setPermissionCode(normalizedPermissionCode);
|
||||
menu.setSortOrder(sortOrder == null ? 0 : sortOrder);
|
||||
|
||||
@@ -9,7 +9,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import cn.nianxx.thhotel.ThHotelApplication;
|
||||
import cn.nianxx.thhotel.platform.access.common.enums.PlatformPermissionStatus;
|
||||
import cn.nianxx.thhotel.platform.access.common.enums.PlatformRoleCode;
|
||||
import cn.nianxx.thhotel.platform.access.common.enums.PlatformRoleStatus;
|
||||
import cn.nianxx.thhotel.platform.access.domain.PlatformPermissionEntity;
|
||||
import cn.nianxx.thhotel.platform.access.domain.PlatformRoleEntity;
|
||||
import cn.nianxx.thhotel.platform.access.repository.PlatformAccessRepository;
|
||||
@@ -264,6 +266,58 @@ class AdminReadonlyControllerTest {
|
||||
.andExpect(status().isUnauthorized());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectDisabledRoleAssignmentToUser() throws Exception {
|
||||
String token = tokenFrom(login("m006-admin", "Admin@123456"));
|
||||
PlatformRoleEntity viewerRole = accessRepository.findRoleByCode(PlatformRoleCode.RESERVATION_VIEWER.name())
|
||||
.orElseThrow();
|
||||
String username = "m006-role-user-" + System.nanoTime();
|
||||
MvcResult createUserResult = mockMvc.perform(post("/api/admin/users")
|
||||
.header("Authorization", "Bearer " + token)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"username": "%s",
|
||||
"initial_password": "User@123456",
|
||||
"display_name": "角色校验用户",
|
||||
"user_status": "ACTIVE",
|
||||
"role_ids": ["%s"],
|
||||
"hotel_ids": ["HOTEL-TEST"],
|
||||
"default_hotel_id": "HOTEL-TEST"
|
||||
}
|
||||
""".formatted(username, viewerRole.getId())))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn();
|
||||
String userId = objectMapper.readTree(createUserResult.getResponse().getContentAsString()).path("id").asText();
|
||||
|
||||
MvcResult disabledRoleResult = mockMvc.perform(post("/api/admin/roles")
|
||||
.header("Authorization", "Bearer " + token)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"role_code": "%s",
|
||||
"role_name": "M006 停用角色",
|
||||
"role_status": "DISABLED"
|
||||
}
|
||||
""".formatted("M006_DISABLED_ROLE_" + System.nanoTime())))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.role_status").value(PlatformRoleStatus.DISABLED.name()))
|
||||
.andReturn();
|
||||
String disabledRoleId = objectMapper.readTree(disabledRoleResult.getResponse().getContentAsString())
|
||||
.path("id").asText();
|
||||
|
||||
mockMvc.perform(put("/api/admin/users/{userId}/roles", userId)
|
||||
.header("Authorization", "Bearer " + token)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"role_ids": ["%s"]
|
||||
}
|
||||
""".formatted(disabledRoleId)))
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.error_code").value("ADMIN_INVALID_REQUEST"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldManageCustomRoleAndRejectBuiltinRoleMutation() throws Exception {
|
||||
String token = tokenFrom(login("m006-admin", "Admin@123456"));
|
||||
@@ -297,6 +351,18 @@ class AdminReadonlyControllerTest {
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.permissions[0].permission_code").value("SYSTEM_USER_MANAGE"));
|
||||
|
||||
PlatformPermissionEntity disabledPermission = createDisabledPermission("M006_DISABLED_PERMISSION_");
|
||||
mockMvc.perform(put("/api/admin/roles/{roleId}/permissions", roleId)
|
||||
.header("Authorization", "Bearer " + token)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"permission_ids": ["%s"]
|
||||
}
|
||||
""".formatted(disabledPermission.getId())))
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.error_code").value("ADMIN_INVALID_REQUEST"));
|
||||
|
||||
PlatformRoleEntity builtinRole = accessRepository.findRoleByCode(PlatformRoleCode.SYSTEM_ADMIN.name())
|
||||
.orElseThrow();
|
||||
mockMvc.perform(put("/api/admin/roles/{roleId}", builtinRole.getId().toString())
|
||||
@@ -344,7 +410,7 @@ class AdminReadonlyControllerTest {
|
||||
{
|
||||
"menu_name": "未来菜单更新",
|
||||
"menu_type": "PAGE",
|
||||
"route_path": "/system/users",
|
||||
"route_path": "/system/audits",
|
||||
"permission_code": "SYSTEM_USER_MANAGE",
|
||||
"visible": true,
|
||||
"menu_status": "ACTIVE"
|
||||
@@ -353,6 +419,25 @@ class AdminReadonlyControllerTest {
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.menu_code").value(menuCode))
|
||||
.andExpect(jsonPath("$.known_route").value(true));
|
||||
|
||||
PlatformPermissionEntity disabledPermission = createDisabledPermission("M006_MENU_DISABLED_PERMISSION_");
|
||||
mockMvc.perform(post("/api/admin/menus")
|
||||
.header("Authorization", "Bearer " + token)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"menu_code": "%s",
|
||||
"menu_name": "停用权限菜单",
|
||||
"menu_type": "PAGE",
|
||||
"route_path": "/system/users",
|
||||
"permission_code": "%s",
|
||||
"visible": true,
|
||||
"menu_status": "ACTIVE"
|
||||
}
|
||||
""".formatted("M006_MENU_DISABLED_" + System.nanoTime(),
|
||||
disabledPermission.getPermissionCode())))
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.error_code").value("ADMIN_INVALID_REQUEST"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -415,4 +500,18 @@ class AdminReadonlyControllerTest {
|
||||
JsonNode json = objectMapper.readTree(result.getResponse().getContentAsString());
|
||||
return json.path("access_token").asText();
|
||||
}
|
||||
|
||||
private PlatformPermissionEntity createDisabledPermission(String codePrefix) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
PlatformPermissionEntity permission = new PlatformPermissionEntity();
|
||||
permission.setPermissionCode(codePrefix + System.nanoTime());
|
||||
permission.setPermissionName("M006 停用权限");
|
||||
permission.setPermissionGroup("SYSTEM");
|
||||
permission.setPermissionStatus(PlatformPermissionStatus.DISABLED.name());
|
||||
permission.setSystemBuiltin(false);
|
||||
permission.setCreatedAt(now);
|
||||
permission.setUpdatedAt(now);
|
||||
accessRepository.insertPermission(permission);
|
||||
return permission;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user