{"record":{"id":"4fb7660cc1a0c2d2","repo":"paascloud/paascloud-master","slug":"uac10012002","errorCode":"UAC10012002","errorMessage":"拥有的角色不允许禁用","messagePattern":"拥有的角色不允许禁用","errorType":"error_code","errorClass":"UacBizException","httpStatus":null,"severity":"error","filePath":"paascloud-provider/paascloud-provider-uac/src/main/java/com/paascloud/provider/web/admin/UacRoleMainController.java","lineNumber":129,"sourceCode":"\t * @return the wrapper\n\t */\n\t@LogAnnotation\n\t@PostMapping(value = \"/modifyRoleStatusById\")\n\t@ApiOperation(httpMethod = \"POST\", value = \"根据角色Id修改角色状态\")\n\tpublic Wrapper modifyUacRoleStatusById(@ApiParam(name = \"modifyRoleStatusDto\", value = \"修改角色状态数据\") @RequestBody ModifyStatusDto modifyStatusDto) {\n\t\tlogger.info(\"根据角色Id修改角色状态 modifyStatusDto={}\", modifyStatusDto);\n\t\tLong roleId = modifyStatusDto.getId();\n\t\tif (roleId == null) {\n\t\t\tthrow new UacBizException(ErrorCodeEnum.UAC10012001);\n\t\t}\n\n\t\tLoginAuthDto loginAuthDto = getLoginAuthDto();\n\t\tLong userId = loginAuthDto.getUserId();\n\n\t\tUacRoleUser ru = uacRoleUserService.getByUserIdAndRoleId(userId, roleId);\n\n\t\tif (ru != null && UacRoleStatusEnum.DISABLE.getType().equals(modifyStatusDto.getStatus())) {\n\t\t\tthrow new UacBizException(ErrorCodeEnum.UAC10012002);\n\t\t}\n\n\t\tUacRole uacRole = new UacRole();\n\t\tuacRole.setId(roleId);\n\t\tuacRole.setStatus(modifyStatusDto.getStatus());\n\t\tuacRole.setUpdateInfo(loginAuthDto);\n\n\t\tint result = uacRoleService.update(uacRole);\n\t\treturn super.handleResult(result);\n\t}\n\n\n\t/**\n\t * 保存用户.\n\t *\n\t * @param role the role\n\t *\n\t * @return the wrapper","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/paascloud/paascloud-master/blob/781281a9503332ed3cef44ea618349d14230a127/paascloud-provider/paascloud-provider-uac/src/main/java/com/paascloud/provider/web/admin/UacRoleMainController.java#L111-L147","documentation":"UacBizException with code UAC10012002 thrown by UacRoleMainController.modifyUacRoleStatusById when the caller attempts to disable (UacRoleStatusEnum.DISABLE) a role that the currently logged-in user owns (a UacRoleUser row exists linking them). This is a self-protection rule preventing users from locking themselves out of their own roles.","triggerScenarios":"POST /modifyRoleStatusById with status='DISABLE' where uacRoleUserService.getByUserIdAndRoleId(loginUserId, roleId) returns a non-null row, i.e. the authenticated user currently holds the role being disabled.","commonSituations":"Admin testing the disable endpoint on their own admin role; bulk-disable scripts that don't exclude roles assigned to the executing user; status flips to DISABLE accidentally sent for roles the caller owns.","solutions":["Log in as a different user who does not hold the target role, then disable it","First unassign the role from the current user (delete the UacRoleUser binding), then disable the role","Change the target role's id in the request to one the caller does not own","If the disable is intentional for self-owned roles, the business rule must be changed in code"],"exampleFix":"// before\n{\"id\": 5, \"status\": \"DISABLE\"}  // caller owns role 5\n// after\n// reassign/disable as a user who does not hold role 5\n{\"id\": 5, \"status\": \"DISABLE\"}  // executed by another admin","handlingStrategy":"validation","validationCode":"// client-side guard: don't offer 'disable' for roles the current user holds\nif (currentUserRoleIds.includes(roleId) && newStatus === 'DISABLE') {\n  alert('不能禁用自己拥有的角色');\n  return;\n}","typeGuard":"function canDisable(roleId, currentUserRoleIds) { return !currentUserRoleIds.includes(roleId); }","tryCatchPattern":null,"preventionTips":["Exclude the current user's roles from bulk-disable operations","Unassign the role from yourself before disabling it","Test status changes with a secondary admin account","Document which roles are owned by the executing account"],"tags":["rest-api","authorization","business-rule"],"backgroundTag":"permission-denied","analyzedSha":"781281a9503332ed3cef44ea618349d14230a127","analyzedAt":"2026-09-10T10:59:02.070Z","contentChangedAt":"2026-09-10T10:59:02.070Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}