All Projects → sergey-telpuk → Nestjs Rbac

sergey-telpuk / Nestjs Rbac

Licence: other
Awesome RBAC for NestJs

Programming Languages

javascript
184084 projects - #8 most used programming language
typescript
32286 projects

Projects that are alternatives of or similar to Nestjs Rbac

Nestjs Roles
Type safe roles guard and decorator made easy
Stars: ✭ 78 (-39.53%)
Mutual labels:  nestjs, rbac
nt-casbin
nest.js with casbin auth Nest.js RBAC ABAC 权限管理
Stars: ✭ 27 (-79.07%)
Mutual labels:  rbac, nestjs
Nestjs Amqp
Amqp connections for nestjs 💌
Stars: ✭ 123 (-4.65%)
Mutual labels:  nestjs
Tiny Package Manager
Learn how npm or Yarn v1 works.
Stars: ✭ 125 (-3.1%)
Mutual labels:  npm
Pnpm
Fast, disk space efficient package manager -- 快速的,节省磁盘空间的包管理工具
Stars: ✭ 14,219 (+10922.48%)
Mutual labels:  npm
Npm Link Shared
links a folder of local modules with inter-dependencies to the target directory
Stars: ✭ 123 (-4.65%)
Mutual labels:  npm
Nest Event
Event handling with decorators for NestJS Framework
Stars: ✭ 128 (-0.78%)
Mutual labels:  nestjs
Create New Cli
Create your own CLI using a series of simple commands.
Stars: ✭ 122 (-5.43%)
Mutual labels:  npm
Web Starter Kit
Web Starter Kit is an opinionated boilerplate for web development. A solid starting point for both professionals and newcomers to the industry.
Stars: ✭ 130 (+0.78%)
Mutual labels:  npm
Npm Module Checklist
Steps to check when starting, working and publishing a module to NPM
Stars: ✭ 125 (-3.1%)
Mutual labels:  npm
Importabular
5kb spreadsheet editor for the web, let your users import their data from excel.
Stars: ✭ 129 (+0%)
Mutual labels:  npm
Nest Cnode
CNode 社区 Nest 版本 https://cnodejs.org/
Stars: ✭ 125 (-3.1%)
Mutual labels:  nestjs
Node Rate Limiter Flexible
Node.js rate limit requests by key with atomic increments in single process or distributed environment.
Stars: ✭ 1,950 (+1411.63%)
Mutual labels:  nestjs
Flagpack Core
Flagpack contains 260+ easily implementable flag icons to use in your design or code project.
Stars: ✭ 127 (-1.55%)
Mutual labels:  npm
Atbmarket
🎉 JUST FOR FUN :: npm package of ATB plastic bag
Stars: ✭ 123 (-4.65%)
Mutual labels:  npm
Vscode Deploy Reloaded
Recoded version of Visual Studio Code extension 'vs-deploy', which provides commands to deploy files to one or more destinations.
Stars: ✭ 129 (+0%)
Mutual labels:  npm
Greenkeeper
🤖 🌴 Real-time automated dependency updates for npm and GitHub
Stars: ✭ 1,564 (+1112.4%)
Mutual labels:  npm
Npm Expansions
Send us a pull request by editing expansions.txt
Stars: ✭ 1,777 (+1277.52%)
Mutual labels:  npm
Caddy Auth Jwt
JWT Authorization Plugin for Caddy v2
Stars: ✭ 127 (-1.55%)
Mutual labels:  rbac
Yii2 Ace Admin
我的Yii2 Admin后台项目
Stars: ✭ 130 (+0.78%)
Mutual labels:  rbac

Scrutinizer Code Quality codecov npm RBAC CI RBAC CD

Description

The rbac module for Nest.

Installation

npm i --save nestjs-rbac

Quick Start

For using RBAC there is need to implement IStorageRbac

export interface IStorageRbac {
  roles: string[];
  permissions: object;
  grants: object;
  filters: { [key: string]: any | IFilterPermission };
}

For instance:

export const RBACstorage: IStorageRbac = {
  roles: ['admin', 'user'],
  permissions: {
    permission1: ['create', 'update', 'delete'],
    permission2: ['create', 'update', 'delete'],
    permission3: ['filter1', 'filter2', RBAC_REQUEST_FILTER],
    permission4: ['create', 'update', 'delete'],
  },
  grants: {
    admin: [
      '&user',
      'permission1',
      'permission3',
    ],
    user: ['permission2', '[email protected]', '[email protected]'],
  },
  filters: {
    filter1: TestFilterOne,
    filter2: TestFilterTwo,
    [RBAC_REQUEST_FILTER]: RequestFilter,
  },
};

Storage consists of the following keys:

roles: array of roles

permissions: objects of permissions which content actions

grants: objects of assigned permission to roles

filters: objects of customized behavior

Grant symbols

&: extends grant by another grant, for instance admin extends user (only support one level inheritance)

@: a particular action from permission, for instance [email protected]

Using RBAC like an unchangeable storage

import { Module } from '@nestjs/common';
import { RBAcModule } from 'nestjs-rbac';

@Module({
  imports: [
    RBAcModule.forRoot(IStorageRbac),
  ],
  controllers: []
})
export class AppModule {}

Using RBAC like a dynamic storage

There is enough to implement IDynamicStorageRbac interface.

import { Module } from '@nestjs/common';
import { RBAcModule } from 'nestjs-rbac';

@Module({
  imports: [
    RBAcModule.forDynamic(DynamicStorageService),
  ],
  controllers: []
})
export class AppModule {}
// implement dynamic storage
import { IDynamicStorageRbac, IStorageRbac } from 'nestjs-rbac';
@Injectable()
export class  DynamicStorageService implements IDynamicStorageRbac {
  constructor(
    private readonly repository: AnyRepository
  ) {

  }
  async getRbac(): Promise<IStorageRbac> {
//use any persistence storage for getting `RBAC`
      return  await this.repository.getRbac();
  }
}

Using for routers

import { RBAcPermissions, RBAcGuard } from 'nestjs-rbac';

@Controller()
export class RbacTestController {

  @RBAcPermissions('permission', '[email protected]')
  @UseGuards(
// Any Guard for getting & adding user to request which implements `IRole` interface from `nestjs-rbac`:
//*NOTE:
//  const request = context.switchToHttp().getRequest();
//  const user: IRole = request.user;
    GuardIsForAddingUserToRequestGuard,
    RBAcGuard,
  )
  @Get('/')
  async test1(): Promise<boolean> {
    return true;
  }
}

Using for a whole controller

It's applicable with the crud library, for example nestjsx/crud

import { RBAcPermissions, RBAcGuard } from 'nestjs-rbac';

@Crud({
	model: {
		type: Company,
	},
})
@RBAcPermissions('permission2')
@UseGuards(
		AuthGuard,
		RBAcGuard,
)
@Controller('companies')
export class CompaniesController implements CrudController<Company> {
	constructor(public service: CompaniesService) {}
}

one more example

@Crud({
	model: {
		type: Company,
	},
	routes: {
		getManyBase: {
			interceptors : [],
			decorators: [RBAcPermissions('permission1')],
		},
		createOneBase: {
			interceptors : [],
			decorators: [RBAcPermissions('permission2')],
		},
	},
})
@UseGuards(
		AuthGuard,
		RBAcGuard,
)
@Controller('companies')
export class CompaniesController implements CrudController<Company> {
	constructor(public service: CompaniesService) {
	}
}

Using like service

import { RbacService } from 'nestjs-rbac';

@Controller()
export class RbacTestController {

  constructor(
    private readonly rbac: RbacService
  ){}

  @Get('/')
  async test1(): Promise<boolean> {
    return await (await this.rbac.getRole(role)).can('permission', '[email protected]');
    return true;
  }
}

Using the custom filters

filter is a great opportunity of customising behaviour RBAC. For creating filter, there is need to implement IFilterPermission interface, which requires for implementing can method, and bind a key filter with filter implementation, like below:

export const RBAC: IStorageRbac = {
  roles: ['role'],
  permissions: {
    permission1: ['filter1', 'filter2'],
  },
  grants: {
    role: [
      `[email protected]`
      `[email protected]`
    ],
  },
  filters: {
    filter1: TestFilter,
    filter2: TestAsyncFilter,
  },
};
//===================== implementing filter
import { IFilterPermission } from 'nestjs-rbac';

export class TestFilter implements IFilterPermission {

  can(params?: any[]): boolean {
    return params[0];
  }

}

//===================== implementing async filter
import { IFilterPermission } from 'nestjs-rbac';

@Injectable()
export class TestAsyncFilter implements IFilterPermission {
  constructor(private readonly myService: MyService) {}

  async canAsync(params?: any[]): Promise<boolean> {
    const myResult = await this.myService.someAsyncOperation()
    // Do something with myResult
    return myResult;
  }
}

⚠️ - A single filter can implement both can and canAsync. If you use the RBAcGuard, they will be evaluated with an AND condition.

ParamsFilter services for passing arguments into particular filter:

const filter = new ParamsFilter();
filter.setParam('filter1', some payload);

const res = await (await rbacService.getRole('admin', filter)).can(
  '[email protected]',
);

Also RBAC has a default filter RBAC_REQUEST_FILTER which has request object as argument:

Example:
//===================== filter
export class RequestFilter implements IFilterPermission {

  can(params?: any[]): boolean {
    return params[0].headers['test-header'] === 'test';
  }
}
//===================== storage
export const RBAC: IStorageRbac = {
  roles: ['role'],
  permissions: {
    permission1: ['filter1', 'filter2', RBAC_REQUEST_FILTER],
  },
  grants: {
    role: [
      `[email protected]${RBAC_REQUEST_FILTER}`
    ],
  },
  filters: {
    [RBAC_REQUEST_FILTER]: RequestFilter,
  },
};
//===================== using for routes
  @RBAcPermissions(`[email protected]${RBAC_REQUEST_FILTER}`)
  @UseGuards(
    AuthGuard,
    RBAcGuard,
  )
  @Get('/')
  async test4(): Promise<boolean> {
    return true;
  }

Performance

By default, RBAC storage always parses grants for each request, in some cases, it can be a very expensive operation. The bigger RBAC storage, the more taking time for parsing. For saving performance RBAC has built-in a cache, based on node-cache

Using cache

import { RbacCache } from 'nestjs-rbac';

@Module({
  imports: [
    RBAcModule.useCache(RbacCache, {KEY: 'RBAC', TTL: 400}).forDynamic(AsyncService),
  ],
})

if you need to change a cache storage, there is enough to implement ICacheRBAC

ICacheRBAC

export interface ICacheRBAC {
  KEY: string;
  TTL: number;

  get(): object | null;

  /**
   *
   * @param value
   */
  set(value: object): void;

  del(): void;
}

Inject ICacheRBAC

import { ICacheRBAC } from 'nestjs-rbac';
...
@Inject('ICacheRBAC') cache: ICacheRBAC
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].