mirror of
https://github.com/dadosfera/maestro.git
synced 2026-08-31 19:58:21 +00:00
FIX: add authentication to swagger
This commit is contained in:
+593
-23
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,8 @@
|
||||
import { Request } from 'express';
|
||||
import { CustomDecorator } from '@nestjs/common';
|
||||
import { applyDecorators, CustomDecorator } from '@nestjs/common';
|
||||
import { PermissionsObjectPermission } from './permissions.enum';
|
||||
import { RequestUser } from './user.decorator';
|
||||
import { ApiSecurity } from '@nestjs/swagger';
|
||||
|
||||
export const AUTH_FUNCTION_KEY = '__AUTH_FUNCTION__';
|
||||
|
||||
@@ -10,7 +11,7 @@ export type AuthenticationFunction = (req: Request, user: any) => boolean;
|
||||
// implementation copied from SetMetadata, but tweaked to get existing values
|
||||
// of the metadataKey and accumulate it with the new metadataValue
|
||||
function SetMultipleMetadata(metadataKey, metadataValue): CustomDecorator {
|
||||
const decoratorFactory = (target, key, descriptor) => {
|
||||
const decoratorFactory: CustomDecorator = (target, key?, descriptor?) => {
|
||||
// .start: tweak
|
||||
// descriptor?.value = function decorator; target = class decorator
|
||||
const accumulatedVal =
|
||||
@@ -28,13 +29,20 @@ function SetMultipleMetadata(metadataKey, metadataValue): CustomDecorator {
|
||||
};
|
||||
|
||||
decoratorFactory.KEY = metadataKey;
|
||||
return decoratorFactory as any;
|
||||
return decoratorFactory;
|
||||
}
|
||||
|
||||
function createAuthenticatedDecorator(metadataValue: AuthenticationFunction) {
|
||||
return applyDecorators(
|
||||
ApiSecurity('access-token'),
|
||||
SetMultipleMetadata(AUTH_FUNCTION_KEY, metadataValue),
|
||||
);
|
||||
}
|
||||
|
||||
export function RequireAllPermissions(
|
||||
...permissions: PermissionsObjectPermission[]
|
||||
) {
|
||||
return SetMultipleMetadata(AUTH_FUNCTION_KEY, (req, user: RequestUser) =>
|
||||
return createAuthenticatedDecorator((req, user: RequestUser) =>
|
||||
permissions.every(({ seqid }) => user.permissions.includes(seqid)),
|
||||
);
|
||||
}
|
||||
@@ -42,15 +50,15 @@ export function RequireAllPermissions(
|
||||
export function RequireSomePermission(
|
||||
...permissions: PermissionsObjectPermission[]
|
||||
) {
|
||||
return SetMultipleMetadata(AUTH_FUNCTION_KEY, (req, user: RequestUser) =>
|
||||
return createAuthenticatedDecorator((req, user: RequestUser) =>
|
||||
permissions.some(({ seqid }) => user.permissions.includes(seqid)),
|
||||
);
|
||||
}
|
||||
|
||||
export function AuthenticateCondition(func: AuthenticationFunction) {
|
||||
return SetMultipleMetadata(AUTH_FUNCTION_KEY, func);
|
||||
return createAuthenticatedDecorator(func);
|
||||
}
|
||||
|
||||
export function Authenticated() {
|
||||
return SetMultipleMetadata(AUTH_FUNCTION_KEY, () => true);
|
||||
return createAuthenticatedDecorator(() => true);
|
||||
}
|
||||
|
||||
@@ -54,14 +54,11 @@ export class AuthenticationGuard
|
||||
>(AUTH_FUNCTION_KEY, [ctx.getClass(), ctx.getHandler()]);
|
||||
const mustBeAuthenticated = authFunctions.length > 0;
|
||||
|
||||
if (!mustBeAuthenticated) return true;
|
||||
|
||||
const request = ctx.switchToHttp().getRequest();
|
||||
const accessToken = this.validateToken(request, mustBeAuthenticated);
|
||||
|
||||
if (!mustBeAuthenticated) {
|
||||
// no need to be authenticated
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!accessToken) {
|
||||
// couldn't load valid token
|
||||
throw new ErrorBuilder(ErrorCodes.AUTH.UNAUTHORIZED);
|
||||
|
||||
+5
-4
@@ -46,10 +46,11 @@ function configureSwagger(app: INestApplication) {
|
||||
const config = new DocumentBuilder()
|
||||
.setTitle(swaggerTitle)
|
||||
.setDescription('Documentation for Maestro gateway')
|
||||
.addBearerAuth(
|
||||
{ type: 'http', scheme: 'bearer', bearerFormat: 'JWT' },
|
||||
'Authorization',
|
||||
)
|
||||
.addSecurity('access-token', {
|
||||
type: 'apiKey',
|
||||
name: 'Authorization',
|
||||
in: 'header',
|
||||
})
|
||||
.build();
|
||||
|
||||
const document = SwaggerModule.createDocument(app, config);
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
UseFilters,
|
||||
Get,
|
||||
} from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { ApiSecurity, ApiTags } from '@nestjs/swagger';
|
||||
import {
|
||||
AuthChangePasswordRequest,
|
||||
AuthResetPasswordRequest,
|
||||
@@ -203,6 +203,7 @@ export class AuthController {
|
||||
}
|
||||
|
||||
@Authenticated()
|
||||
@ApiSecurity('access-token')
|
||||
@Get('verify-access-token')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
verifyAccessToken() {
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
ForbiddenException,
|
||||
Get,
|
||||
Headers,
|
||||
HttpException,
|
||||
Inject,
|
||||
NotFoundException,
|
||||
Param,
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
Query,
|
||||
UseFilters,
|
||||
} from '@nestjs/common';
|
||||
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { ConnectionClientService } from './client.service';
|
||||
import { DadosferaLogger } from '@dadosfera/dadosfera-logs';
|
||||
import {
|
||||
@@ -34,7 +34,6 @@ import { GrpcToHttpExceptionFilter } from 'src/error/grpc-to-http-exception.filt
|
||||
const connectionPermissions = PERMISSIONS_GROUPS.CONNECTION.permissions;
|
||||
@UseFilters(new GrpcToHttpExceptionFilter())
|
||||
@ApiTags('connections')
|
||||
@ApiBearerAuth()
|
||||
@Authenticated()
|
||||
@Controller('connections')
|
||||
export class ConnectionController {
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
UploadedFiles,
|
||||
} from '@nestjs/common';
|
||||
import { FileInterceptor, FilesInterceptor } from '@nestjs/platform-express';
|
||||
import { ApiBearerAuth, ApiConsumes, ApiTags } from '@nestjs/swagger';
|
||||
import { ApiConsumes, ApiTags } from '@nestjs/swagger';
|
||||
import { ConnectorClientService } from './client.service';
|
||||
import { AddTagDto } from './dtos/add-tag';
|
||||
import { CreateConnectorDto } from './dtos/create-connector';
|
||||
@@ -31,7 +31,6 @@ import {
|
||||
import { PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum';
|
||||
|
||||
@ApiTags('connectors')
|
||||
@ApiBearerAuth()
|
||||
@Authenticated()
|
||||
@Controller('connectors')
|
||||
export class ConnectorController {
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { Body, Controller, HttpException, Post } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import axios from 'axios';
|
||||
import { Authenticated } from 'src/authentication/authentication.decorator';
|
||||
import { User, RequestUser } from 'src/authentication/user.decorator';
|
||||
import { getSecretFromSecretsManager } from 'src/utils/SecretManager';
|
||||
import { INote } from './dtos';
|
||||
|
||||
@ApiTags('Productboard')
|
||||
@Controller('productboard')
|
||||
@Authenticated()
|
||||
export class ProductboardController {
|
||||
@Post('notes')
|
||||
async sendNote(@Body() note: INote, @User() user: RequestUser) {
|
||||
|
||||
Reference in New Issue
Block a user