feat: add CASL authorization and AI configuration

This commit is contained in:
2026-07-11 14:25:34 +08:00
parent 8f0991a51f
commit 1e1c476bc3
59 changed files with 7733 additions and 120 deletions

View File

@@ -10,6 +10,11 @@ import {
UseGuards,
Request,
} from '@nestjs/common';
import {
AuthorizationService,
CaslAction,
SubjectName,
} from '../authorization';
import { SchedulesService } from './schedules.service';
import {
CreateScheduleDto,
@@ -28,8 +33,8 @@ import { RequirePermission } from '../auth/decorators/permission.decorator';
interface RequestUser {
id: number;
username: string;
permissions?: string[];
isSuperAdmin?: boolean;
permissions: string[];
isSuperAdmin: boolean;
}
@UseGuards(JwtAuthGuard)
@@ -39,13 +44,15 @@ export class SchedulesController {
private readonly service: SchedulesService,
private readonly logService: OperationLogsService,
private readonly notificationsService: NotificationsService,
private readonly authService: AuthorizationService,
) {}
private canManageAllSchedules(user: RequestUser): boolean {
private canManageAllSchedules(req: { user: RequestUser }): boolean {
const ability = this.authService.abilityForRequest(req);
// Legacy: class:edit grants broad schedule access for teachers
return (
user.isSuperAdmin === true ||
user.permissions?.includes('schedule:edit') === true ||
user.permissions?.includes('class:edit') === true
ability.can(CaslAction.Manage, SubjectName.Schedule) ||
ability.can(CaslAction.Update, SubjectName.Class)
);
}
@@ -54,7 +61,7 @@ export class SchedulesController {
async findAll(@Query() query: QueryScheduleDto, @Request() req: { user: RequestUser }) {
const classIds = await this.service.getAccessibleClassIds(
req.user.id,
this.canManageAllSchedules(req.user),
this.canManageAllSchedules(req),
);
return this.service.findAll(query, classIds);
}
@@ -64,7 +71,7 @@ export class SchedulesController {
async getWeeklyView(@Query() query: WeeklyViewQueryDto, @Request() req: { user: RequestUser }) {
const classIds = await this.service.getAccessibleClassIds(
req.user.id,
this.canManageAllSchedules(req.user),
this.canManageAllSchedules(req),
);
return this.service.getWeeklyView(query, classIds);
}
@@ -74,7 +81,7 @@ export class SchedulesController {
async getClassTeachers(@Param('classId') classId: string, @Request() req: { user: RequestUser }) {
const classIds = await this.service.getAccessibleClassIds(
req.user.id,
this.canManageAllSchedules(req.user),
this.canManageAllSchedules(req),
);
if (classIds && !classIds.includes(+classId)) return [];
return this.service.getClassTeachers(+classId);