From 521ca17c1b14ea181b6016c17f900769a40709ce Mon Sep 17 00:00:00 2001 From: apurvaubade Date: Fri, 26 Apr 2024 14:21:17 +0530 Subject: [PATCH] UserRole:Delete Userrole API --- src/adapters/assignroleservicelocater.ts | 2 +- .../hasura/rbac/assignrole.adapter.ts | 2 +- .../postgres/rbac/assignrole-adapter.ts | 78 ++++++++++++++----- .../assign-role/assign-role.controller.ts | 17 ++-- .../assign-role/dto/delete-assign-role.dto.ts | 28 +++++++ 5 files changed, 99 insertions(+), 28 deletions(-) create mode 100644 src/rbac/assign-role/dto/delete-assign-role.dto.ts diff --git a/src/adapters/assignroleservicelocater.ts b/src/adapters/assignroleservicelocater.ts index 2d4619f5..35f8fb50 100644 --- a/src/adapters/assignroleservicelocater.ts +++ b/src/adapters/assignroleservicelocater.ts @@ -3,5 +3,5 @@ import { CreateAssignRoleDto } from "src/rbac/assign-role/dto/create-assign-role export interface IServicelocatorassignRole { createAssignRole(request: any, createAssignRoleDto:CreateAssignRoleDto); getAssignedRole(userId, request); - deleteAssignedRole(userId); + deleteAssignedRole(deleteAssignRoleDto); } \ No newline at end of file diff --git a/src/adapters/hasura/rbac/assignrole.adapter.ts b/src/adapters/hasura/rbac/assignrole.adapter.ts index 24481f21..f98b94d9 100644 --- a/src/adapters/hasura/rbac/assignrole.adapter.ts +++ b/src/adapters/hasura/rbac/assignrole.adapter.ts @@ -8,5 +8,5 @@ export class HasuraAssignRoleService { constructor(private httpService: HttpService) {} public async createAssignRole(request: any, createAssignRoleDto:CreateAssignRoleDto){}; public async getAssignedRole(request: any, createAssignRoleDto:CreateAssignRoleDto){}; - public async deleteAssignedRole(userId){}; + public async deleteAssignedRole(deleteAssignRoleDto){}; } \ No newline at end of file diff --git a/src/adapters/postgres/rbac/assignrole-adapter.ts b/src/adapters/postgres/rbac/assignrole-adapter.ts index 9dd7d308..acd4c0ac 100644 --- a/src/adapters/postgres/rbac/assignrole-adapter.ts +++ b/src/adapters/postgres/rbac/assignrole-adapter.ts @@ -1,6 +1,6 @@ import { BadRequestException, ConsoleLogger, HttpStatus, Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import { Repository } from 'typeorm'; +import { In, Repository } from 'typeorm'; import { SuccessResponse } from 'src/success-response'; import { ErrorResponseTypeOrm } from 'src/error-response-typeorm'; import { CreateAssignRoleDto, ResponseAssignRoleDto } from 'src/rbac/assign-role/dto/create-assign-role.dto'; @@ -9,6 +9,7 @@ import { Role } from "src/rbac/role/entities/role.entity"; import { IsAlpha, IsUUID, isUUID } from 'class-validator'; import { executionAsyncResource } from 'async_hooks'; import jwt_decode from "jwt-decode"; +import { DeleteAssignRoleDto } from 'src/rbac/assign-role/dto/delete-assign-role.dto'; @Injectable() @@ -133,31 +134,68 @@ export class PostgresAssignroleService { } - public async deleteAssignedRole(userId) { + public async deleteAssignedRole(deleteAssignRoleDto: DeleteAssignRoleDto) { try { - let result = await this.checkExistingRole(userId); - if (!result) { - return new SuccessResponse({ - statusCode: HttpStatus.NOT_FOUND, - message: 'No Role assigned to user', - data: result, - }); + // Validate userId format + if (!isUUID(deleteAssignRoleDto.userId)) { + return new ErrorResponseTypeOrm({ + statusCode: HttpStatus.BAD_REQUEST, + errorMessage: "Invalid userId format. Please provide a valid UUID.", + }); + } + // Validate roleId format + for (const roleId of deleteAssignRoleDto.roleId) { + if (!isUUID(roleId)) { + return new ErrorResponseTypeOrm({ + statusCode: HttpStatus.BAD_REQUEST, + errorMessage: "Invalid roleId format. Please provide valid UUIDs.", + }); } - let response = await this.userRoleMappingRepository.delete(userId) - return new SuccessResponse({ - statusCode: HttpStatus.OK, - message: 'Role deleted successfully.', - data: { - rowCount: response.affected, - } + } + // Check if the userId exists in userRoleMapping table + const userExists = await this.userRoleMappingRepository.findOne({ + where: { userId: deleteAssignRoleDto.userId }, + }); + if (!userExists) { + return new ErrorResponseTypeOrm({ + statusCode: HttpStatus.BAD_REQUEST, + errorMessage: "User not found in userRoleMapping table", }); - } catch (e) { + } + // Check if all roleId(s) exist + const roleExists = await this.userRoleMappingRepository.find({ + where: { + userId: deleteAssignRoleDto.userId, + roleId: In(deleteAssignRoleDto.roleId), + }, + }); + // If any roleId(s) are missing, throw an error + if (roleExists.length !== deleteAssignRoleDto.roleId.length) { + // throw new Error("One or more roles not found for the user"); return new ErrorResponseTypeOrm({ - statusCode: HttpStatus.INTERNAL_SERVER_ERROR, - errorMessage: e, + statusCode: HttpStatus.BAD_REQUEST, + errorMessage: "Roles not found for the user", }); + } + // If all validations pass, proceed with deletion + const response = await this.userRoleMappingRepository.delete({ + userId: deleteAssignRoleDto.userId, + roleId: In(deleteAssignRoleDto.roleId), + }); + return new SuccessResponse({ + statusCode: HttpStatus.OK, + message: "Roles deleted successfully.", + data: { + rowCount: response.affected, + }, + }); + } catch (e) { + return new ErrorResponseTypeOrm({ + statusCode: HttpStatus.INTERNAL_SERVER_ERROR, + errorMessage: e.message || "Internal server error", + }); } - } + } // async checkAndAddUserRole(data){ // let existingUser = await this.checkExistingRole(data.userId) ; diff --git a/src/rbac/assign-role/assign-role.controller.ts b/src/rbac/assign-role/assign-role.controller.ts index 55bfbd05..7f440440 100644 --- a/src/rbac/assign-role/assign-role.controller.ts +++ b/src/rbac/assign-role/assign-role.controller.ts @@ -2,8 +2,9 @@ import { Controller, Get, Post, Body, Patch, Param, Delete, UsePipes, Validation import { AssignRoleAdapter } from './assign-role.apater'; import { CreateAssignRoleDto } from './dto/create-assign-role.dto'; import { Response, Request } from "express"; -import { ApiBasicAuth, ApiCreatedResponse, ApiBody, ApiForbiddenResponse, ApiHeader, ApiOkResponse, ApiTags, ApiBadRequestResponse, ApiInternalServerErrorResponse, ApiConflictResponse } from '@nestjs/swagger'; +import { ApiBasicAuth, ApiCreatedResponse, ApiBody, ApiForbiddenResponse, ApiHeader, ApiOkResponse, ApiTags, ApiBadRequestResponse, ApiInternalServerErrorResponse, ApiConflictResponse, ApiNotFoundResponse } from '@nestjs/swagger'; import { JwtAuthGuard } from "src/common/guards/keycloak.guard"; +import { DeleteAssignRoleDto } from './dto/delete-assign-role.dto'; @@ -52,15 +53,19 @@ export class AssignRoleController { return response.status(result.statusCode).json(result); } - @Delete("/:id") + @Delete("/:userId") @ApiBasicAuth("access-token") - @ApiCreatedResponse({ description: "Assigend Role deleted successfully." }) - @ApiForbiddenResponse({ description: "Forbidden" }) + @ApiHeader({ name: "tenantid" }) + @ApiOkResponse({ description: "Role deleted successfully." }) + @ApiNotFoundResponse({ description: "Data not found" }) + @ApiBadRequestResponse({ description: "Bad request" }) public async deleteRole( - @Param("id") userId: string, + @Body() deleteAssignRoleDto: DeleteAssignRoleDto, // Modify this line to accept DeleteAssignRoleDto @Res() response: Response ) { - const result = await this.assignRoleAdpater.buildassignroleAdapter().deleteAssignedRole(userId); + const result = await this.assignRoleAdpater + .buildassignroleAdapter() + .deleteAssignedRole(deleteAssignRoleDto); return response.status(result.statusCode).json(result); } diff --git a/src/rbac/assign-role/dto/delete-assign-role.dto.ts b/src/rbac/assign-role/dto/delete-assign-role.dto.ts new file mode 100644 index 00000000..2dec6bba --- /dev/null +++ b/src/rbac/assign-role/dto/delete-assign-role.dto.ts @@ -0,0 +1,28 @@ +import { Expose } from "class-transformer"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsArray, IsNotEmpty, IsString, IsUUID } from "class-validator"; + +export class DeleteAssignRoleDto { + @ApiProperty({ + type: String, + description: "User Id of User", + default: "", + }) + @Expose() + // @IsUUID() + userId: string; + + @ApiProperty({ + type: [String], // Define roleId as an array of strings + description: "Assigned Role Id", + default: [], + }) + @IsArray() + @IsString({ each: true }) // Validate each string in the array + // @IsUUID(4, { each: true }) // Specify the UUID version (4) and validate each UUID string in the array + roleId: string[]; +} + +// constructor(obj: any) { +// Object.assign(this, obj); +// } \ No newline at end of file