add rbac module
This commit is contained in:
parent
5de299c0c1
commit
23c8eba867
@ -40,6 +40,7 @@
|
|||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"deepmerge": "^4.3.1",
|
"deepmerge": "^4.3.1",
|
||||||
"dotenv": "^16.5.0",
|
"dotenv": "^16.5.0",
|
||||||
|
"fastify": "^5.4.0",
|
||||||
"find-up": "^7.0.0",
|
"find-up": "^7.0.0",
|
||||||
"fs-extra": "^11.3.0",
|
"fs-extra": "^11.3.0",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
|
1251
pnpm-lock.yaml
1251
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -6,3 +6,12 @@ export enum SystemRoles {
|
|||||||
export const SYSTEM_PERMISSION = 'system-manage';
|
export const SYSTEM_PERMISSION = 'system-manage';
|
||||||
|
|
||||||
export const PERMISSION_CHECKERS = 'permission_checkers';
|
export const PERMISSION_CHECKERS = 'permission_checkers';
|
||||||
|
|
||||||
|
export enum PermissionAction {
|
||||||
|
CREATE = 'create',
|
||||||
|
READ = 'read',
|
||||||
|
UPDATE = 'update',
|
||||||
|
DELETE = 'delete',
|
||||||
|
MANAGE = 'manage',
|
||||||
|
OWNER = 'onwer',
|
||||||
|
}
|
2
src/modules/rbac/entities/index.ts
Normal file
2
src/modules/rbac/entities/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './permission.entity';
|
||||||
|
export * from './role.entity';
|
52
src/modules/rbac/rbac.module.ts
Normal file
52
src/modules/rbac/rbac.module.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import { DynamicModule, forwardRef, Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { getDataSourceToken } from '@nestjs/typeorm';
|
||||||
|
import { DataSource } from 'typeorm';
|
||||||
|
|
||||||
|
import { DatabaseModule } from '@/modules/database/database.module';
|
||||||
|
|
||||||
|
import { RbacGuard } from '@/modules/rbac/guards/rbac.guard';
|
||||||
|
|
||||||
|
import { RbacResolver } from '@/modules/rbac/rbac.resolver';
|
||||||
|
|
||||||
|
import { Configure } from '../config/configure';
|
||||||
|
import { addEntities, addSubscribers } from '../database/utils';
|
||||||
|
import { UserModule } from '../user/user.module';
|
||||||
|
|
||||||
|
import * as entities from './entities';
|
||||||
|
import * as repositories from './repositories';
|
||||||
|
import * as services from './services';
|
||||||
|
import * as subscribers from './subscribers';
|
||||||
|
|
||||||
|
@Module({})
|
||||||
|
export class RbacModule {
|
||||||
|
static async forRoot(configure: Configure): Promise<DynamicModule> {
|
||||||
|
return {
|
||||||
|
module: RbacModule,
|
||||||
|
imports: [
|
||||||
|
forwardRef(() => UserModule),
|
||||||
|
await addEntities(configure, Object.values(entities)),
|
||||||
|
DatabaseModule.forRepository(Object.values(repositories)),
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
...Object.values(services),
|
||||||
|
...(await addSubscribers(configure, Object.values(subscribers))),
|
||||||
|
RbacGuard,
|
||||||
|
{
|
||||||
|
provide: RbacResolver,
|
||||||
|
useFactory: async (dataSource: DataSource) => {
|
||||||
|
const resolver = new RbacResolver(dataSource, configure);
|
||||||
|
resolver.setOptions({});
|
||||||
|
return resolver;
|
||||||
|
},
|
||||||
|
inject: [getDataSourceToken()],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
RbacResolver,
|
||||||
|
...Object.values(services),
|
||||||
|
DatabaseModule.forRepository(Object.values(repositories)),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -68,6 +68,7 @@ export class RbacResolver<P extends AbilityTuple = AbilityTuple, T extends Mongo
|
|||||||
if (!this.setuped) {
|
if (!this.setuped) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.setuped = true;
|
this.setuped = true;
|
||||||
|
console.log(this.options);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
2
src/modules/rbac/repositories/index.ts
Normal file
2
src/modules/rbac/repositories/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './permission.repository';
|
||||||
|
export * from './role.repository';
|
2
src/modules/rbac/services/index.ts
Normal file
2
src/modules/rbac/services/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './permission.service';
|
||||||
|
export * from './role.service';
|
2
src/modules/rbac/subscribers/index.ts
Normal file
2
src/modules/rbac/subscribers/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './permission.subscriber';
|
||||||
|
export * from './role.subscriber';
|
19
src/modules/rbac/utils.ts
Normal file
19
src/modules/rbac/utils.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { MongoAbility } from '@casl/ability';
|
||||||
|
import { FastifyRekquest as Request } from 'fastify';
|
||||||
|
import { ObjectLiteral } from 'typeorm';
|
||||||
|
|
||||||
|
import { PermissionAction } from './constants';
|
||||||
|
|
||||||
|
export async function checkOwnerPermission<T extends ObjectLiteral>(
|
||||||
|
ability: MongoAbility,
|
||||||
|
options: {
|
||||||
|
request: Request;
|
||||||
|
key?: string;
|
||||||
|
getData: (items: string[]) => Promise<T[]>;
|
||||||
|
permission?: string;
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
const { request, key, getData, permission } = options;
|
||||||
|
const models = await getData(getRequestData(request, key));
|
||||||
|
return models.every((model) => ability.can(permission ?? PermissionAction.OWNER, model));
|
||||||
|
}
|
@ -7,7 +7,6 @@ import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify
|
|||||||
import { existsSync } from 'fs-extra';
|
import { existsSync } from 'fs-extra';
|
||||||
import { isNil } from 'lodash';
|
import { isNil } from 'lodash';
|
||||||
|
|
||||||
import { JwtAuthGuard } from '@/modules/user/guards';
|
|
||||||
import { UserModule } from '@/modules/user/user.module';
|
import { UserModule } from '@/modules/user/user.module';
|
||||||
|
|
||||||
import * as configs from './config';
|
import * as configs from './config';
|
||||||
@ -16,6 +15,7 @@ import { CreateOptions } from './modules/core/types';
|
|||||||
import * as dbCommands from './modules/database/commands';
|
import * as dbCommands from './modules/database/commands';
|
||||||
import { DatabaseModule } from './modules/database/database.module';
|
import { DatabaseModule } from './modules/database/database.module';
|
||||||
import { MeiliModule } from './modules/meilisearch/meili.module';
|
import { MeiliModule } from './modules/meilisearch/meili.module';
|
||||||
|
import { RbacGuard } from './modules/rbac/guards/rbac.guard';
|
||||||
import { Restful } from './modules/restful/restful';
|
import { Restful } from './modules/restful/restful';
|
||||||
import { RestfulModule } from './modules/restful/restful.module';
|
import { RestfulModule } from './modules/restful/restful.module';
|
||||||
import { ApiConfig } from './modules/restful/types';
|
import { ApiConfig } from './modules/restful/types';
|
||||||
@ -30,7 +30,7 @@ export const createOptions: CreateOptions = {
|
|||||||
await ContentModule.forRoot(configure),
|
await ContentModule.forRoot(configure),
|
||||||
await UserModule.forRoot(configure),
|
await UserModule.forRoot(configure),
|
||||||
],
|
],
|
||||||
globals: { guard: JwtAuthGuard },
|
globals: { guard: RbacGuard },
|
||||||
builder: async ({ configure, BootModule }) => {
|
builder: async ({ configure, BootModule }) => {
|
||||||
const container = await NestFactory.create<NestFastifyApplication>(
|
const container = await NestFactory.create<NestFastifyApplication>(
|
||||||
BootModule,
|
BootModule,
|
||||||
|
Loading…
Reference in New Issue
Block a user