维护权限:注册教师与学员安全删除按钮权限
This commit is contained in:
1 parent
225f58481a
commit
18c5ff5914
3 files changed
+142
No files matched your search
+55
@@ -132,6 +132,61 @@ public class RbacPermissionMigrationContractTest
|
||||
"select 5, 2240");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void teacherAndStudentSafeDeletePermissionsRegisteredInSqlAndContractProtected() throws Exception
|
||||
{
|
||||
// 1. 验证权威初始化 SQL (005) 包含教师与学员安全删除按钮权限注册
|
||||
String sql005 = new String(Files.readAllBytes(findMigration("005_training_roles_permissions.sql")), StandardCharsets.UTF_8).toLowerCase();
|
||||
assertContains(sql005,
|
||||
"train:teacher:remove",
|
||||
"train:student:remove",
|
||||
"2245",
|
||||
"2246",
|
||||
"教师删除",
|
||||
"学员删除");
|
||||
|
||||
// 2. 验证增量 V2 migration (011) 包含幂等安全删除注册
|
||||
Path incrementalMigrationPath = findMigration("011_teacher_student_remove_permissions.sql");
|
||||
String sql011 = new String(Files.readAllBytes(incrementalMigrationPath), StandardCharsets.UTF_8).toLowerCase();
|
||||
assertContains(sql011,
|
||||
"train:teacher:remove",
|
||||
"train:student:remove",
|
||||
"2245",
|
||||
"2246",
|
||||
"where not exists",
|
||||
"train_admin");
|
||||
|
||||
// 3. 严格断言并未向 train_admin 授予教师/学员删除权限
|
||||
assertFalse("train_admin 绝不能被授予教师删除权限", sql005.contains("select 3, 2245"));
|
||||
assertFalse("train_admin 绝不能被授予学员删除权限", sql005.contains("select 3, 2246"));
|
||||
assertFalse("011迁移绝不能向sys_role_menu赋予train_admin删除权限", sql011.contains("insert into public.sys_role_menu (role_id, menu_id) values (3"));
|
||||
|
||||
// 4. 验证后端 Controller 注解与权限树完全对齐
|
||||
boolean teacherRemoveFound = false;
|
||||
for (Method method : TrainTeacherController.class.getDeclaredMethods())
|
||||
{
|
||||
if (method.isAnnotationPresent(PreAuthorize.class)
|
||||
&& method.getAnnotation(PreAuthorize.class).value().contains("train:teacher:remove"))
|
||||
{
|
||||
teacherRemoveFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertTrue("TrainTeacherController 必须配置 train:teacher:remove", teacherRemoveFound);
|
||||
|
||||
boolean studentRemoveFound = false;
|
||||
for (Method method : TrainStudentController.class.getDeclaredMethods())
|
||||
{
|
||||
if (method.isAnnotationPresent(PreAuthorize.class)
|
||||
&& method.getAnnotation(PreAuthorize.class).value().contains("train:student:remove"))
|
||||
{
|
||||
studentRemoveFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertTrue("TrainStudentController 必须配置 train:student:remove", studentRemoveFound);
|
||||
}
|
||||
|
||||
private Path findMigration(String filename)
|
||||
{
|
||||
for (Path path = Paths.get("").toAbsolutePath(); path != null; path = path.getParent())
|
||||
|
||||
@@ -112,6 +112,10 @@ INSERT INTO public.sys_menu (menu_id, menu_name, parent_id, order_num, path, com
|
||||
SELECT 2242, '教师账号解绑', 2155, 6, '#', '', '', 1, 0, 'F', '0', '0', 'train:teacher:unbindUser', '#', 'admin', CURRENT_TIMESTAMP, '教师系统账号解绑'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM public.sys_menu WHERE menu_id = 2242 OR perms = 'train:teacher:unbindUser');
|
||||
|
||||
INSERT INTO public.sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||||
SELECT 2245, '教师删除', 2155, 7, '#', '', '', 1, 0, 'F', '0', '0', 'train:teacher:remove', '#', 'admin', CURRENT_TIMESTAMP, '教师档案安全删除'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM public.sys_menu WHERE menu_id = 2245 OR perms = 'train:teacher:remove');
|
||||
|
||||
-- 3.2 学员管理 (parent: 2156)
|
||||
INSERT INTO public.sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||||
SELECT 2205, '学员查询', 2156, 1, '#', '', '', 1, 0, 'F', '0', '0', 'train:student:list', '#', 'admin', CURRENT_TIMESTAMP, '学员列表查询'
|
||||
@@ -133,6 +137,10 @@ INSERT INTO public.sys_menu (menu_id, menu_name, parent_id, order_num, path, com
|
||||
SELECT 2244, '学员账号解绑', 2156, 5, '#', '', '', 1, 0, 'F', '0', '0', 'train:student:unbindUser', '#', 'admin', CURRENT_TIMESTAMP, '学员系统账号解绑'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM public.sys_menu WHERE menu_id = 2244 OR perms = 'train:student:unbindUser');
|
||||
|
||||
INSERT INTO public.sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||||
SELECT 2246, '学员删除', 2156, 6, '#', '', '', 1, 0, 'F', '0', '0', 'train:student:remove', '#', 'admin', CURRENT_TIMESTAMP, '学员档案安全删除'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM public.sys_menu WHERE menu_id = 2246 OR perms = 'train:student:remove');
|
||||
|
||||
-- 3.3 教室管理 (parent: 2157)
|
||||
INSERT INTO public.sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||||
SELECT 2208, '教室查询', 2157, 1, '#', '', '', 1, 0, 'F', '0', '0', 'train:classroom:list', '#', 'admin', CURRENT_TIMESTAMP, '教室列表查询'
|
||||
@@ -326,6 +334,14 @@ BEGIN
|
||||
RAISE EXCEPTION 'Student binding permission missing';
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM public.sys_menu WHERE perms = 'train:teacher:remove') THEN
|
||||
RAISE EXCEPTION 'Teacher safe delete permission missing';
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM public.sys_menu WHERE perms = 'train:student:remove') THEN
|
||||
RAISE EXCEPTION 'Student safe delete permission missing';
|
||||
END IF;
|
||||
|
||||
IF EXISTS (SELECT 1 FROM public.sys_menu WHERE perms LIKE 'system:board:%') THEN
|
||||
RAISE EXCEPTION 'Legacy system:board:* permission namespace still exists';
|
||||
END IF;
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
-- =============================================================================
|
||||
-- 脚本名称: 011_teacher_student_remove_permissions.sql
|
||||
-- 业务模块: 教师与学员零引用安全删除权限节点注册 (ZERO-REFERENCE SAFE DELETE RBAC)
|
||||
-- 适用数据库: KingbaseES, schema public
|
||||
-- 范围: 仅限 sys_menu 按钮级权限增量注册,不改动已有角色分配 (sys_role_menu Δ = 0)
|
||||
-- 幂等性设计: 支持重复执行,WHERE NOT EXISTS 防重,无破坏性语句
|
||||
-- 安全红线:
|
||||
-- 1. 严禁执行 007_dicts.sql
|
||||
-- 2. 严禁清空/重建 sys_menu
|
||||
-- 3. 严禁重置角色权限
|
||||
-- 4. 严禁给 train_admin (role_id = 3) 自动赋权,保持 TRAIN_ADMIN_*_REMOVE = NO
|
||||
-- =============================================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- 前置碰撞检查
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM public.sys_menu
|
||||
WHERE menu_id = 2245 AND perms <> 'train:teacher:remove'
|
||||
) THEN
|
||||
RAISE EXCEPTION 'Menu ID 2245 collides with an existing menu item';
|
||||
END IF;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM public.sys_menu
|
||||
WHERE menu_id = 2246 AND perms <> 'train:student:remove'
|
||||
) THEN
|
||||
RAISE EXCEPTION 'Menu ID 2246 collides with an existing menu item';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- 1. 教师删除按钮权限 (train:teacher:remove, parent: 2155 教师管理)
|
||||
INSERT INTO public.sys_menu
|
||||
(menu_id, menu_name, parent_id, order_num, path, component, query, is_frame, is_cache,
|
||||
menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||||
SELECT 2245, '教师删除', 2155, 7, '#', '', '', 1, 0,
|
||||
'F', '0', '0', 'train:teacher:remove', '#', 'admin', CURRENT_TIMESTAMP, '教师档案安全删除'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM public.sys_menu WHERE perms = 'train:teacher:remove');
|
||||
|
||||
-- 2. 学员删除按钮权限 (train:student:remove, parent: 2156 学员管理)
|
||||
INSERT INTO public.sys_menu
|
||||
(menu_id, menu_name, parent_id, order_num, path, component, query, is_frame, is_cache,
|
||||
menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||||
SELECT 2246, '学员删除', 2156, 6, '#', '', '', 1, 0,
|
||||
'F', '0', '0', 'train:student:remove', '#', 'admin', CURRENT_TIMESTAMP, '学员档案安全删除'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM public.sys_menu WHERE perms = 'train:student:remove');
|
||||
|
||||
-- 3. 后置自检验收 (断言权限存在且唯一,且未向 train_admin 越权授权)
|
||||
DO $$
|
||||
BEGIN
|
||||
IF (SELECT count(*) FROM public.sys_menu WHERE perms = 'train:teacher:remove' AND parent_id = 2155 AND menu_type = 'F') <> 1 THEN
|
||||
RAISE EXCEPTION 'Teacher remove permission registration verification failed';
|
||||
END IF;
|
||||
|
||||
IF (SELECT count(*) FROM public.sys_menu WHERE perms = 'train:student:remove' AND parent_id = 2156 AND menu_type = 'F') <> 1 THEN
|
||||
RAISE EXCEPTION 'Student remove permission registration verification failed';
|
||||
END IF;
|
||||
|
||||
-- 严格断言 train_admin (role_id = 3) 未被分配这两个权限
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM public.sys_role_menu rm
|
||||
JOIN public.sys_menu m ON rm.menu_id = m.menu_id
|
||||
WHERE rm.role_id = 3 AND m.perms IN ('train:teacher:remove', 'train:student:remove')
|
||||
) THEN
|
||||
RAISE EXCEPTION 'FATAL: train_admin must not be granted teacher/student remove permissions';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
COMMIT;
|
||||
Reference in new issue
Block a user