NestJS (6 services): implement @RequirePermission decorator with SetMetadata+Reflector, register APP_GUARD globally, fix as assertions to type guards, add explicit return types, fix import type for express, fix /metrics implicit any, replace native Error with ApplicationError, remove typeorm remnants, register LifecycleService. teacher-bff: add logger, ApplicationError, GlobalErrorFilter, forward real userId to downstream, log downstream failures, migrate health controller to shared/health. Go (2 services): interface to any, doc comments, CORS dev whitelist, JWT secret fail-fast, push-gateway internal API auth, metrics and readyz endpoints, remove dead code. Python (2 services): lifespan return type, dev_mode to bool, data-ana APIRouter, ai POST body model, ClickHouse async wrapping.
63 lines
2.2 KiB
TypeScript
63 lines
2.2 KiB
TypeScript
import { Controller, Get, Req } from "@nestjs/common";
|
||
import type { Request } from "express";
|
||
import { IamService } from "./iam.service.js";
|
||
import type { ViewportItem } from "./iam.service.js";
|
||
import type { Role, Permission } from "./iam.schema.js";
|
||
import { UnauthorizedError } from "../shared/errors/application-error.js";
|
||
import {
|
||
Permissions,
|
||
RequirePermission,
|
||
} from "../middleware/permission.guard.js";
|
||
|
||
// RBAC 管理端点:角色/权限/视口查询
|
||
@Controller("iam")
|
||
export class RbacController {
|
||
constructor(private readonly service: IamService) {}
|
||
|
||
// 获取当前用户的视口配置(L1 导航)
|
||
@Get("viewports")
|
||
@RequirePermission(Permissions.IAM_USER_READ)
|
||
async viewports(
|
||
@Req() req: Request,
|
||
): Promise<{ success: true; data: ViewportItem[] }> {
|
||
const userIdHeader = req.headers["x-user-id"];
|
||
const userId = typeof userIdHeader === "string" ? userIdHeader : undefined;
|
||
if (!userId) {
|
||
throw new UnauthorizedError("Missing x-user-id header");
|
||
}
|
||
const data = await this.service.getUserViewports(userId);
|
||
return { success: true as const, data };
|
||
}
|
||
|
||
// 获取当前用户的有效权限
|
||
@Get("permissions/effective")
|
||
@RequirePermission(Permissions.IAM_USER_READ)
|
||
async effectivePermissions(
|
||
@Req() req: Request,
|
||
): Promise<{ success: true; data: { permissions: string[] } }> {
|
||
const userIdHeader = req.headers["x-user-id"];
|
||
const userId = typeof userIdHeader === "string" ? userIdHeader : undefined;
|
||
if (!userId) {
|
||
throw new UnauthorizedError("Missing x-user-id header");
|
||
}
|
||
const permissions = await this.service.getEffectivePermissions(userId);
|
||
return { success: true as const, data: { permissions } };
|
||
}
|
||
|
||
// 列出所有角色(管理端用)
|
||
@Get("roles")
|
||
@RequirePermission(Permissions.IAM_ROLE_MANAGE)
|
||
async roles(): Promise<{ success: true; data: Role[] }> {
|
||
const data = await this.service.getAllRoles();
|
||
return { success: true as const, data };
|
||
}
|
||
|
||
// 列出所有权限点(管理端用)
|
||
@Get("permissions")
|
||
@RequirePermission(Permissions.IAM_ROLE_MANAGE)
|
||
async permissions(): Promise<{ success: true; data: Permission[] }> {
|
||
const data = await this.service.getAllPermissions();
|
||
return { success: true as const, data };
|
||
}
|
||
}
|