feat: RBAC
This commit is contained in:
@@ -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('无权访问!');
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@ export class PermissionService {
|
||||
resourceId: true,
|
||||
},
|
||||
where: {
|
||||
resource: {
|
||||
type,
|
||||
},
|
||||
permission: {
|
||||
sysRolePermission: {
|
||||
some: { roleId },
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { difference, isEmpty } from 'lodash';
|
||||
|
||||
export const isArrayFullyContained = (arr1: any[], arr2: any[]) => {
|
||||
return isEmpty(difference(arr2, arr1));
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user