diff --git a/docsfera.json b/docsfera.json index b333454..635c2a8 100644 --- a/docsfera.json +++ b/docsfera.json @@ -6022,6 +6022,9 @@ "ApiKey" ], "security": [ + { + "access-token": [] + }, { "access-token": [] } @@ -6075,6 +6078,9 @@ "ApiKey" ], "security": [ + { + "access-token": [] + }, { "access-token": [] } @@ -6115,6 +6121,9 @@ "ApiKey" ], "security": [ + { + "access-token": [] + }, { "access-token": [] } diff --git a/src/authentication/permissions.enum.ts b/src/authentication/permissions.enum.ts index ee74e22..8b49244 100644 --- a/src/authentication/permissions.enum.ts +++ b/src/authentication/permissions.enum.ts @@ -603,6 +603,22 @@ export const PERMISSIONS_GROUPS = { }, }, }; + +export const PUBLIC_PERMISSIONS_SEQID = [ + 46, // AUTH.GENERATE_TOKEN + 23, 13, 29, 5, // PIPELINE + 37, 38, // CONNECTION + 35, // NETWORK_CONFIG + 7, 19, 25, 1, // CATALOG + 14, // SNOWFLAKE + 11, // DATAVIZ + 31, // INTELLIGENCE + 34, // USERS + 43, // PROCESS + 47 // CUSTOMER +]; + + export interface DadosferaModule { name: string; description: string; diff --git a/src/modules/api-key/api-key.controller.ts b/src/modules/api-key/api-key.controller.ts index bc2c51c..4f8faab 100644 --- a/src/modules/api-key/api-key.controller.ts +++ b/src/modules/api-key/api-key.controller.ts @@ -1,12 +1,13 @@ import { Controller, Get, Post, Body, Param, Delete, UseFilters, Inject } from '@nestjs/common'; import { ApiKeyService } from './api-key.service'; import { CreateApiKeyDto, CreateApiKeyResponseDto, ApiKeyBaseResponseDto } from './dto/api-key.dto'; -import { Authenticated } from 'src/decorators/authentication.decorator'; +import { Authenticated, RequireAllPermissions } from 'src/decorators/authentication.decorator'; import { ApiHeaders, ApiTags, ApiResponse } from '@nestjs/swagger'; import { LanguageEnum } from 'src/utils/languages.enum'; import { GrpcToHttpExceptionFilter } from 'src/error/grpc-to-http-exception.filter'; import { RequestUser, User } from 'src/decorators/user.decorator'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; +import { PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum'; @Controller('api-key') @Authenticated() @@ -26,6 +27,7 @@ export class ApiKeyController { @Post() @ApiResponse({ type: CreateApiKeyResponseDto }) + @RequireAllPermissions(PERMISSIONS_GROUPS.USERS.permissions.ADMIN) async create(@Body() createApiKeyDto: CreateApiKeyDto, @User() user: RequestUser): Promise { this.logger.info('POST /api-key', { permissions: createApiKeyDto.permissions, @@ -41,6 +43,7 @@ export class ApiKeyController { @Get() @ApiResponse({ type: [ApiKeyBaseResponseDto] }) + @RequireAllPermissions(PERMISSIONS_GROUPS.USERS.permissions.ADMIN) async findAll(@User() user: RequestUser): Promise { this.logger.info('GET /api-key', { method: 'findAll' @@ -54,6 +57,7 @@ export class ApiKeyController { } @Delete(':id') + @RequireAllPermissions(PERMISSIONS_GROUPS.USERS.permissions.ADMIN) async remove(@Param('id') id: string, @User() user: RequestUser): Promise { this.logger.info('DELETE /api-key/:id', { id, diff --git a/src/modules/api-key/api-key.service.ts b/src/modules/api-key/api-key.service.ts index ea96801..69d646b 100644 --- a/src/modules/api-key/api-key.service.ts +++ b/src/modules/api-key/api-key.service.ts @@ -1,38 +1,73 @@ -import { Injectable, Inject, OnModuleInit } from '@nestjs/common'; +import { + Injectable, + Inject, + OnModuleInit, + BadRequestException, +} from '@nestjs/common'; import { ClientGrpc } from '@nestjs/microservices'; -import { CreateApiKeyDto, CreateApiKeyResponseDto, ApiKeyBaseResponseDto } from './dto/api-key.dto'; +import { + CreateApiKeyDto, + CreateApiKeyResponseDto, + ApiKeyBaseResponseDto, +} from './dto/api-key.dto'; import { RequestUser } from 'src/decorators/user.decorator'; import { DucClient } from '../duc/client.config'; import { PackTheMetadata } from '../../utils/ PackTheMetadata'; import { ApiKeyWriteProtoService } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/write-service'; import { lastValueFrom } from 'rxjs'; import { ProtoServices } from '@dadosfera/protospack-v2/dist/lib/Duc'; +import { PUBLIC_PERMISSIONS_SEQID } from 'src/authentication/permissions.enum'; @Injectable() export class ApiKeyService implements OnModuleInit { private apiKeyService: ApiKeyWriteProtoService; constructor( - @Inject(DucClient.name) private readonly client: ClientGrpc, + @Inject(DucClient.name) private readonly client: ClientGrpc ) {} onModuleInit() { - this.apiKeyService = this.client.getService(ProtoServices.ApiKeyWriteProtoService); + this.apiKeyService = this.client.getService( + ProtoServices.ApiKeyWriteProtoService, + ); } - create(createApiKeyDto: CreateApiKeyDto, user: RequestUser): Promise { + create( + createApiKeyDto: CreateApiKeyDto, + user: RequestUser, + ): Promise { const metadata = PackTheMetadata(user); - return lastValueFrom(this.apiKeyService.CreateApiKey({ - permissions: createApiKeyDto.permissions - }, metadata)); + const invalidPermissions = []; + for (const permission of createApiKeyDto.permissions) { + if (!PUBLIC_PERMISSIONS_SEQID.includes(permission)) { + invalidPermissions.push(permission); + } + } + + if (invalidPermissions.length > 0) { + throw new BadRequestException( + `Invalid permissions: ${invalidPermissions.join(', ')}`, + ); + } + + return lastValueFrom( + this.apiKeyService.CreateApiKey( + { + permissions: createApiKeyDto.permissions, + }, + metadata, + ), + ); } async findAll(user: RequestUser): Promise { const metadata = PackTheMetadata(user); - console.log(metadata) + console.log(metadata); - const data = await lastValueFrom(this.apiKeyService.ListApiKeys({}, metadata)); + const data = await lastValueFrom( + this.apiKeyService.ListApiKeys({}, metadata), + ); return data.api_keys; } diff --git a/src/modules/roles/roles.service.ts b/src/modules/roles/roles.service.ts index bd41ca5..5350b8e 100644 --- a/src/modules/roles/roles.service.ts +++ b/src/modules/roles/roles.service.ts @@ -20,6 +20,7 @@ import { PermissionsService } from '../permissions/permissions.service'; import { LanguageEnum } from 'src/utils/languages.enum'; import { RequestUser } from 'src/decorators/user.decorator'; import { DucClient } from '../duc/client.config'; +import { PUBLIC_PERMISSIONS_SEQID } from 'src/authentication/permissions.enum'; interface GetRolesPermissionsName { id: string; @@ -103,6 +104,20 @@ export class RolesService { const meta = new Metadata(); meta.add('access_token', access_token); const { description, name, permissionIds, userIds } = data; + + const invalidPermissions = []; + for (const permission of permissionIds) { + if (!PUBLIC_PERMISSIONS_SEQID.includes(permission)) { + invalidPermissions.push(permission); + } + } + + if (invalidPermissions.length > 0) { + throw new BadRequestException( + `Invalid permissions: ${invalidPermissions.join(', ')}`, + ); + } + const role = await lastValueFrom( this.rolesClientService.RoleCreate( {