From db5b553a93c758f6401cca7a755116440082a564 Mon Sep 17 00:00:00 2001 From: liuyi Date: Mon, 30 Jun 2025 13:44:11 +0800 Subject: [PATCH] add rbac module --- src/modules/content/content.module.ts | 2 + src/modules/content/rbac.ts | 97 +++++++++++++++++++++++++++ src/modules/rbac/constants.ts | 2 +- 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 src/modules/content/rbac.ts diff --git a/src/modules/content/content.module.ts b/src/modules/content/content.module.ts index 3738848..fe1e0ee 100644 --- a/src/modules/content/content.module.ts +++ b/src/modules/content/content.module.ts @@ -1,6 +1,7 @@ import { DynamicModule, Module, ModuleMetadata } from '@nestjs/common'; import * as entities from '@/modules/content/entities'; +import { ContentRbac } from '@/modules/content/rbac'; import * as repositories from '@/modules/content/repositories'; import * as services from '@/modules/content/services'; import { SearchService } from '@/modules/content/services'; @@ -23,6 +24,7 @@ export class ContentModule { static async forRoot(configure: Configure): Promise { const config = await configure.get('content', defauleContentConfig); const providers: ModuleMetadata['providers'] = [ + ContentRbac, ...Object.values(services), ...(await addSubscribers(configure, Object.values(subscribers))), { diff --git a/src/modules/content/rbac.ts b/src/modules/content/rbac.ts new file mode 100644 index 0000000..d32a9a9 --- /dev/null +++ b/src/modules/content/rbac.ts @@ -0,0 +1,97 @@ +import { Injectable, OnModuleInit } from '@nestjs/common'; +import { ModuleRef } from '@nestjs/core'; + +import { CategoryEntity, CommentEntity, PostEntity, TagEntity } from '@/modules/content/entities'; +import { PermissionAction, SystemRoles } from '@/modules/rbac/constants'; +import { RbacResolver } from '@/modules/rbac/rbac.resolver'; + +@Injectable() +export class ContentRbac implements OnModuleInit { + constructor(private ref: ModuleRef) {} + onModuleInit() { + const resolver = this.ref.get(RbacResolver, { strict: false }); + resolver.addPermissions([ + { + name: 'post.create', + rule: { + action: PermissionAction.CREATE, + subject: PostEntity, + }, + }, + { + name: 'post.owner', + rule: { + action: PermissionAction.OWNER, + subject: PostEntity, + conditions: (user) => ({ + 'author.id': user.id, + }), + }, + }, + { + name: 'comment.create', + rule: { + action: PermissionAction.CREATE, + subject: CommentEntity, + }, + }, + { + name: 'comment.owner', + rule: { + action: PermissionAction.OWNER, + subject: CommentEntity, + conditions: (user) => ({ + 'author.id': user.id, + }), + }, + }, + { + name: 'post.manage', + rule: { + action: PermissionAction.MANAGE, + subject: PostEntity, + }, + }, + { + name: 'tag.manage', + rule: { + action: PermissionAction.MANAGE, + subject: TagEntity, + }, + }, + { + name: 'category.manage', + rule: { + action: PermissionAction.MANAGE, + subject: CategoryEntity, + }, + }, + { + name: 'comment.manage', + rule: { + action: PermissionAction.MANAGE, + subject: CommentEntity, + }, + }, + ]); + + resolver.addRoles([ + { + name: SystemRoles.USER, + permissions: [ + 'post.read', + 'post.create', + 'post.owner', + 'comment.create', + 'comment.owner', + ], + }, + { + name: 'content-manage', + label: '内容管理员', + description: '管理内容模块', + permissions: ['post.manage', 'category.manage', 'tag.manage', 'comment.manage'], + }, + ]); + } +} diff --git a/src/modules/rbac/constants.ts b/src/modules/rbac/constants.ts index 4921d50..85de963 100644 --- a/src/modules/rbac/constants.ts +++ b/src/modules/rbac/constants.ts @@ -13,5 +13,5 @@ export enum PermissionAction { UPDATE = 'update', DELETE = 'delete', MANAGE = 'manage', - OWNER = 'onwer', + OWNER = 'owner', }