auth permission guard added

This commit is contained in:
VirajBrainvire
2024-04-23 12:41:37 +05:30
parent bef2f1e4ad
commit 59badb41a3
3 changed files with 112 additions and 10 deletions

View File

@ -19,6 +19,8 @@ import {
GetDeviceByRoomIdDto,
} from '../dtos/get.device.dto';
import { ControlDeviceDto } from '../dtos/control.device.dto';
import { AuthGuardWithRoles } from 'src/guards/device.permission.guard';
import { PermissionType } from '@app/common/constants/permission-type.enum';
@ApiTags('Device Module')
@Controller({
@ -29,7 +31,7 @@ export class DeviceController {
constructor(private readonly deviceService: DeviceService) {}
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@AuthGuardWithRoles(PermissionType.READ)
@Get('room')
async getDevicesByRoomId(
@Query() getDeviceByRoomIdDto: GetDeviceByRoomIdDto,
@ -41,7 +43,7 @@ export class DeviceController {
}
}
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@AuthGuardWithRoles(PermissionType.READ)
@Get('group')
async getDevicesByGroupId(
@Query() getDeviceByGroupIdDto: GetDeviceByGroupIdDto,
@ -55,7 +57,7 @@ export class DeviceController {
}
}
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@AuthGuardWithRoles(PermissionType.READ)
@Get(':deviceId')
async getDeviceDetailsByDeviceId(@Param('deviceId') deviceId: string) {
try {
@ -65,7 +67,7 @@ export class DeviceController {
}
}
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@AuthGuardWithRoles(PermissionType.READ)
@Get(':deviceId/functions')
async getDeviceInstructionByDeviceId(@Param('deviceId') deviceId: string) {
try {
@ -75,7 +77,7 @@ export class DeviceController {
}
}
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@AuthGuardWithRoles(PermissionType.READ)
@Get(':deviceId/functions/status')
async getDevicesInstructionStatus(@Param('deviceId') deviceId: string) {
try {
@ -85,7 +87,7 @@ export class DeviceController {
}
}
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@AuthGuardWithRoles(PermissionType.CONTROLLABLE)
@Post('room')
async addDeviceInRoom(@Body() addDeviceInRoomDto: AddDeviceInRoomDto) {
try {
@ -95,7 +97,7 @@ export class DeviceController {
}
}
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@AuthGuardWithRoles(PermissionType.CONTROLLABLE)
@Post('group')
async addDeviceInGroup(@Body() addDeviceInGroupDto: AddDeviceInGroupDto) {
try {
@ -105,7 +107,7 @@ export class DeviceController {
}
}
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@AuthGuardWithRoles(PermissionType.CONTROLLABLE)
@Post('control')
async controlDevice(@Body() controlDeviceDto: ControlDeviceDto) {
try {

View File

@ -4,10 +4,13 @@ import { DeviceController } from './controllers/device.controller';
import { ConfigModule } from '@nestjs/config';
import { ProductRepositoryModule } from '@app/common/modules/product/product.repository.module';
import { ProductRepository } from '@app/common/modules/product/repositories';
import { DeviceRepositoryModule } from '@app/common/modules/device';
import { DeviceUserTypeRepository } from '@app/common/modules/device/repositories';
import { PermissionTypeRepository } from '@app/common/modules/permission/repositories';
@Module({
imports: [ConfigModule, ProductRepositoryModule],
imports: [ConfigModule, ProductRepositoryModule,DeviceRepositoryModule],
controllers: [DeviceController],
providers: [DeviceService, ProductRepository],
providers: [DeviceService, ProductRepository,DeviceUserTypeRepository,PermissionTypeRepository],
exports: [DeviceService],
})
export class DeviceModule {}

View File

@ -0,0 +1,97 @@
import { PermissionType } from '@app/common/constants/permission-type.enum';
import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard';
import { DeviceUserTypeRepository } from '@app/common/modules/device/repositories';
import { PermissionTypeRepository } from '@app/common/modules/permission/repositories';
import {
Injectable,
CanActivate,
HttpStatus,
ExecutionContext,
BadRequestException,
applyDecorators,
SetMetadata,
UseGuards,
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
@Injectable()
export class DevicePermissionGuard implements CanActivate {
constructor(
private reflector: Reflector,
private readonly deviceUserTypeRepository: DeviceUserTypeRepository,
private readonly permissionTypeRepository: PermissionTypeRepository,
) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const req = context.switchToHttp().getRequest();
try {
const { deviceId } = req.headers;
const userId = req.user.uuid;
const requirePermission =
this.reflector.getAllAndOverride<PermissionType>('permission', [
context.getHandler(),
context.getClass(),
]);
if (!requirePermission) {
return true;
}
await this.checkDevicePermission(deviceId, userId, requirePermission);
return true;
} catch (error) {
this.handleGuardError(error, context);
return false;
}
}
async checkDevicePermission(
deviceId: string,
userId: string,
requirePermission,
) {
const [userPermissionDetails, permissionDetails] = await Promise.all([
this.deviceUserTypeRepository.findOne({
where: { deviceUuid: deviceId, userUuid: userId },
}),
this.permissionTypeRepository.findOne({
where: {
type: requirePermission,
},
}),
]);
if (!userPermissionDetails) {
throw new BadRequestException('User Permission Details Not Found');
}
if (userPermissionDetails.permissionTypeUuid !== permissionDetails.uuid) {
throw new BadRequestException(
`User Does not have a ${requirePermission}`,
);
}
}
private handleGuardError(error: Error, context: ExecutionContext) {
const response = context.switchToHttp().getResponse();
console.error(error);
if (error instanceof BadRequestException) {
response
.status(HttpStatus.BAD_REQUEST)
.json({ statusCode: HttpStatus.BAD_REQUEST, message: error.message });
} else {
response.status(HttpStatus.NOT_FOUND).json({
statusCode: HttpStatus.NOT_FOUND,
message: 'User Permission not found',
});
}
}
}
export function AuthGuardWithRoles(permission?: string) {
return applyDecorators(
SetMetadata('permission', permission),
UseGuards(JwtAuthGuard),
UseGuards(DevicePermissionGuard),
);
}