This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Controller("invoices") | |
export class InvoicesController { | |
constructor(private readonly invoicesService: InvoicesService, private abilityFactory: AbilityFactory) {} | |
@Get(":id") | |
async findOne( | |
@Param("departmentId", ParseIntPipe) departmentId: number, | |
@Param("invoiceId", ParseIntPipe) invoiceId: number, | |
@Request() req: AuthenticatedRequest, | |
): Promise<InvoiceResponseDto> { | |
const ability = await this.abilityFactory.createForUser(req.user); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface CaslPermission { | |
action: PermissionAction; | |
subject: string; | |
condition?: PermissionCondition; | |
} | |
@Injectable() | |
export class CaslAbilityFactory { | |
constructor(private authoService: AuthzService) {} | |
async createForUser(user: User): Promise<AppAbility> { | |
const dbPermissions: Permission[] = await this.authoService.findAllPermissionsOfUser(user); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export interface PermissionCondition {} | |
@Entity("permissions") | |
export class Permission extends BaseEntity { | |
// define class attributes... | |
/** | |
* @param condition: {"departmentId": "${id}"} | |
* @param variables: {"id: 1"} | |
* @return condition after parse: {"departmentId": 1} | |
*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"id": 1, | |
"action": "READ", | |
"objectId": 5, // id of Invoice object, refer to objects table. | |
"condition": { | |
"departmentId": "${id}" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Global() | |
@Module({ | |
imports: [ | |
TypeOrmModule.forFeature([UserRepository]), | |
], | |
providers: [CaslAbilityFactory, PermissionsGuard, AuthzService], | |
exports: [CaslAbilityFactory, PermissionsGuard], | |
}) | |
export class AuthzModule {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Post() | |
@UseGuards(PermissionsGuard) | |
@CheckPermissions([PermissionAction.CREATE, "Invoice"]) // "Invoice" is the value in name column of objects table | |
async create( | |
// create invoice params | |
): Promise<InvoiceResponseDto> { | |
// create invoice logic | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { CanActivate, ExecutionContext, Injectable } from "@nestjs/common"; | |
import { Reflector } from "@nestjs/core"; | |
@Injectable() | |
export class PermissionsGuard implements CanActivate { | |
constructor(private reflector: Reflector, private abilityFactory: CaslAbilityFactory) {} | |
async canActivate(context: ExecutionContext): Promise<boolean> { | |
const requiredPermissions = | |
this.reflector.get<RequiredPermission[]>(PERMISSION_CHECKER_KEY, context.getHandler()) || []; | |
const req = context.switchToHttp().getRequest(); | |
const user = req.user; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { CustomDecorator, SetMetadata } from "@nestjs/common"; | |
// action, object | |
export type RequiredPermission = [PermissionAction, PermissionObjectType] | |
export const PERMISSION_CHECKER_KEY = "permission_checker_params_key"; | |
export const CheckPermissions = (...params: RequiredPermission[]): CustomDecorator<string> => | |
SetMetadata(PERMISSION_CHECKER_KEY, params); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Ability } from "@casl/ability"; | |
export enum PermissionAction { | |
CREATE = "create", | |
READ = "read", | |
UPDATE = "update", | |
DELETE = "delete", | |
} | |
export type PermissionObjectType = any; | |
export type AppAbility = Ability<[PermissionAction, PermissionObjectType]>; | |
interface CaslPermission { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ nest g class authz/casl-ability.factory |
NewerOlder