diff --git a/package-lock.json b/package-lock.json index abb1638..4e0f471 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9017,7 +9017,7 @@ "node_modules/protospack-v2": { "version": "0.0.0", "resolved": "file:../protospack-v2/protospack-v2-0.0.0.tgz", - "integrity": "sha512-tT+tkBmv9rQlWS6kX/NqVCBZfMsSe7aym2sENQqaMKPGMD1yKR2BI5fvn9Oq3D7wTF0BFNxXHIz4CkmNwdp/OQ==", + "integrity": "sha512-S0CjzM2xctP6b2eJuelF802FkrndD+UA/ghSaLunTfw+my0yNtXZLxLbAC+0pphAZTkFrvWg3TdP4KIRA+59cA==", "license": "ISC", "dependencies": { "@grpc/grpc-js": "^1.6.7", @@ -17247,7 +17247,7 @@ }, "protospack-v2": { "version": "file:../protospack-v2/protospack-v2-0.0.0.tgz", - "integrity": "sha512-tT+tkBmv9rQlWS6kX/NqVCBZfMsSe7aym2sENQqaMKPGMD1yKR2BI5fvn9Oq3D7wTF0BFNxXHIz4CkmNwdp/OQ==", + "integrity": "sha512-S0CjzM2xctP6b2eJuelF802FkrndD+UA/ghSaLunTfw+my0yNtXZLxLbAC+0pphAZTkFrvWg3TdP4KIRA+59cA==", "requires": { "@grpc/grpc-js": "^1.6.7", "rxjs": "^7.5.5", diff --git a/src/modules/permissions/dto/entities.ts b/src/modules/permissions/dto/entities.ts index f4dc174..faa4a3b 100644 --- a/src/modules/permissions/dto/entities.ts +++ b/src/modules/permissions/dto/entities.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; -export class PermissionDto { +export class PermissionGroupPermission { @ApiProperty() name: string; @ApiProperty() @@ -10,8 +10,8 @@ export class PermissionDto { export class PermissionGroup { @ApiProperty() title: string; - @ApiProperty({ type: [PermissionDto] }) - permissions: PermissionDto[]; + @ApiProperty({ type: [PermissionGroupPermission] }) + permissions: PermissionGroupPermission[]; } export class Permission { @@ -29,6 +29,20 @@ export class Permission { updatedAt: string; } +export class PermissionDto { + @ApiProperty() + id: number; + @ApiProperty() + seqid: number; + @ApiProperty() + name: string; + @ApiProperty() + claim: string; + @ApiProperty() + createdAt: string; + @ApiProperty() + updatedAt: string; +} export class GetPublicPermissionsRes { @ApiProperty({ type: [PermissionGroup] }) permissionGroups: PermissionGroup[]; diff --git a/src/modules/permissions/permissions.service.ts b/src/modules/permissions/permissions.service.ts index 58b75e2..1344299 100644 --- a/src/modules/permissions/permissions.service.ts +++ b/src/modules/permissions/permissions.service.ts @@ -19,7 +19,7 @@ import { LanguageEnum, } from '../../authentication/permissions.enum'; import ErrorBuilder from '../../utils/ErrorBuilder'; -import { PermissionDto, PermissionGroup } from './dto/entities'; +import { PermissionGroupPermission, PermissionGroup } from './dto/entities'; @Injectable() export class PermissionsService @@ -82,7 +82,7 @@ export class PermissionsService for (const key in PERMISSIONS) { const permissionGroup: PermissionsObjectGroup = PERMISSIONS[key]; const title = permissionGroup.title[language]; - const permissions: PermissionDto[] = Object.values( + const permissions: PermissionGroupPermission[] = Object.values( permissionGroup.permissions, ) .filter(({ usage }) => diff --git a/src/modules/roles/dto/entities.ts b/src/modules/roles/dto/entities.ts index 74b8de5..275896e 100644 --- a/src/modules/roles/dto/entities.ts +++ b/src/modules/roles/dto/entities.ts @@ -14,7 +14,7 @@ export class RoleDto { @ApiPropertyOptional({ type: () => [PermissionDto] }) permissions: PermissionDto[]; @ApiPropertyOptional({ type: () => [UserNoRolesAndCustomer] }) - users: UserNoRolesAndCustomer[]; + users?: UserNoRolesAndCustomer[]; @ApiProperty() createdAt: string; @ApiProperty() @@ -24,6 +24,7 @@ export class RoleDto { } export class CustomerRole extends OmitType(RoleDto, ['customer']) {} +export class UserRole extends OmitType(RoleDto, ['users']) {} export enum TrueOrFalseEnum { true = 'true', diff --git a/src/modules/roles/roles.controller.ts b/src/modules/roles/roles.controller.ts index fd904ad..651ea0d 100644 --- a/src/modules/roles/roles.controller.ts +++ b/src/modules/roles/roles.controller.ts @@ -130,6 +130,7 @@ export class RolesController { this.rolesService.setLanguage(language); return this.rolesService.setRolePermissions(body); } + @Patch('users') @ApiOkResponse({ type: SetRoleUsersRes }) @RequireAllPermissions(PERMISSIONS.USERS.permissions.ADMIN) diff --git a/src/modules/roles/roles.module.ts b/src/modules/roles/roles.module.ts index 5b3a3b9..2ec4a05 100644 --- a/src/modules/roles/roles.module.ts +++ b/src/modules/roles/roles.module.ts @@ -20,5 +20,6 @@ const ducClient = new DucClient(); ], controllers: [RolesController], providers: [RolesService, DadosferaLogger], + exports: [RolesService], }) export class RolesModule {} diff --git a/src/modules/roles/roles.service.ts b/src/modules/roles/roles.service.ts index 9ef20f7..6925715 100644 --- a/src/modules/roles/roles.service.ts +++ b/src/modules/roles/roles.service.ts @@ -16,7 +16,7 @@ import { ClientGrpc } from '@nestjs/microservices'; import { lastValueFrom } from 'rxjs'; import { PermissionsService } from '../permissions/permissions.service'; import { LanguageEnum } from 'src/authentication/permissions.enum'; -import { Role } from 'protospack-v2/dist/lib/Duc/interfaces/entities'; +import { Role, UserRole } from 'protospack-v2/dist/lib/Duc/interfaces/entities'; @Injectable() export class RolesService { @@ -165,7 +165,7 @@ export class RolesService { const [roleTreated] = this.getRolesPermissionsName([role.role]); return { role: roleTreated }; } - getRolesPermissionsName(roles: Role[]): RoleDto[] { + getRolesPermissionsName(roles: UserRole[]): RoleDto[] { const newRoles: RoleDto[] = []; for (const role of roles) { const allPermissions = this.permissionsService.getAllPermissions( diff --git a/src/modules/users/dtos/entities.ts b/src/modules/users/dtos/entities.ts index 46170c3..02a154e 100644 --- a/src/modules/users/dtos/entities.ts +++ b/src/modules/users/dtos/entities.ts @@ -1,5 +1,5 @@ import { ApiProperty, ApiPropertyOptional, OmitType } from '@nestjs/swagger'; -import { RoleDto } from 'src/modules/roles/dto/entities'; +import { RoleDto, UserRole } from 'src/modules/roles/dto/entities'; export class Customer { @ApiProperty() id: string; @@ -23,8 +23,8 @@ export class User { name: string; @ApiProperty() email: string; - @ApiProperty({ type: [RoleDto] }) - roles: RoleDto[]; + @ApiProperty({ type: [UserRole] }) + roles: UserRole[]; @ApiProperty() jobTitle?: string; @ApiProperty() @@ -66,7 +66,7 @@ export class CreateUserReq { @ApiProperty() email: string; @ApiPropertyOptional() - roles?: string[]; + roleNames?: string[]; @ApiPropertyOptional() jobTitle?: string; @ApiPropertyOptional() @@ -84,15 +84,15 @@ export class BatchCreateUserReq { } export class BatchCreateUserRes { @ApiProperty({ type: [User] }) - users: User[]; + usersCreated: User[]; + @ApiProperty({ type: [CreateUserReq] }) + errorUsers: CreateUserReq[]; } export class UpdateUserReq { @ApiPropertyOptional() name?: string; @ApiPropertyOptional() - roles?: string[]; - @ApiPropertyOptional() jobTitle?: string; @ApiPropertyOptional() department?: string; @@ -100,6 +100,11 @@ export class UpdateUserReq { hierarchy?: number; } +export class UpdateUserRes { + @ApiProperty() + user: UserByCustomer; +} + export class GetAllUsersByCustomerIdReq { @ApiPropertyOptional() s?: string; @@ -131,4 +136,16 @@ export class SearchUserReq { s: string; } +export class SetUserRolesReq { + @ApiProperty() + userId: string; + @ApiProperty() + roleNames: string[]; +} + +export class SetUserRolesRes { + @ApiProperty() + user: UserByCustomer; +} + export class SearchUserRes extends GetAllUsersByCustomerIdRes {} diff --git a/src/modules/users/users.controller.ts b/src/modules/users/users.controller.ts index ac3e021..29e75ed 100644 --- a/src/modules/users/users.controller.ts +++ b/src/modules/users/users.controller.ts @@ -25,7 +25,11 @@ import { CreateUserRes, DeleteUserRes, GetAllUsersByCustomerIdRes, + SetUserRolesReq, + SetUserRolesRes, UnassignRoleToUserReq, + UpdateUserReq, + UpdateUserRes, UserByCustomer, } from './dtos/entities'; import { UsersService } from './users.service'; @@ -63,18 +67,6 @@ export class UsersController { return await this.userService.createUser(body); } - @Patch(':id') - @RequireAllPermissions(PERMISSIONS.USERS.permissions.ADMIN) - @ApiCreatedResponse({ type: CreateUserRes }) - async updateUser( - @User() user: RequestUser, - @Body() body: CreateUserReq, - @Param('id') id: string, - ) { - this.logger.info('createUser', { user }); - return await this.userService.updateUser(body, id); - } - @Post('batch') @RequireAllPermissions(PERMISSIONS.USERS.permissions.ADMIN) @ApiCreatedResponse({ type: BatchCreateUserRes }) @@ -94,6 +86,14 @@ export class UsersController { return await this.userService.deleteUser({ id }); } + @Patch('roles') + @RequireAllPermissions(PERMISSIONS.USERS.permissions.ADMIN) + @ApiOkResponse({ type: SetUserRolesRes }) + async setUserRoles(@User() user: RequestUser, @Body() body: SetUserRolesReq) { + this.logger.info('createUser', { user }); + return await this.userService.setRoles(body); + } + @Put('role') @RequireAllPermissions(PERMISSIONS.USERS.permissions.ADMIN) async assignRoleToUser( @@ -123,4 +123,16 @@ export class UsersController { this.logger.info('findOneById', { user }); return await this.userService.findOneById(id); } + + @Patch(':id') + @RequireAllPermissions(PERMISSIONS.USERS.permissions.ADMIN) + @ApiOkResponse({ type: UpdateUserRes }) + async updateUser( + @User() user: RequestUser, + @Body() body: UpdateUserReq, + @Param('id') id: string, + ) { + this.logger.info('createUser', { user }); + return await this.userService.updateUser(body, id); + } } diff --git a/src/modules/users/users.module.ts b/src/modules/users/users.module.ts index 87b5a5d..8ff3a49 100644 --- a/src/modules/users/users.module.ts +++ b/src/modules/users/users.module.ts @@ -4,6 +4,8 @@ import { UsersService } from './users.service'; import { DadosferaLogger } from 'dadosfera-logs'; import { ClientsModule } from '@nestjs/microservices'; import { DucClient } from 'src/clients/duc/client.config'; +import { RolesModule } from '../roles/roles.module'; +import { PermissionsModule } from '../permissions/permissions.module'; const ducClient = new DucClient(); @@ -15,6 +17,8 @@ const ducClient = new DucClient(); ...ducClient.config(), }, ]), + RolesModule, + PermissionsModule, ], controllers: [UsersController], providers: [UsersService, DadosferaLogger], diff --git a/src/modules/users/users.service.ts b/src/modules/users/users.service.ts index 79c9b79..691b48f 100644 --- a/src/modules/users/users.service.ts +++ b/src/modules/users/users.service.ts @@ -14,87 +14,145 @@ import { lastValueFrom } from 'rxjs'; import { BatchCreateUserReq, CreateUserReq, + SetUserRolesReq, UpdateUserReq, } from './dtos/entities'; +import { RolesService } from '../roles/roles.service'; @Injectable() export class UsersService implements OnModuleInit { logger: any; - private usersService: UsersProtoService; + private usersClientService: UsersProtoService; constructor( @Inject(DadosferaLogger) dadosferaLogger: DadosferaLogger, @Inject('DUC_PACKAGE') private readonly grpcClient: ClientGrpc, + private rolesService: RolesService, ) { this.logger = dadosferaLogger.logger; } onModuleInit() { - this.usersService = this.grpcClient.getService( + this.usersClientService = this.grpcClient.getService( ProtoServices.UsersProtoService, ); } async findAllUsersByCustomerId(customerId: string) { - return lastValueFrom( - this.usersService.UserFindAllByCustomerId({ customerId }), + const { users } = await lastValueFrom( + this.usersClientService.UserFindAllByCustomerId({ customerId }), ); + users?.forEach((u) => { + const roles: any[] = this.rolesService.getRolesPermissionsName(u.roles); + u.roles = roles; + }); + return users; } async findOneById(id: string) { - return lastValueFrom(this.usersService.UserFindOneById({ id })); + const { user } = await lastValueFrom( + this.usersClientService.UserFindOneById({ id }), + ); + if (user) { + const roles: any[] = this.rolesService.getRolesPermissionsName( + user.roles, + ); + user.roles = roles; + } + return user; } - async createUser(user: CreateUserReq) { - const { email, department, hierarchy, jobTitle, name, roles } = user; - return lastValueFrom( - this.usersService.UserCreate({ + async createUser(req: CreateUserReq) { + const { email, department, hierarchy, jobTitle, name, roleNames } = req; + const { user } = await lastValueFrom( + this.usersClientService.UserCreate({ email, hierarchy, name, roleIds: [], department, jobTitle, - roleNames: roles, + roleNames, }), ); + if (user) { + const roles: any[] = this.rolesService.getRolesPermissionsName( + user.roles, + ); + user.roles = roles; + } + return user; } - async updateUser(user: UpdateUserReq, id: string) { - const { department, hierarchy, jobTitle, name, roles } = user; - return lastValueFrom( - this.usersService.UserUpdate({ + async updateUser(req: UpdateUserReq, id: string) { + const { department, hierarchy, jobTitle, name } = req; + const { user } = await lastValueFrom( + this.usersClientService.UserUpdate({ name, - customerId: '', + customerId: undefined, id, + department, + hierarchy, + jobTitle, }), ); + if (user) { + const roles: any[] = this.rolesService.getRolesPermissionsName( + user.roles, + ); + user.roles = roles; + } + return user; } + async setRoles(body: SetUserRolesReq) { + const { roleNames, userId } = body; + const clearRoles = roleNames && roleNames.length === 0; + const { user } = await lastValueFrom( + this.usersClientService.UserSetRoles({ + userId, + roleIds: [], + roleNames, + clearRoles, + }), + ); + if (user) { + const roles: any[] = this.rolesService.getRolesPermissionsName( + user.roles, + ); + user.roles = roles; + } + return user; + } async batchCreateUser({ users }: BatchCreateUserReq) { const usersToCreate: UserCreateRequest[] = users.map((u) => ({ ...u, roleIds: [], - roleNames: u.roles, + roleNames: u.roleNames, name: u.name || '', hierarchy: u.hierarchy || null, })); - return lastValueFrom( - this.usersService.UserBatchCreate({ + const { errorUsers, usersCreated } = await lastValueFrom( + this.usersClientService.UserBatchCreate({ users: usersToCreate, }), ); + usersCreated?.forEach((u) => { + const roles: any[] = this.rolesService.getRolesPermissionsName(u.roles); + u.roles = roles; + }); + return { errorUsers, usersCreated }; } async assignRoleToUser(body: AssignRoleToUserRequest) { - return lastValueFrom(this.usersService.AssignRoleToUser(body)); + return lastValueFrom(this.usersClientService.AssignRoleToUser(body)); } async unassignRoleToUser(body: UnassignRoleFromUserRequest) { - return lastValueFrom(this.usersService.UnassignRoleFromUser(body)); + return lastValueFrom(this.usersClientService.UnassignRoleFromUser(body)); } async deleteUser(id: IdRequest) { - return lastValueFrom(this.usersService.UserRemove(id)); + return lastValueFrom(this.usersClientService.UserRemove(id)); } }