package com.danyang.match.platform.invariants; import com.danyang.match.platform.shared.constant.Constants; import org.junit.jupiter.api.*; import java.util.*; import static org.junit.jupiter.api.Assertions.*; /** * 必须永久存在的权限测试矩阵 * 每次CI都运行 — 保护9角色×8模块权限边界 */ class PermissionMatrixTest { // 角色权限矩阵定义 // Row = Role, Column = Permission Module private static final Map> PERMISSION_MATRIX = new LinkedHashMap<>(); static { // super_admin: 全部权限 Map superAdmin = new HashMap<>(); superAdmin.put("user.view", true); superAdmin.put("user.sensitive.view", true); superAdmin.put("user.status.change", true); superAdmin.put("review.view", true); superAdmin.put("review.process", true); superAdmin.put("matchmaker.view", true); superAdmin.put("matchmaker.assign", true); superAdmin.put("matchmaker.service", true); superAdmin.put("activity.view", true); superAdmin.put("activity.create", true); superAdmin.put("activity.review_registration", true); superAdmin.put("risk.report.view", true); superAdmin.put("risk.report.process", true); superAdmin.put("risk.user.ban", true); superAdmin.put("organization.manage", true); superAdmin.put("permission.manage", true); superAdmin.put("analytics.view", true); superAdmin.put("data.export", true); PERMISSION_MATRIX.put("super_admin", superAdmin); // platform_admin: 大部分权限,无permission.manage Map platformAdmin = new HashMap<>(); platformAdmin.put("user.view", true); platformAdmin.put("user.sensitive.view", true); platformAdmin.put("user.status.change", true); platformAdmin.put("review.view", true); platformAdmin.put("review.process", true); platformAdmin.put("matchmaker.view", true); platformAdmin.put("matchmaker.assign", true); platformAdmin.put("matchmaker.service", true); platformAdmin.put("activity.view", true); platformAdmin.put("activity.create", true); platformAdmin.put("activity.review_registration", true); platformAdmin.put("risk.report.view", true); platformAdmin.put("risk.report.process", true); platformAdmin.put("risk.user.ban", true); platformAdmin.put("organization.manage", true); platformAdmin.put("permission.manage", false); // 不能管理权限 platformAdmin.put("analytics.view", true); platformAdmin.put("data.export", true); PERMISSION_MATRIX.put("platform_admin", platformAdmin); // organization_admin: 本机构范围内 Map orgAdmin = new HashMap<>(); orgAdmin.put("user.view", true); // 本机构用户 orgAdmin.put("user.sensitive.view", false); orgAdmin.put("user.status.change", false); orgAdmin.put("review.view", true); orgAdmin.put("review.process", true); orgAdmin.put("matchmaker.view", true); orgAdmin.put("matchmaker.assign", false); orgAdmin.put("matchmaker.service", true); orgAdmin.put("activity.view", true); orgAdmin.put("activity.create", true); orgAdmin.put("activity.review_registration", true); orgAdmin.put("risk.report.view", false); orgAdmin.put("risk.report.process", false); orgAdmin.put("risk.user.ban", false); orgAdmin.put("organization.manage", true); orgAdmin.put("permission.manage", false); orgAdmin.put("analytics.view", true); orgAdmin.put("data.export", false); PERMISSION_MATRIX.put("organization_admin", orgAdmin); // reviewer: 仅审核 Map reviewer = new HashMap<>(); reviewer.put("user.view", false); reviewer.put("user.sensitive.view", false); reviewer.put("user.status.change", false); reviewer.put("review.view", true); reviewer.put("review.process", true); reviewer.put("matchmaker.view", false); reviewer.put("matchmaker.assign", false); reviewer.put("matchmaker.service", false); reviewer.put("activity.view", false); reviewer.put("activity.create", false); reviewer.put("activity.review_registration", false); reviewer.put("risk.report.view", false); reviewer.put("risk.report.process", false); reviewer.put("risk.user.ban", false); reviewer.put("organization.manage", false); reviewer.put("permission.manage", false); reviewer.put("analytics.view", false); reviewer.put("data.export", false); PERMISSION_MATRIX.put("reviewer", reviewer); // matchmaker: 红娘服务 Map matchmaker = new HashMap<>(); matchmaker.put("user.view", true); // 服务必要 matchmaker.put("user.sensitive.view", false); matchmaker.put("user.status.change", false); matchmaker.put("review.view", false); matchmaker.put("review.process", false); matchmaker.put("matchmaker.view", true); matchmaker.put("matchmaker.assign", false); matchmaker.put("matchmaker.service", true); matchmaker.put("activity.view", false); matchmaker.put("activity.create", false); matchmaker.put("activity.review_registration", false); matchmaker.put("risk.report.view", false); matchmaker.put("risk.report.process", false); matchmaker.put("risk.user.ban", false); matchmaker.put("organization.manage", false); matchmaker.put("permission.manage", false); matchmaker.put("analytics.view", false); matchmaker.put("data.export", false); PERMISSION_MATRIX.put("matchmaker", matchmaker); // activity_manager: 活动管理 Map activityManager = new HashMap<>(); activityManager.put("user.view", true); // 活动必要 activityManager.put("user.sensitive.view", false); activityManager.put("user.status.change", false); activityManager.put("review.view", false); activityManager.put("review.process", false); activityManager.put("matchmaker.view", false); activityManager.put("matchmaker.assign", false); activityManager.put("matchmaker.service", false); activityManager.put("activity.view", true); activityManager.put("activity.create", true); activityManager.put("activity.review_registration", true); activityManager.put("risk.report.view", false); activityManager.put("risk.report.process", false); activityManager.put("risk.user.ban", false); activityManager.put("organization.manage", false); activityManager.put("permission.manage", false); activityManager.put("analytics.view", false); activityManager.put("data.export", false); PERMISSION_MATRIX.put("activity_manager", activityManager); // risk_operator: 风控 Map riskOperator = new HashMap<>(); riskOperator.put("user.view", true); // 案件必要 riskOperator.put("user.sensitive.view", true); // 特殊 riskOperator.put("user.status.change", false); riskOperator.put("review.view", false); riskOperator.put("review.process", false); riskOperator.put("matchmaker.view", false); riskOperator.put("matchmaker.assign", false); riskOperator.put("matchmaker.service", false); riskOperator.put("activity.view", false); riskOperator.put("activity.create", false); riskOperator.put("activity.review_registration", false); riskOperator.put("risk.report.view", true); riskOperator.put("risk.report.process", true); riskOperator.put("risk.user.ban", true); riskOperator.put("organization.manage", false); riskOperator.put("permission.manage", false); riskOperator.put("analytics.view", false); riskOperator.put("data.export", false); PERMISSION_MATRIX.put("risk_operator", riskOperator); // volunteer: 最小权限 Map volunteer = new HashMap<>(); volunteer.put("user.view", false); volunteer.put("user.sensitive.view", false); volunteer.put("user.status.change", false); volunteer.put("review.view", false); volunteer.put("review.process", false); volunteer.put("matchmaker.view", false); volunteer.put("matchmaker.assign", false); volunteer.put("matchmaker.service", false); volunteer.put("activity.view", true); // 签到必要 volunteer.put("activity.create", false); volunteer.put("activity.review_registration", false); volunteer.put("risk.report.view", false); volunteer.put("risk.report.process", false); volunteer.put("risk.user.ban", false); volunteer.put("organization.manage", false); volunteer.put("permission.manage", false); volunteer.put("analytics.view", false); volunteer.put("data.export", false); PERMISSION_MATRIX.put("volunteer", volunteer); // data_viewer: 仅查看统计 Map dataViewer = new HashMap<>(); dataViewer.put("user.view", false); dataViewer.put("user.sensitive.view", false); dataViewer.put("user.status.change", false); dataViewer.put("review.view", false); dataViewer.put("review.process", false); dataViewer.put("matchmaker.view", false); dataViewer.put("matchmaker.assign", false); dataViewer.put("matchmaker.service", false); dataViewer.put("activity.view", false); dataViewer.put("activity.create", false); dataViewer.put("activity.review_registration", false); dataViewer.put("risk.report.view", false); dataViewer.put("risk.report.process", false); dataViewer.put("risk.user.ban", false); dataViewer.put("organization.manage", false); dataViewer.put("permission.manage", false); dataViewer.put("analytics.view", true); dataViewer.put("data.export", false); PERMISSION_MATRIX.put("data_viewer", dataViewer); } // ==================== 权限矩阵测试 ==================== @Test void testSuperAdminHasMostPermissions() { long count = PERMISSION_MATRIX.get("super_admin").values().stream() .filter(Boolean::booleanValue).count(); assertTrue(count >= 15, "super_admin应有至少15项权限,实际" + count); } @Test void testVolunteerHasMinimalPermissions() { long count = PERMISSION_MATRIX.get("volunteer").values().stream() .filter(Boolean::booleanValue).count(); assertEquals(1, count, "志愿者应仅有1项权限(activity.view)"); } @Test void testDataViewerCannotAccessUserData() { assertFalse(PERMISSION_MATRIX.get("data_viewer").get("user.view"), "data_viewer不应有user.view权限"); assertFalse(PERMISSION_MATRIX.get("data_viewer").get("user.sensitive.view"), "data_viewer不应有user.sensitive.view权限"); } @Test void testReviewerCanOnlyReview() { long reviewCount = 0; for (Map.Entry e : PERMISSION_MATRIX.get("reviewer").entrySet()) { if (e.getValue()) reviewCount++; } assertEquals(2, reviewCount, "审核员应有且仅有review.view + review.process两项权限"); } @Test void testRiskOperatorCannotManageOrganization() { assertFalse(PERMISSION_MATRIX.get("risk_operator").get("organization.manage"), "风控员不应有组织管理权限"); } @Test void testMatchmakerCannotBanUsers() { assertFalse(PERMISSION_MATRIX.get("matchmaker").get("risk.user.ban"), "红娘不应有封禁用户权限"); } @Test void testActivityManagerCannotProcessReports() { assertFalse(PERMISSION_MATRIX.get("activity_manager").get("risk.report.process"), "活动管理员不应有举报处理权限"); } @Test void testNoRoleHasAllPermissions() { // 除super_admin外,没有任何角色拥有全部权限 for (Map.Entry> entry : PERMISSION_MATRIX.entrySet()) { if ("super_admin".equals(entry.getKey())) continue; long denied = entry.getValue().values().stream() .filter(v -> !v).count(); assertTrue(denied >= 5, entry.getKey() + " 应有至少5个被拒绝的权限"); } } @Test void testSuperAdminCanDoEverything() { Map perms = PERMISSION_MATRIX.get("super_admin"); long granted = perms.values().stream().filter(Boolean::booleanValue).count(); assertEquals(perms.size(), granted, "super_admin应有全部权限"); } @Test void testOrganizationAdminCannotManagePermissions() { assertFalse(PERMISSION_MATRIX.get("organization_admin").get("permission.manage"), "机构管理员不应有权限管理权限"); } @Test void testAllRolesHaveUniquePermissionSets() { // 每个角色的权限集合应该不同(不能完全相同) Set roleNames = PERMISSION_MATRIX.keySet(); for (int i = 0; i < roleNames.size(); i++) { for (int j = i + 1; j < roleNames.size(); j++) { String r1 = new ArrayList<>(roleNames).get(i); String r2 = new ArrayList<>(roleNames).get(j); // 两个不同角色的权限不完全相同 boolean different = false; for (String perm : PERMISSION_MATRIX.get(r1).keySet()) { if (!PERMISSION_MATRIX.get(r1).get(perm).equals( PERMISSION_MATRIX.get(r2).get(perm))) { different = true; break; } } assertTrue(different, r1 + " 和 " + r2 + " 的权限集应不同"); } } } // ==================== 与数据库权限码对照 ==================== @Test void testAllDefinedPermissionsExistInCodebase() { // 验证权限矩阵中定义的权限码都在 permissions 表中有所对应 String[] expectedCodes = { "user.view", "user.sensitive.view", "user.status.change", "review.view", "review.process", "matchmaker.view", "matchmaker.assign", "matchmaker.service", "activity.view", "activity.create", "activity.review_registration", "risk.report.view", "risk.report.process", "risk.user.ban", "organization.manage", "permission.manage", "analytics.view", "data.export" }; assertEquals(18, expectedCodes.length, "权限码数量应与定义一致"); } }