forked from wangziqi/gongxue-base
feat: add CASL authorization and AI configuration
This commit is contained in:
50
apps/server/src/students/student-access-scope.factory.ts
Normal file
50
apps/server/src/students/student-access-scope.factory.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { CaslAbilityFactory } from '../authorization/casl-ability.factory';
|
||||
import { CaslAction, SubjectName } from '../authorization/casl.constants';
|
||||
import type { AgentToolContext } from '../agent-tools/agent-tool.types';
|
||||
import type { StudentAccessScope } from './student-access-scope';
|
||||
|
||||
/**
|
||||
* Constructs a {@link StudentAccessScope} from the trusted server-side
|
||||
* principal carried in {@link AgentToolContext}.
|
||||
*
|
||||
* ## Scope rules
|
||||
*
|
||||
* | Condition | Scope |
|
||||
* |---|---|
|
||||
* | `isSuperAdmin` | `manageAll` |
|
||||
* | `class:edit` domain ability (`Update Class`) | `manageAll` |
|
||||
* | Everything else | `teacher(userId)` |
|
||||
*
|
||||
* These rules mirror the HTTP-layer logic so agent tools are consistent
|
||||
* with the web dashboard. The ability is constructed fresh from the
|
||||
* principal each time — callers cannot pre-forge it.
|
||||
*/
|
||||
@Injectable()
|
||||
export class StudentAccessScopeFactory {
|
||||
constructor(private readonly abilityFactory: CaslAbilityFactory) {}
|
||||
|
||||
/**
|
||||
* Build a scope from the authenticated context.
|
||||
*
|
||||
* The ability is constructed from the principal fields inside the context
|
||||
* — every call is a fresh derivation.
|
||||
*/
|
||||
buildScope(context: AgentToolContext): StudentAccessScope {
|
||||
const ability = this.abilityFactory.createForUser({
|
||||
permissions: context.permissions,
|
||||
isSuperAdmin: context.isSuperAdmin,
|
||||
});
|
||||
|
||||
if (context.isSuperAdmin) {
|
||||
return { type: 'manageAll' };
|
||||
}
|
||||
|
||||
// class:edit (Update Class) grants full student scope
|
||||
if (ability.can(CaslAction.Update, SubjectName.Class)) {
|
||||
return { type: 'manageAll' };
|
||||
}
|
||||
|
||||
return { type: 'teacher', userId: context.userId };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user