{"record":{"id":"5196da9245c716ef","repo":"YunaiV/ruoyi-vue-pro","slug":"loginuser-d-table-s-s","errorCode":null,"errorMessage":"LoginUser(%d) Table(%s/%s) 未返回数据权限","messagePattern":"LoginUser\\((.+?)\\) Table\\((.+?)/(.+?)\\) 未返回数据权限","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java","lineNumber":109,"sourceCode":"    public Expression getExpression(String tableName, Alias tableAlias) {\n        // 只有有登陆用户的情况下，才进行数据权限的处理\n        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();\n        if (loginUser == null) {\n            return null;\n        }\n        // 只有管理员类型的用户，才进行数据权限的处理\n        if (ObjectUtil.notEqual(loginUser.getUserType(), UserTypeEnum.ADMIN.getValue())) {\n            return null;\n        }\n\n        // 获得数据权限\n        DeptDataPermissionRespDTO deptDataPermission = loginUser.getContext(CONTEXT_KEY, DeptDataPermissionRespDTO.class);\n        // 从上下文中拿不到，则调用逻辑进行获取\n        if (deptDataPermission == null) {\n            deptDataPermission = permissionApi.getDeptDataPermission(loginUser.getId());\n            if (deptDataPermission == null) {\n                log.error(\"[getExpression][LoginUser({}) 获取数据权限为 null]\", JsonUtils.toJsonString(loginUser));\n                throw new NullPointerException(String.format(\"LoginUser(%d) Table(%s/%s) 未返回数据权限\",\n                        loginUser.getId(), tableName, tableAlias.getName()));\n            }\n            // 添加到上下文中，避免重复计算\n            loginUser.setContext(CONTEXT_KEY, deptDataPermission);\n        }\n\n        // 情况一，如果是 ALL 可查看全部，则无需拼接条件\n        if (deptDataPermission.getAll()) {\n            return null;\n        }\n\n        // 情况二，即不能查看部门，又不能查看自己，则说明 100% 无权限\n        if (CollUtil.isEmpty(deptDataPermission.getDeptIds())\n            && Boolean.FALSE.equals(deptDataPermission.getSelf())) {\n            return new EqualsTo(null, null); // WHERE null = null，可以保证返回的数据为空\n        }\n\n        // 情况三，拼接 Dept 和 User 的条件，最后组合","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/YunaiV/ruoyi-vue-pro/blob/0418084e222612af2fc1141f566af454f9236ab1/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java#L91-L127","documentation":"yudao's DeptDataPermissionRule builds a dept-scoped data-permission expression. For an ADMIN user it calls permissionApi.getDeptDataPermission(userId); if the API returns null (no rule matched, no dept assigned), the rule cannot compose any SQL condition and throws NullPointerException to fail loudly rather than silently granting/denying all rows. tableName and tableAlias are included for context.","triggerScenarios":"An admin user has no dept binding and no 'all' permission configured for the table; the permission RPC returns null due to a backend bug or missing seed data; the dept-data-permission rule is enabled for a table the user has no permission record for.","commonSituations":"Fresh install without seeding dept/role-permission data; misconfigured data-permission rule referencing a table with no permission rows; permissionApi cache miss returning null.","solutions":["Ensure the admin user is bound to a dept and that DeptDataPermission records exist for the target table.","If null is legitimately 'no data', fix permissionApi to return a default (empty/all=false) DeptDataPermissionRespDTO instead of null.","Disable the dept-data-permission rule for tables where it should not apply."],"exampleFix":"// before\nDeptDataPermissionRespDTO perm = permissionApi.getDeptDataPermission(userId);\nif (perm == null) throw new NullPointerException(...);\n// after: default to no-access instead of NPE\nDeptDataPermissionRespDTO perm = permissionApi.getDeptDataPermission(userId);\nif (perm == null) perm = new DeptDataPermissionRespDTO().setAll(false);","handlingStrategy":"validation","validationCode":"DeptDataPermissionRespDTO perm = permissionApi.getDeptDataPermission(loginUser.getId());\nif (perm == null) perm = new DeptDataPermissionRespDTO().setAll(false).setDeptIds(Collections.emptySet());","typeGuard":"static boolean hasDataPermission(DeptDataPermissionRespDTO p) { return p != null && (p.getAll() || p.getDeptIds()!=null || p.getSelf()); }","tryCatchPattern":"try { return rule.getExpression(tableName, tableAlias, root, mapper); }\ncatch (NullPointerException e) { return null; /* treat as no restriction / no access per policy */ }","preventionTips":["Seed dept/permission data for all admin users","Make permissionApi return a safe default DTO instead of null","Disable the dept-data-permission rule for tables without permission records"],"tags":["yudao","data-permission","null-pointer","authorization"],"backgroundTag":null,"analyzedSha":"0418084e222612af2fc1141f566af454f9236ab1","analyzedAt":"2026-08-14T00:56:18.412Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}