feat: implement AdminGuard and QueryGuard for enhanced access control; refactor API and query handling; add deleteQuery method in QueryHandlerService; update QueryResponse type for improved response handling
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
import {
|
||||
Body,
|
||||
Delete,
|
||||
Headers,
|
||||
Inject,
|
||||
Param,
|
||||
@ -11,7 +12,7 @@ import { Response } from "express";
|
||||
import { QueryHandlerService } from "../handler/query.handler.service";
|
||||
import { ApiTokenGuard } from "src/api/guards/api-token.guard";
|
||||
import { QueryExecuterService } from "../executer/query.executer.service";
|
||||
import { QueryGuard } from "src/api/guards/query.guard";
|
||||
import { QueryGuard } from "src/query/guards/query.guard";
|
||||
|
||||
@UseGuards(ApiTokenGuard)
|
||||
export abstract class BaseQueryController {
|
||||
@ -57,11 +58,12 @@ export abstract class BaseQueryController {
|
||||
res.status(queryResult?.statusCode || 200);
|
||||
|
||||
if (
|
||||
queryResult?.statusCode === 302 &&
|
||||
queryResult?.headers &&
|
||||
queryResult?.headers["Location"]
|
||||
queryResult?.redirect ||
|
||||
(queryResult?.statusCode === 302 &&
|
||||
queryResult?.headers &&
|
||||
queryResult?.headers["Location"])
|
||||
) {
|
||||
res.redirect(queryResult?.headers["Location"]);
|
||||
res.redirect(queryResult?.redirect || queryResult?.headers["Location"]);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -71,4 +73,10 @@ export abstract class BaseQueryController {
|
||||
|
||||
res.send(queryResult?.response || null);
|
||||
}
|
||||
|
||||
@Delete("/delete/:id")
|
||||
@UseGuards(QueryGuard)
|
||||
async deleteQuery(@Param("id") id: string) {
|
||||
return this.queryHandlerService.deleteQuery(id);
|
||||
}
|
||||
}
|
||||
|
||||
49
src/query/guards/query.guard.ts
Normal file
49
src/query/guards/query.guard.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import {
|
||||
CanActivate,
|
||||
ExecutionContext,
|
||||
Inject,
|
||||
Injectable,
|
||||
UnauthorizedException,
|
||||
} from "@nestjs/common";
|
||||
import { QueryHandlerService } from "src/query/handler/query.handler.service";
|
||||
|
||||
@Injectable()
|
||||
export class QueryGuard implements CanActivate {
|
||||
constructor(
|
||||
@Inject(QueryHandlerService)
|
||||
private readonly queryHandlerService: QueryHandlerService
|
||||
) {}
|
||||
|
||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
const request = context.switchToHttp().getRequest();
|
||||
const apiToken = request.apiToken;
|
||||
|
||||
if (!apiToken || !apiToken.project) {
|
||||
throw new UnauthorizedException("Project not found for the API token");
|
||||
}
|
||||
|
||||
const queryId = request.params?.id;
|
||||
|
||||
if (!queryId) {
|
||||
throw new UnauthorizedException("Query ID is required");
|
||||
}
|
||||
|
||||
const query = await this.queryHandlerService.getQueryById(queryId);
|
||||
|
||||
if (!query) {
|
||||
throw new UnauthorizedException("Query not found");
|
||||
}
|
||||
|
||||
if (!query.isActive) {
|
||||
throw new UnauthorizedException("Query is inactive");
|
||||
}
|
||||
|
||||
if (query.project.id !== apiToken.project.id) {
|
||||
throw new UnauthorizedException("You do not have access to this query");
|
||||
}
|
||||
|
||||
request.query = query;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -68,4 +68,16 @@ export class QueryHandlerService {
|
||||
Object.assign(query, updateData);
|
||||
return this.queryRepository.save(query);
|
||||
}
|
||||
|
||||
async deleteQuery(id: string) {
|
||||
const query = await this.queryRepository.findOne({ where: { id } });
|
||||
|
||||
if (!query) {
|
||||
throw new Error("Query not found");
|
||||
}
|
||||
|
||||
await this.redisClient.del(`query_${id}`);
|
||||
|
||||
return this.queryRepository.remove(query);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user