Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | import { CanActivate, ExecutionContext, Injectable, ForbiddenException, } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { PermissionEvaluationService } from './permission.service'; import { PERMISSION_CHECK, PermissionMetadata } from './permission.decorator'; @Injectable() export class PermissionGuard implements CanActivate { constructor( private readonly reflector: Reflector, private readonly evaluationService: PermissionEvaluationService, ) {} async canActivate(context: ExecutionContext): Promise<boolean> { const check = this.reflector.getAllAndOverride<PermissionMetadata>( PERMISSION_CHECK, [context.getHandler(), context.getClass()], ); if (!check) { return true; } const request = context.switchToHttp().getRequest(); const tenantId = request.user?.tenantId || request.headers['x-tenant-id']; const userId = request.user?.id || request.headers['x-user-id']; if (!tenantId || !userId) { throw new ForbiddenException( 'Authentication context missing for authorization evaluation', ); } const result = await this.evaluationService.evaluate({ tenantId, userId, resource: check.resource, action: check.action, }); if (result.decision === 'DENY') { throw new ForbiddenException( `Access Denied: Required permission [${check.action}] on [${check.resource}]`, ); } return true; } } |