feat: RBAC

This commit is contained in:
2025-03-12 16:34:54 +08:00
parent fb3686968d
commit 1c691e8626
9 changed files with 188 additions and 26 deletions

View File

@@ -14,6 +14,7 @@ import { SKIP_AUTH } from '@/common/decorators/skip-auth.decorator';
import { PERMISSIONS_KEY } from '@/common/decorators/permissions.decorator';
import { PrismaService } from '@/prisma/prisma.service';
import { PermissionType, Role } from '@/common/enum';
import { isArrayFullyContained } from '@/utils';
@Injectable()
export class PermissionGuard implements CanActivate {
@@ -44,6 +45,9 @@ export class PermissionGuard implements CanActivate {
sysUserRole: {
some: {
userId: request.user.sub,
role: {
status: 1,
},
},
},
},
@@ -59,18 +63,34 @@ export class PermissionGuard implements CanActivate {
return true;
}
// // 已知 权限字符 通过权限字符找出权限id 再根据权限id 找出拥有权限的角色code
// const hasPermission = await this.prisma.sysRolePermission.findMany({
// where: {
// roleId: {
// in: roleIds,
// },
// },
// });
// // TODO
//
// console.log(hasPermission);
// 已知 权限字符 通过权限字符判断是否有符合条件的结果
const rolePermissions = await this.prisma.sysResource.findMany({
select: {
permissionKey: true,
},
where: {
type: PermissionType.Api,
sysResourcePermission: {
some: {
permission: {
sysRolePermission: {
some: {
roleId: {
in: roleIds,
},
},
},
},
},
},
},
});
const hasPermission = isArrayFullyContained(
rolePermissions.map((item) => item.permissionKey),
requiredPermissions,
);
if (hasPermission) return true;
// 判断当前接口是否存在权限
throw new ForbiddenException('无权访问!');
}

View File

@@ -24,14 +24,14 @@ export class PermissionController {
@Get('/roles/:roleId/resources')
getRolResources(@Param('roleId') roleId: string) {
return this.permissionService.getRoleResources(roleId, PermissionType.Menu);
return this.permissionService.getRoleResources(roleId, PermissionType.Api);
}
@Put('/roles/:roleId/resources')
assignResources(@Param('roleId') roleId: string, @Body() data: GrantMenuDto) {
return this.permissionService.assignResources(
roleId,
PermissionType.Menu,
PermissionType.Api,
data,
);
}

View File

@@ -13,6 +13,9 @@ export class PermissionService {
resourceId: true,
},
where: {
resource: {
type,
},
permission: {
sysRolePermission: {
some: { roleId },

View File

@@ -1,11 +1,9 @@
import { Controller, Get } from '@nestjs/common';
import { TestService } from './test.service';
import { SkipAuth } from '@/common/decorators/skip-auth.decorator';
import { Permissions } from '@/common/decorators/permissions.decorator';
@Controller()
// @SkipAuth()
@Permissions('test', 'test2')
export class TestController {
constructor(private readonly testService: TestService) {}

View File

@@ -0,0 +1,5 @@
import { difference, isEmpty } from 'lodash';
export const isArrayFullyContained = (arr1: any[], arr2: any[]) => {
return isEmpty(difference(arr2, arr1));
};