From 4356adea65572953d1d260d47808ffff698129c9 Mon Sep 17 00:00:00 2001 From: Gabriel Rosa Date: Thu, 7 Jul 2022 15:57:40 -0300 Subject: [PATCH] FEAT: User module init --- src/app.module.ts | 3 + src/modules/users/dtos/entities.ts | 105 +++++++++++++++++++++ src/modules/users/users.controller.spec.ts | 18 ++++ src/modules/users/users.controller.ts | 68 +++++++++++++ src/modules/users/users.module.ts | 21 +++++ src/modules/users/users.service.spec.ts | 18 ++++ src/modules/users/users.service.ts | 53 +++++++++++ 7 files changed, 286 insertions(+) create mode 100644 src/modules/users/dtos/entities.ts create mode 100644 src/modules/users/users.controller.spec.ts create mode 100644 src/modules/users/users.controller.ts create mode 100644 src/modules/users/users.module.ts create mode 100644 src/modules/users/users.service.spec.ts create mode 100644 src/modules/users/users.service.ts diff --git a/src/app.module.ts b/src/app.module.ts index 5653cf5..d643c3e 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -40,6 +40,7 @@ import { SalesforceStrategy } from './modules/oauth/passport-strategies/salesfor 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'; const inputClient = new InputsClientConfiguration(); const outputClient = new OutputsClientConfiguration(); @@ -111,6 +112,8 @@ const connectorClient = new ConnectorClientConfiguration(); ...connectorClient.config(), }, ]), + + UsersModule, ], }) export class AppModule {} diff --git a/src/modules/users/dtos/entities.ts b/src/modules/users/dtos/entities.ts new file mode 100644 index 0000000..ef8fd41 --- /dev/null +++ b/src/modules/users/dtos/entities.ts @@ -0,0 +1,105 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +export class Customer { + @ApiProperty() + id: string; + @ApiProperty() + name: string; + @ApiProperty() + domain: string; + @ApiProperty() + tier: string; + @ApiProperty() + info: string; + @ApiProperty() + createdAt: string; + @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[]; + @ApiProperty() + id: string; + @ApiProperty() + name: string; + @ApiProperty() + createdAt: string; + @ApiProperty() + updatedAt: string; +} +export class UserByCustomer { + @ApiProperty({ type: [Role] }) + roles: Role[]; + @ApiProperty() + id: string; + @ApiProperty() + name: string; + @ApiProperty() + username: string; + @ApiProperty() + mfaStatus: string; + @ApiProperty() + createdAt: string; + @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 GetAllUsersByCustomerIdReq { + @ApiPropertyOptional() + s: string; +} +export class GetAllUsersByCustomerIdRes { + @ApiProperty({ type: [UserByCustomer] }) + users: UserByCustomer[]; +} + +export class AssignRoleToUserReq { + @ApiProperty() + userId: string; + @ApiProperty() + roleId: string; +} +export class UnassignRoleToUserReq { + @ApiProperty() + userId: string; + @ApiProperty() + roleId: string; +} + +export class SearchUserReq { + @ApiProperty() + s: string; +} +export class SearchUserRes extends GetAllUsersByCustomerIdRes {} diff --git a/src/modules/users/users.controller.spec.ts b/src/modules/users/users.controller.spec.ts new file mode 100644 index 0000000..3e27c39 --- /dev/null +++ b/src/modules/users/users.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { UsersController } from './users.controller'; + +describe('UsersController', () => { + let controller: UsersController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [UsersController], + }).compile(); + + controller = module.get(UsersController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/modules/users/users.controller.ts b/src/modules/users/users.controller.ts new file mode 100644 index 0000000..c6e2e98 --- /dev/null +++ b/src/modules/users/users.controller.ts @@ -0,0 +1,68 @@ +import { + Body, + Controller, + Delete, + Get, + Inject, + Put, + Query, +} from '@nestjs/common'; +import { ApiOkResponse, ApiTags } from '@nestjs/swagger'; +import { DadosferaLogger } from 'dadosfera-logs'; +import { RequestUser, User } from 'src/authentication/user.decorator'; +import { + AssignRoleToUserReq, + GetAllUsersByCustomerIdReq, + GetAllUsersByCustomerIdRes, + UnassignRoleToUserReq, +} from './dtos/entities'; +import { UsersService } from './users.service'; + +@ApiTags('Users') +@Controller('users') +export class UsersController { + logger: any; + + constructor( + @Inject(DadosferaLogger) + dadosferaLogger: DadosferaLogger, + private userService: UsersService, + ) { + this.logger = dadosferaLogger.logger; + } + + @Get() + @ApiOkResponse({ + type: GetAllUsersByCustomerIdRes, + description: 'List of users of a customer', + }) + async getAllUsersByCustomerId( + @User() user: RequestUser, + @Query('s') s: GetAllUsersByCustomerIdReq, + ) { + this.logger.info('getAllUsersByCustomerId', { user }); + return await this.userService.findAllUsersByCustomerId(user.customer_id, s); + } + + @Put('role') + async assignRoleToUser(@User() user, @Body() body: AssignRoleToUserReq) { + this.logger.info('assignRoleToUser', { user }); + return await this.userService.assignRoleToUser(body); + } + + @Delete('role') + async unassignRoleToUser(@User() user, @Body() body: UnassignRoleToUserReq) { + this.logger.info('unassignRoleToUser', { user }); + return await this.userService.unassignRoleToUser(body); + } + + // @Get('search') + // @ApiOkResponse({ type: SearchUserRes }) + // async searchUser( + // @User() user: RequestUser, + // @Query('s') searchQuery: SearchUserReq, + // ) { + // this.logger.info('searchUser', { user }); + // console.log(searchQuery); + // } +} diff --git a/src/modules/users/users.module.ts b/src/modules/users/users.module.ts new file mode 100644 index 0000000..8ee1859 --- /dev/null +++ b/src/modules/users/users.module.ts @@ -0,0 +1,21 @@ +import { Module } from '@nestjs/common'; +import { UsersController } from './users.controller'; +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({ + imports: [ + ClientsModule.register([ + { + name: 'DUC_PACKAGE', + ...ducClient.config(), + }, + ]), + ], + controllers: [UsersController], + providers: [UsersService, DadosferaLogger], +}) +export class UsersModule {} diff --git a/src/modules/users/users.service.spec.ts b/src/modules/users/users.service.spec.ts new file mode 100644 index 0000000..62815ba --- /dev/null +++ b/src/modules/users/users.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { UsersService } from './users.service'; + +describe('UsersService', () => { + let service: UsersService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [UsersService], + }).compile(); + + service = module.get(UsersService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/modules/users/users.service.ts b/src/modules/users/users.service.ts new file mode 100644 index 0000000..63a4a8c --- /dev/null +++ b/src/modules/users/users.service.ts @@ -0,0 +1,53 @@ +import { OnModuleInit, Inject, Injectable } from '@nestjs/common'; +import { ClientGrpc } from '@nestjs/microservices'; +import { DadosferaLogger } from 'dadosfera-logs'; + +import { ProtoServices } from 'protospack-v2/dist/lib/Duc'; +import { UsersProtoService } from 'protospack-v2/dist/lib/Duc/interfaces/write-service'; +import { + AssignRoleToUserRequest, + AssignRoleToUserResponse, + UnassignRoleFromUserRequest, + UnassignRoleFromUserResponse, + UserFindAllByCustomerIdResponse, +} from 'protospack-v2/dist/lib/Duc/interfaces/messages'; + +import grpcHandler from '../../utils/grpcHandler'; + +@Injectable() +export class UsersService implements OnModuleInit { + logger: any; + + private usersService: UsersProtoService; + constructor( + @Inject(DadosferaLogger) + dadosferaLogger: DadosferaLogger, + @Inject('DUC_PACKAGE') private readonly grpcClient: ClientGrpc, + ) { + this.logger = dadosferaLogger.logger; + } + + onModuleInit() { + this.usersService = this.grpcClient.getService( + ProtoServices.UsersProtoService, + ); + } + + async findAllUsersByCustomerId(customerId, searchQuery) { + return grpcHandler( + this.usersService.UserFindAllByCustomerId({ customerId }), + ); + } + + async assignRoleToUser(body: AssignRoleToUserRequest) { + return grpcHandler( + this.usersService.AssignRoleToUser(body), + ); + } + + async unassignRoleToUser(body: UnassignRoleFromUserRequest) { + return grpcHandler( + this.usersService.UnassignRoleFromUser(body), + ); + } +}