diff --git a/nest-cli.json b/nest-cli.json index 2edc9db..69ccf04 100644 --- a/nest-cli.json +++ b/nest-cli.json @@ -3,7 +3,11 @@ "sourceRoot": "src", "compilerOptions": { "assets": [ - "**/*.proto" + "**/*.proto", + { + "include": "i18n/**/*", + "watchAssets": true + } ], "plugins": [ "@nestjs/swagger" diff --git a/package-lock.json b/package-lock.json index 6126ab4..8e2c785 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,7 @@ "helmet": "^5.1.0", "jsonwebtoken": "^8.5.1", "jwk-to-pem": "^2.0.5", + "nestjs-i18n": "^9.1.3", "passport": "^0.6.0", "passport-facebook": "^3.0.0", "passport-forcedotcom": "^0.1.5", @@ -3467,6 +3468,11 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/accept-language-parser": { + "version": "1.5.0", + "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/accept-language-parser/-/accept-language-parser-1.5.0.tgz", + "integrity": "sha512-QhyTbMLYo0BBGg1aWbeMG4ekWtds/31BrEU+DONOg/7ax23vxpL03Pb7/zBmha2v7vdD3AyzZVWBVGEZxKOXWw==" + }, "node_modules/accepts": { "version": "1.3.8", "license": "MIT", @@ -3657,7 +3663,6 @@ }, "node_modules/anymatch": { "version": "3.1.2", - "dev": true, "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", @@ -3678,7 +3683,6 @@ }, "node_modules/argparse": { "version": "2.0.1", - "dev": true, "license": "Python-2.0" }, "node_modules/array-flatten": { @@ -3920,7 +3924,6 @@ }, "node_modules/binary-extensions": { "version": "2.2.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4006,7 +4009,6 @@ }, "node_modules/braces": { "version": "3.0.2", - "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.0.1" @@ -4195,7 +4197,6 @@ }, "node_modules/chokidar": { "version": "3.5.3", - "dev": true, "funding": [ { "type": "individual", @@ -4237,6 +4238,16 @@ "dev": true, "license": "MIT" }, + "node_modules/class-validator": { + "version": "0.13.2", + "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/class-validator/-/class-validator-0.13.2.tgz", + "integrity": "sha512-yBUcQy07FPlGzUjoLuUfIOXzgynnQPPruyK1Ge2B74k9ROwnle1E+NxLWnUv5OLU8hA/qL5leAE9XnXq3byaBw==", + "peer": true, + "dependencies": { + "libphonenumber-js": "^1.9.43", + "validator": "^13.7.0" + } + }, "node_modules/cli-cursor": { "version": "3.1.0", "dev": true, @@ -5707,7 +5718,6 @@ }, "node_modules/fill-range": { "version": "7.0.1", - "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -6041,7 +6051,6 @@ }, "node_modules/glob-parent": { "version": "5.1.2", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -6455,7 +6464,6 @@ }, "node_modules/is-binary-path": { "version": "2.1.0", - "dev": true, "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" @@ -6516,7 +6524,6 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -6550,7 +6557,6 @@ }, "node_modules/is-glob": { "version": "4.0.3", - "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -6602,7 +6608,6 @@ }, "node_modules/is-number": { "version": "7.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -7625,7 +7630,6 @@ }, "node_modules/js-yaml": { "version": "4.1.0", - "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -7823,6 +7827,12 @@ "node": ">= 0.8.0" } }, + "node_modules/libphonenumber-js": { + "version": "1.10.7", + "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/libphonenumber-js/-/libphonenumber-js-1.10.7.tgz", + "integrity": "sha512-jZXLCCWMe1b/HXkjiLeYt2JsytZMcqH26jLFIdzFDFF0xvSUWrYKyvPlyPG+XJzEyKUFbcZxLdWGMwQsWaHDxQ==", + "peer": true + }, "node_modules/lines-and-columns": { "version": "1.2.4", "dev": true, @@ -8239,6 +8249,33 @@ "dev": true, "license": "MIT" }, + "node_modules/nestjs-i18n": { + "version": "9.1.3", + "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/nestjs-i18n/-/nestjs-i18n-9.1.3.tgz", + "integrity": "sha512-55hLPenqoHq7sNybxjHoe6Q+RjeZelmaCnCx/niT28GvCLPUteNO4jOe/4AWvLvLrnW0cj7l0sHHzgXlPTilfg==", + "dependencies": { + "accept-language-parser": "^1.5.0", + "chokidar": "^3.5.3", + "cookie": "^0.4.1", + "iterare": "^1.2.1", + "js-yaml": "^4.1.0", + "string-format": "^2.0.0" + }, + "peerDependencies": { + "@nestjs/common": "*", + "@nestjs/core": "*", + "class-validator": "~0.13", + "rxjs": "*" + } + }, + "node_modules/nestjs-i18n/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/next-line": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-line/-/next-line-1.1.0.tgz", @@ -8313,7 +8350,6 @@ }, "node_modules/normalize-path": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -8812,7 +8848,6 @@ }, "node_modules/picomatch": { "version": "2.3.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -9132,7 +9167,6 @@ }, "node_modules/readdirp": { "version": "3.6.0", - "dev": true, "license": "MIT", "dependencies": { "picomatch": "^2.2.1" @@ -9716,6 +9750,11 @@ "version": "5.1.2", "license": "MIT" }, + "node_modules/string-format": { + "version": "2.0.0", + "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/string-format/-/string-format-2.0.0.tgz", + "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==" + }, "node_modules/string-length": { "version": "4.0.2", "dev": true, @@ -10087,7 +10126,6 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", - "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -10570,6 +10608,15 @@ "node": ">=10.12.0" } }, + "node_modules/validator": { + "version": "13.7.0", + "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", + "peer": true, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "license": "MIT", @@ -13458,6 +13505,11 @@ "version": "2.0.6", "dev": true }, + "accept-language-parser": { + "version": "1.5.0", + "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/accept-language-parser/-/accept-language-parser-1.5.0.tgz", + "integrity": "sha512-QhyTbMLYo0BBGg1aWbeMG4ekWtds/31BrEU+DONOg/7ax23vxpL03Pb7/zBmha2v7vdD3AyzZVWBVGEZxKOXWw==" + }, "accepts": { "version": "1.3.8", "requires": { @@ -13573,7 +13625,6 @@ }, "anymatch": { "version": "3.1.2", - "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -13587,8 +13638,7 @@ "dev": true }, "argparse": { - "version": "2.0.1", - "dev": true + "version": "2.0.1" }, "array-flatten": { "version": "1.1.1" @@ -13767,8 +13817,7 @@ } }, "binary-extensions": { - "version": "2.2.0", - "dev": true + "version": "2.2.0" }, "binary-search": { "version": "1.3.6", @@ -13840,7 +13889,6 @@ }, "braces": { "version": "3.0.2", - "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -13945,7 +13993,6 @@ }, "chokidar": { "version": "3.5.3", - "dev": true, "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -13969,6 +14016,16 @@ "version": "1.2.2", "dev": true }, + "class-validator": { + "version": "0.13.2", + "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/class-validator/-/class-validator-0.13.2.tgz", + "integrity": "sha512-yBUcQy07FPlGzUjoLuUfIOXzgynnQPPruyK1Ge2B74k9ROwnle1E+NxLWnUv5OLU8hA/qL5leAE9XnXq3byaBw==", + "peer": true, + "requires": { + "libphonenumber-js": "^1.9.43", + "validator": "^13.7.0" + } + }, "cli-cursor": { "version": "3.1.0", "dev": true, @@ -15010,7 +15067,6 @@ }, "fill-range": { "version": "7.0.1", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -15218,7 +15274,6 @@ }, "glob-parent": { "version": "5.1.2", - "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -15480,7 +15535,6 @@ }, "is-binary-path": { "version": "2.1.0", - "dev": true, "requires": { "binary-extensions": "^2.0.0" } @@ -15514,8 +15568,7 @@ } }, "is-extglob": { - "version": "2.1.1", - "dev": true + "version": "2.1.1" }, "is-finite": { "version": "1.1.0", @@ -15531,7 +15584,6 @@ }, "is-glob": { "version": "4.0.3", - "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -15568,8 +15620,7 @@ "integrity": "sha512-m2Rm8PhUFDNNhgvwZJjJG74a9h5CHU0fkA8WT+WGlCjyEbZ2jPwgb+ZxHu4np284EqNVyOsgppReK4qy/TwEwg==" }, "is-number": { - "version": "7.0.0", - "dev": true + "version": "7.0.0" }, "is-number-object": { "version": "1.0.7", @@ -16269,7 +16320,6 @@ }, "js-yaml": { "version": "4.1.0", - "dev": true, "requires": { "argparse": "^2.0.1" } @@ -16407,6 +16457,12 @@ "type-check": "~0.4.0" } }, + "libphonenumber-js": { + "version": "1.10.7", + "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/libphonenumber-js/-/libphonenumber-js-1.10.7.tgz", + "integrity": "sha512-jZXLCCWMe1b/HXkjiLeYt2JsytZMcqH26jLFIdzFDFF0xvSUWrYKyvPlyPG+XJzEyKUFbcZxLdWGMwQsWaHDxQ==", + "peer": true + }, "lines-and-columns": { "version": "1.2.4", "dev": true @@ -16688,6 +16744,26 @@ "version": "2.6.2", "dev": true }, + "nestjs-i18n": { + "version": "9.1.3", + "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/nestjs-i18n/-/nestjs-i18n-9.1.3.tgz", + "integrity": "sha512-55hLPenqoHq7sNybxjHoe6Q+RjeZelmaCnCx/niT28GvCLPUteNO4jOe/4AWvLvLrnW0cj7l0sHHzgXlPTilfg==", + "requires": { + "accept-language-parser": "^1.5.0", + "chokidar": "^3.5.3", + "cookie": "^0.4.1", + "iterare": "^1.2.1", + "js-yaml": "^4.1.0", + "string-format": "^2.0.0" + }, + "dependencies": { + "cookie": { + "version": "0.4.2", + "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + } + } + }, "next-line": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-line/-/next-line-1.1.0.tgz", @@ -16742,8 +16818,7 @@ "dev": true }, "normalize-path": { - "version": "3.0.0", - "dev": true + "version": "3.0.0" }, "npm-run-path": { "version": "4.0.1", @@ -17078,8 +17153,7 @@ "dev": true }, "picomatch": { - "version": "2.3.1", - "dev": true + "version": "2.3.1" }, "pino": { "version": "6.14.0", @@ -17292,7 +17366,6 @@ }, "readdirp": { "version": "3.6.0", - "dev": true, "requires": { "picomatch": "^2.2.1" } @@ -17689,6 +17762,11 @@ } } }, + "string-format": { + "version": "2.0.0", + "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/string-format/-/string-format-2.0.0.tgz", + "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==" + }, "string-length": { "version": "4.0.2", "dev": true, @@ -17923,7 +18001,6 @@ }, "to-regex-range": { "version": "5.0.1", - "dev": true, "requires": { "is-number": "^7.0.0" } @@ -18241,6 +18318,12 @@ "source-map": "^0.7.3" } }, + "validator": { + "version": "13.7.0", + "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", + "peer": true + }, "vary": { "version": "1.1.2" }, diff --git a/package.json b/package.json index c3e5c80..4b3c251 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "helmet": "^5.1.0", "jsonwebtoken": "^8.5.1", "jwk-to-pem": "^2.0.5", + "nestjs-i18n": "^9.1.3", "passport": "^0.6.0", "passport-facebook": "^3.0.0", "passport-forcedotcom": "^0.1.5", diff --git a/src/app.module.ts b/src/app.module.ts index d643c3e..aa062b3 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -41,6 +41,7 @@ import { ConnectorClientConfiguration } from './clients/connector/client.config' import { ConnectorController } from './modules/connector/connector.controller'; import { ConnectorClientService } from './clients/connector/client.service'; import { UsersModule } from './modules/users/users.module'; +import { RolesModule } from './modules/roles/roles.module'; const inputClient = new InputsClientConfiguration(); const outputClient = new OutputsClientConfiguration(); @@ -114,6 +115,8 @@ const connectorClient = new ConnectorClientConfiguration(); ]), UsersModule, + + RolesModule, ], }) export class AppModule {} diff --git a/src/authentication/permissions.enum.ts b/src/authentication/permissions.enum.ts index 2c8a47d..0dc0b2a 100644 --- a/src/authentication/permissions.enum.ts +++ b/src/authentication/permissions.enum.ts @@ -12,6 +12,7 @@ export interface Permission { seqid: number; claim: string; usage: PermissionUsages; + name?: string; } /* @@ -22,7 +23,7 @@ export interface Permission { /*export const Permissions: { [P in keyof any]: { [Q in keyof any]: Permission }; } = {*/ -export const Permissions = { +export const Permissions: Record> = { AUTH: { CREATE: { seqid: 18, @@ -34,23 +35,27 @@ export const Permissions = { PIPELINE: { CREATE: { seqid: 23, - claim: 'POST /pipelines', + claim: 'pipeline:create', usage: PermissionUsages.PUBLIC, + name: 'PERMISSIONS.NAMES.PIPELINE_CREATE', }, GET: { seqid: 13, - claim: 'GET /pipelines', + claim: 'pipeline:get', usage: PermissionUsages.PUBLIC, + name: 'PERMISSIONS.NAMES.PIPELINE_GET', }, UPDATE: { seqid: 29, - claim: 'PUT /pipelines', + claim: 'pipeline:update', usage: PermissionUsages.PUBLIC, + name: 'PERMISSIONS.NAMES.PIPELINE_PUT', }, DELETE: { seqid: 5, - claim: 'DELETE /pipelines', + claim: 'pipeline:delete', usage: PermissionUsages.PUBLIC, + name: 'PERMISSIONS.NAMES.PIPELINE_DELETE', }, }, @@ -59,21 +64,25 @@ export const Permissions = { seqid: 21, claim: 'POST /inputs', usage: PermissionUsages.PUBLIC, + name: 'Criar conexões', }, GET: { seqid: 9, claim: 'GET /inputs', usage: PermissionUsages.PUBLIC, + name: 'Buscar conexões', }, UPDATE: { seqid: 27, claim: 'PUT /inputs', usage: PermissionUsages.PUBLIC, + name: 'Atualizar conexões', }, UPDATE_PARTIAL: { seqid: 17, claim: 'PATCH /inputs', usage: PermissionUsages.PUBLIC, + name: 'Atualizar conexões', }, DELETE: { seqid: 3, diff --git a/src/i18n/pt/messages.json b/src/i18n/pt/messages.json new file mode 100644 index 0000000..dc5f042 --- /dev/null +++ b/src/i18n/pt/messages.json @@ -0,0 +1,11 @@ +{ + "ERRORS": {}, + "PERMISSIONS": { + "NAMES": { + "PIPELINE_CREATE": "Criar pipeline", + "PIPELINE_GET": "Buscar pipelines", + "PIPELINE_PUT": "Atualizar pipeline", + "PIPELINE_DELETE": "Excluir pipeline" + } + } +} \ No newline at end of file diff --git a/src/modules/permissions/permissions.controller.spec.ts b/src/modules/permissions/permissions.controller.spec.ts new file mode 100644 index 0000000..3da89aa --- /dev/null +++ b/src/modules/permissions/permissions.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { PermissionsController } from './permissions.controller'; + +describe('PermissionsController', () => { + let controller: PermissionsController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [PermissionsController], + }).compile(); + + controller = module.get(PermissionsController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/modules/permissions/permissions.controller.ts b/src/modules/permissions/permissions.controller.ts new file mode 100644 index 0000000..2be94c4 --- /dev/null +++ b/src/modules/permissions/permissions.controller.ts @@ -0,0 +1,23 @@ +import { Controller, Get, Inject } from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; +import { DadosferaLogger } from 'dadosfera-logs'; +import { User } from 'src/authentication/user.decorator'; +import { PermissionsClientService } from './permissions.service'; + +@ApiTags('Permissions') +@Controller('permissions') +export class PermissionsController { + logger: any; + + constructor( + @Inject(DadosferaLogger) + dadosferaLogger: DadosferaLogger, + private permissionsService: PermissionsClientService, + ) { + this.logger = dadosferaLogger.logger; + } + @Get() + getPublicPermissions(@User() user) { + this.logger.info('getPublicPermissions', { user }); + } +} diff --git a/src/modules/permissions/permissions.module.ts b/src/modules/permissions/permissions.module.ts index f390558..3dca762 100644 --- a/src/modules/permissions/permissions.module.ts +++ b/src/modules/permissions/permissions.module.ts @@ -5,6 +5,7 @@ import { DadosferaLogger } from 'dadosfera-logs'; import { PermissionsClientService } from './permissions.service'; import { DucClient } from '../../clients/duc/client.config'; +import { PermissionsController } from './permissions.controller'; const ducClient = new DucClient(); @Module({ @@ -17,5 +18,6 @@ const ducClient = new DucClient(); ]), ], providers: [PermissionsClientService, DadosferaLogger], + controllers: [PermissionsController], }) export class PermissionsModule {} diff --git a/src/modules/roles/dto/entities.ts b/src/modules/roles/dto/entities.ts new file mode 100644 index 0000000..65eebcc --- /dev/null +++ b/src/modules/roles/dto/entities.ts @@ -0,0 +1,58 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; + +export class Permission { + @ApiProperty() + id: string; + @ApiProperty() + seqid: number; + @ApiProperty() + name: string; + @ApiProperty() + claim: string; + @ApiProperty() + createdAt: string; + @ApiProperty() + updatedAt: string; +} +export class Role { + @ApiPropertyOptional({ type: [Permission] }) + permissions: Permission[]; + @ApiProperty() + id: string; + @ApiProperty() + name: string; + @ApiProperty() + createdAt: string; + @ApiProperty() + updatedAt: string; +} + +export enum TrueOrFalseEnum { + true = 'true', + false = 'false', +} +export class GetRolesByCustomerReq { + @ApiPropertyOptional() + permission_id: string[]; + @ApiPropertyOptional({ enum: TrueOrFalseEnum }) + get_users: TrueOrFalseEnum; +} + +export class GetRolesByCustomerRes { + @ApiProperty({ type: [Role] }) + roles: Role[]; +} +export class CreateRoleReq { + @ApiProperty() + name: string; + @ApiProperty() + permissionIds: string[]; + @ApiProperty() + userIds: string[]; + @ApiProperty() + customerId: string; +} +export class CreateRoleRes { + @ApiProperty({ type: [Role] }) + roles: Role[]; +} diff --git a/src/modules/roles/roles.controller.spec.ts b/src/modules/roles/roles.controller.spec.ts new file mode 100644 index 0000000..79260d6 --- /dev/null +++ b/src/modules/roles/roles.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { RolesController } from './roles.controller'; + +describe('RolesController', () => { + let controller: RolesController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [RolesController], + }).compile(); + + controller = module.get(RolesController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/modules/roles/roles.controller.ts b/src/modules/roles/roles.controller.ts new file mode 100644 index 0000000..13fe6b6 --- /dev/null +++ b/src/modules/roles/roles.controller.ts @@ -0,0 +1,53 @@ +import { + Body, + Controller, + Delete, + Get, + Inject, + Param, + Post, + Query, +} from '@nestjs/common'; +import { ApiResponse, ApiTags } from '@nestjs/swagger'; +import { User } from 'src/authentication/user.decorator'; +import { DadosferaLogger } from 'dadosfera-logs'; +import { RolesService } from './roles.service'; +import { + CreateRoleReq, + CreateRoleRes, + GetRolesByCustomerReq, + GetRolesByCustomerRes, +} from './dto/entities'; + +@ApiTags('Roles') +@Controller('roles') +export class RolesController { + logger: any; + + constructor( + @Inject(DadosferaLogger) + dadosferaLogger: DadosferaLogger, + private rolesService: RolesService, + ) { + this.logger = dadosferaLogger.logger; + } + @Get() + @ApiResponse({ type: GetRolesByCustomerRes }) + async getRolesByCustomer( + @User() user, + @Query() filters: GetRolesByCustomerReq, + ) { + this.logger.info('getRolesByCustomer', { user }); + this.rolesService.getRolesByCustomer(filters); + } + @Post() + @ApiResponse({ type: CreateRoleRes }) + async createRole(@User() user, @Body() body: CreateRoleReq) { + this.logger.info('createRole', { user }); + } + @Delete(':id') + async deleteRole(@User() user, @Param('id') id: string) { + this.logger.info('deleteRole', { user }); + return await this.rolesService.removeRole(id); + } +} diff --git a/src/modules/roles/roles.module.ts b/src/modules/roles/roles.module.ts new file mode 100644 index 0000000..4e3bec6 --- /dev/null +++ b/src/modules/roles/roles.module.ts @@ -0,0 +1,22 @@ +import { Module } from '@nestjs/common'; +import { ClientsModule } from '@nestjs/microservices'; +import { DucClient } from 'src/clients/duc/client.config'; +import { RolesController } from './roles.controller'; +import { RolesService } from './roles.service'; +import { DadosferaLogger } from 'dadosfera-logs'; + +const ducClient = new DucClient(); + +@Module({ + imports: [ + ClientsModule.register([ + { + name: 'DUC_PACKAGE', + ...ducClient.config(), + }, + ]), + ], + controllers: [RolesController], + providers: [RolesService, DadosferaLogger], +}) +export class RolesModule {} diff --git a/src/modules/roles/roles.service.spec.ts b/src/modules/roles/roles.service.spec.ts new file mode 100644 index 0000000..058d35f --- /dev/null +++ b/src/modules/roles/roles.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { RolesService } from './roles.service'; + +describe('RolesService', () => { + let service: RolesService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [RolesService], + }).compile(); + + service = module.get(RolesService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/modules/roles/roles.service.ts b/src/modules/roles/roles.service.ts new file mode 100644 index 0000000..5b64d32 --- /dev/null +++ b/src/modules/roles/roles.service.ts @@ -0,0 +1,36 @@ +import { Inject, Injectable } from '@nestjs/common'; +import { ProtoServices } from 'protospack-v2/dist/lib/Duc'; +import { RolesProtoService } from 'protospack-v2/dist/lib/Duc/interfaces/write-service'; +import { GetRolesByCustomerReq } from './dto/entities'; +import { DadosferaLogger } from 'dadosfera-logs'; +import { ClientGrpc } from '@nestjs/microservices'; +import { lastValueFrom } from 'rxjs'; + +@Injectable() +export class RolesService { + logger: any; + + private rolesClientService: RolesProtoService; + constructor( + @Inject(DadosferaLogger) + dadosferaLogger: DadosferaLogger, + @Inject('DUC_PACKAGE') private readonly grpcClient: ClientGrpc, + ) { + this.logger = dadosferaLogger.logger; + } + + onModuleInit() { + this.rolesClientService = this.grpcClient.getService( + ProtoServices.UsersProtoService, + ); + } + async getRolesByCustomer(filters: GetRolesByCustomerReq) { + let { permission_id } = filters; + if (!Array.isArray(permission_id)) permission_id = [permission_id]; + const { get_users } = filters; + const is_get_users = get_users === 'true'; + } + async removeRole(id: string) { + return lastValueFrom(this.rolesClientService.RoleRemove({ id })); + } +} diff --git a/src/modules/users/dtos/entities.ts b/src/modules/users/dtos/entities.ts index b6d4420..5a07fac 100644 --- a/src/modules/users/dtos/entities.ts +++ b/src/modules/users/dtos/entities.ts @@ -1,4 +1,5 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { Role } from 'src/modules/roles/dto/entities'; export class Customer { @ApiProperty() id: string; @@ -15,28 +16,26 @@ export class Customer { @ApiProperty() updatedAt: string; } -export class Permission { - @ApiProperty() - id: string; - @ApiProperty() - seqid: number; - @ApiProperty() - name: string; - @ApiProperty() - claim: string; - @ApiProperty() - createdAt: string; - @ApiProperty() - updatedAt: string; -} -export class Role { - @ApiProperty({ type: [Permission] }) - permissions: Permission[]; +export class User { @ApiProperty() id: string; @ApiProperty() name: string; @ApiProperty() + email: string; + @ApiProperty({ type: [Role] }) + roles: Role[]; + @ApiProperty() + jobTitle: string; + @ApiProperty() + department: string; + @ApiProperty() + hierarchy: number; + @ApiProperty() + customer: Customer; + @ApiProperty() + mfaStatus: string; + @ApiProperty() createdAt: string; @ApiProperty() updatedAt: string; @@ -57,61 +56,31 @@ export class UserByCustomer { @ApiProperty() updatedAt: string; } -export class User { - @ApiProperty() - id: string; - @ApiProperty() - name: string; - @ApiProperty() - username: string; - @ApiProperty() - UserRole: string[]; - @ApiProperty() - customer: Customer; - @ApiProperty() - mfaStatus: string; - @ApiProperty() - createdAt: string; - @ApiProperty() - updatedAt: string; -} export class CreateUserReq { - @ApiProperty() + @ApiPropertyOptional() name: string; @ApiProperty() email: string; - @ApiProperty() + @ApiPropertyOptional() roles: string[]; - @ApiProperty() + @ApiPropertyOptional() jobTitle: string; - @ApiProperty() + @ApiPropertyOptional() department: string; - @ApiProperty() + @ApiPropertyOptional() hierarchy: number; } export class CreateUserRes { @ApiProperty() - id: string; - @ApiProperty() - name: string; - @ApiProperty() - email: string; - @ApiProperty() - roles: string[]; - @ApiProperty() - jobTitle: string; - @ApiProperty() - department: string; - @ApiProperty() - hierarchy: number; - @ApiProperty() - customer: Customer; - @ApiProperty() - mfaStatus: string; - @ApiProperty() - createdAt: string; - @ApiProperty() - updatedAt: string; + user: User; +} +export class BatchCreateUserReq { + @ApiProperty({ type: [CreateUserReq] }) + users: CreateUserReq[]; +} +export class BatchCreateUserRes { + @ApiProperty({ type: [User] }) + users: User[]; } export class GetAllUsersByCustomerIdReq { diff --git a/src/modules/users/users.controller.ts b/src/modules/users/users.controller.ts index 0871659..a2c2507 100644 --- a/src/modules/users/users.controller.ts +++ b/src/modules/users/users.controller.ts @@ -39,9 +39,14 @@ export class UsersController { @Post() @ApiOkResponse({ type: CreateUserRes }) async createUser(@User() user, @Body() body: CreateUserReq) { - console.log(body); + this.logger.info('createUser', { user }); } + @Post('batch') + @ApiOkResponse({ type: CreateUserRes }) + async batchCreateUser(@User() user, @Body() body: CreateUserReq) { + this.logger.info('batchCreateUser', { user }); + } @Delete(':id') @ApiOkResponse({ type: DeleteUserRes }) async deleteUser(@User() user, @Param('id') id: string) { diff --git a/src/modules/users/users.module.ts b/src/modules/users/users.module.ts index 8ee1859..87b5a5d 100644 --- a/src/modules/users/users.module.ts +++ b/src/modules/users/users.module.ts @@ -4,6 +4,7 @@ import { UsersService } from './users.service'; import { DadosferaLogger } from 'dadosfera-logs'; import { ClientsModule } from '@nestjs/microservices'; import { DucClient } from 'src/clients/duc/client.config'; + const ducClient = new DucClient(); @Module({