From d310ec2b93e57c1c717ef9ffc37385dcb05f36b3 Mon Sep 17 00:00:00 2001 From: Rafael Moraes Date: Mon, 7 Apr 2025 11:55:06 -0300 Subject: [PATCH 1/5] FEAT: logs_dasboard --- package-lock.json | 34 +++++++++---------- src/modules/customers/customers.controller.ts | 15 ++++++++ src/modules/customers/customers.service.ts | 17 ++++++++++ 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 31af08d..80f218f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2417,6 +2417,23 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/@nestjs/platform-express/node_modules/multer": { + "version": "1.4.4-lts.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4-lts.1.tgz", + "integrity": "sha512-WeSGziVj6+Z2/MwQo3GvqzgR+9Uc+qt8SwHKh3gvNPiISKfsMfG4SvCOFYlxxgkXt7yIV2i1yczehm0EOKIxIg==", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.0.0", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.4", + "object-assign": "^4.1.1", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/@nestjs/platform-express/node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -8703,23 +8720,6 @@ "node": ">=12.13" } }, - "node_modules/multer": { - "version": "1.4.5-lts.1", - "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", - "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", - "dependencies": { - "append-field": "^1.0.0", - "busboy": "^1.0.0", - "concat-stream": "^1.5.2", - "mkdirp": "^0.5.4", - "object-assign": "^4.1.1", - "type-is": "^1.6.4", - "xtend": "^4.0.0" - }, - "engines": { - "node": ">= 6.0.0" - } - }, "node_modules/mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", diff --git a/src/modules/customers/customers.controller.ts b/src/modules/customers/customers.controller.ts index 1bd9835..57b2d38 100644 --- a/src/modules/customers/customers.controller.ts +++ b/src/modules/customers/customers.controller.ts @@ -91,4 +91,19 @@ export class CustomersController { const metadata = PackTheMetadata(user); return this.customersService.getMonitoringDashboardUrl(metadata); } + + @Get('logs-dashboard') + @Authenticated() + @RequireAllPermissions( + PERMISSIONS_GROUPS.USERS.permissions.ADMIN, + ) + async getCustomerMixPanelLogsDashboard( + @User() user: RequestUser, + ): Promise<{ url: string }> { + this.logger.info('getLogsDashboardUrl'); + const metadata = PackTheMetadata(user); + const result = await this.customersService.getLogsDashboardUrl(metadata); + return result; + } + } diff --git a/src/modules/customers/customers.service.ts b/src/modules/customers/customers.service.ts index 7c85561..6cb7b24 100644 --- a/src/modules/customers/customers.service.ts +++ b/src/modules/customers/customers.service.ts @@ -154,6 +154,23 @@ export class CustomersService implements OnModuleInit { ); logger.info('Done'); + return res; + } + async getLogsDashboardUrl(metadata: Metadata) { + logger.info('CustomersService - getMixPanelLogsDashboardUrl'); + + const res = await lastValueFrom( + this.pipelineReadService.PipelineV2GetDashboardUrl( + { + dashboard_id: '104', + exp: '15m', + metabase_customer_name: 'dadosferatech', + }, + metadata, + ), + ); + logger.info('Done'); + return res; } } From 0df286a5f7de04bff172fcc675c5946b5b6b8c47 Mon Sep 17 00:00:00 2001 From: Rafael Moraes Date: Fri, 11 Apr 2025 15:23:41 -0300 Subject: [PATCH 2/5] FEAT: att docsfera --- docsfera.json | 22 ++++++++++++ package-lock.json | 35 ++++++++++--------- src/modules/customers/customers.controller.ts | 9 +++-- src/modules/customers/customers.service.ts | 2 +- 4 files changed, 48 insertions(+), 20 deletions(-) diff --git a/docsfera.json b/docsfera.json index 212ad4e..b98c072 100644 --- a/docsfera.json +++ b/docsfera.json @@ -5466,6 +5466,28 @@ ] } }, + "/customers/logs-dashboard": { + "get": { + "operationId": "CustomersController_getCustomerMixPanelLogsDashboard", + "parameters": [], + "responses": { + "200": { + "description": "" + } + }, + "tags": [ + "Customers" + ], + "security": [ + { + "access-token": [] + }, + { + "access-token": [] + } + ] + } + }, "/open-data/sharing-ocean-data": { "post": { "operationId": "OpenDataController_createUser", diff --git a/package-lock.json b/package-lock.json index 80f218f..6fd4bc8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2417,23 +2417,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/@nestjs/platform-express/node_modules/multer": { - "version": "1.4.4-lts.1", - "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4-lts.1.tgz", - "integrity": "sha512-WeSGziVj6+Z2/MwQo3GvqzgR+9Uc+qt8SwHKh3gvNPiISKfsMfG4SvCOFYlxxgkXt7yIV2i1yczehm0EOKIxIg==", - "dependencies": { - "append-field": "^1.0.0", - "busboy": "^1.0.0", - "concat-stream": "^1.5.2", - "mkdirp": "^0.5.4", - "object-assign": "^4.1.1", - "type-is": "^1.6.4", - "xtend": "^4.0.0" - }, - "engines": { - "node": ">= 6.0.0" - } - }, "node_modules/@nestjs/platform-express/node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -8720,6 +8703,24 @@ "node": ">=12.13" } }, + "node_modules/multer": { + "version": "1.4.5-lts.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", + "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", + "license": "MIT", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.0.0", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.4", + "object-assign": "^4.1.1", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", diff --git a/src/modules/customers/customers.controller.ts b/src/modules/customers/customers.controller.ts index 57b2d38..3d2afa2 100644 --- a/src/modules/customers/customers.controller.ts +++ b/src/modules/customers/customers.controller.ts @@ -101,9 +101,14 @@ export class CustomersController { @User() user: RequestUser, ): Promise<{ url: string }> { this.logger.info('getLogsDashboardUrl'); - const metadata = PackTheMetadata(user); + const metadata = PackTheMetadata({ + ...user, + customer_name: 'dadosferatech', + }); + const result = await this.customersService.getLogsDashboardUrl(metadata); return result; - } + } + } diff --git a/src/modules/customers/customers.service.ts b/src/modules/customers/customers.service.ts index 6cb7b24..36df7c3 100644 --- a/src/modules/customers/customers.service.ts +++ b/src/modules/customers/customers.service.ts @@ -162,7 +162,7 @@ export class CustomersService implements OnModuleInit { const res = await lastValueFrom( this.pipelineReadService.PipelineV2GetDashboardUrl( { - dashboard_id: '104', + dashboard_id: '103', exp: '15m', metabase_customer_name: 'dadosferatech', }, From a8ae07e6c48863b68de1b7e5ee91d8c0969e083f Mon Sep 17 00:00:00 2001 From: Rafael Moraes Date: Fri, 11 Apr 2025 16:06:55 -0300 Subject: [PATCH 3/5] FEAT: url fix --- src/modules/customers/customers.controller.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/modules/customers/customers.controller.ts b/src/modules/customers/customers.controller.ts index 3d2afa2..7700eb3 100644 --- a/src/modules/customers/customers.controller.ts +++ b/src/modules/customers/customers.controller.ts @@ -101,10 +101,7 @@ export class CustomersController { @User() user: RequestUser, ): Promise<{ url: string }> { this.logger.info('getLogsDashboardUrl'); - const metadata = PackTheMetadata({ - ...user, - customer_name: 'dadosferatech', - }); + const metadata = PackTheMetadata(user); const result = await this.customersService.getLogsDashboardUrl(metadata); return result; From 2aed66d371237fe83e18ab69aafab794268539e3 Mon Sep 17 00:00:00 2001 From: marcos-silva-rodrigues Date: Thu, 17 Apr 2025 15:20:27 -0300 Subject: [PATCH 4/5] FEAT: add decorator to block endpoint if not found module --- src/authentication/authentication.guard.ts | 1 + src/authentication/permissions.enum.ts | 5 +++++ src/decorators/authentication.decorator.ts | 8 ++++++++ src/decorators/user.decorator.ts | 1 + src/modules/customers/customers.controller.ts | 12 ++++++------ 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/authentication/authentication.guard.ts b/src/authentication/authentication.guard.ts index 7e938b0..bc69f8c 100644 --- a/src/authentication/authentication.guard.ts +++ b/src/authentication/authentication.guard.ts @@ -121,6 +121,7 @@ export class AuthenticationGuard customer_id: accessTokenPayload.customer_id, customer_name: accessTokenPayload.customer_name, customer_tier: accessTokenPayload.customer_tier, + customer_modules: accessTokenPayload.customer_modules, access_token: accessToken, }; // TODO: for backwards compatibility. remove in the future diff --git a/src/authentication/permissions.enum.ts b/src/authentication/permissions.enum.ts index 5116cfe..4e23457 100644 --- a/src/authentication/permissions.enum.ts +++ b/src/authentication/permissions.enum.ts @@ -609,6 +609,11 @@ export interface DadosferaModule { key: string; permissionSeqId: number; } + +export const DADOSFERA_MODULES_KEYS = { + LOG_DASHBOARD: 'logs-dashboard' +} + export const DADOSFERA_MODULES: Array = [ { name: 'Intelligence Module', diff --git a/src/decorators/authentication.decorator.ts b/src/decorators/authentication.decorator.ts index 385ced0..03f9aed 100644 --- a/src/decorators/authentication.decorator.ts +++ b/src/decorators/authentication.decorator.ts @@ -25,6 +25,14 @@ export function RequireSomePermission( ); } +export function RequireModule( + key: string +) { + return createAuthenticatedDecorator((_, user: RequestUser) => + user.customer_modules.some(module => module === key), + ); +} + export function AuthenticateCondition(func: AuthenticationFunction) { return createAuthenticatedDecorator(func); } diff --git a/src/decorators/user.decorator.ts b/src/decorators/user.decorator.ts index 94b6045..2ce38ae 100644 --- a/src/decorators/user.decorator.ts +++ b/src/decorators/user.decorator.ts @@ -11,6 +11,7 @@ export interface RequestUser { customer_name: string; customer_tier: string; access_token: string; + customer_modules: string[]; } export const User: (options?: { required?: boolean }) => ParameterDecorator = diff --git a/src/modules/customers/customers.controller.ts b/src/modules/customers/customers.controller.ts index 7700eb3..c4980d0 100644 --- a/src/modules/customers/customers.controller.ts +++ b/src/modules/customers/customers.controller.ts @@ -12,10 +12,11 @@ import { UseFilters, } from '@nestjs/common'; import { ApiOkResponse, ApiProduces, ApiTags } from '@nestjs/swagger'; -import { PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum'; +import { DADOSFERA_MODULES_KEYS, PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum'; import { Authenticated, RequireAllPermissions, + RequireModule, } from 'src/decorators/authentication.decorator'; import { GrpcToHttpExceptionFilter } from 'src/error/grpc-to-http-exception.filter'; import { CustomersService } from './customers.service'; @@ -97,15 +98,14 @@ export class CustomersController { @RequireAllPermissions( PERMISSIONS_GROUPS.USERS.permissions.ADMIN, ) + @RequireModule(DADOSFERA_MODULES_KEYS.LOG_DASHBOARD) async getCustomerMixPanelLogsDashboard( @User() user: RequestUser, - ): Promise<{ url: string }> { - this.logger.info('getLogsDashboardUrl'); + ): Promise<{ url: string }> { + this.logger.info('getLogsDashboardUrl'); const metadata = PackTheMetadata(user); - const result = await this.customersService.getLogsDashboardUrl(metadata); + const result = await this.customersService.getLogsDashboardUrl(metadata); return result; } - - } From 419c063c6c0bf0e2a4c9d6ca8c63deffcbd4565e Mon Sep 17 00:00:00 2001 From: marcos-silva-rodrigues Date: Thu, 17 Apr 2025 18:04:18 -0300 Subject: [PATCH 5/5] FEAT: add access dashboard --- src/authentication/permissions.enum.ts | 3 +- src/modules/customers/customers.controller.ts | 16 ++++++++++ src/modules/customers/customers.service.ts | 30 +++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/authentication/permissions.enum.ts b/src/authentication/permissions.enum.ts index 4e23457..1e01531 100644 --- a/src/authentication/permissions.enum.ts +++ b/src/authentication/permissions.enum.ts @@ -611,7 +611,8 @@ export interface DadosferaModule { } export const DADOSFERA_MODULES_KEYS = { - LOG_DASHBOARD: 'logs-dashboard' + LOG_DASHBOARD: 'logs-dashboard', + ACCESS_DASHBOARD: 'access-dashboard' } export const DADOSFERA_MODULES: Array = [ diff --git a/src/modules/customers/customers.controller.ts b/src/modules/customers/customers.controller.ts index c4980d0..280dce3 100644 --- a/src/modules/customers/customers.controller.ts +++ b/src/modules/customers/customers.controller.ts @@ -108,4 +108,20 @@ export class CustomersController { const result = await this.customersService.getLogsDashboardUrl(metadata); return result; } + + @Get('access-dashboard') + @Authenticated() + @RequireAllPermissions( + PERMISSIONS_GROUPS.USERS.permissions.ADMIN, + ) + @RequireModule(DADOSFERA_MODULES_KEYS.ACCESS_DASHBOARD) + async getAccessDashboard( + @User() user: RequestUser, + ): Promise<{ url: string }> { + this.logger.info('getAccessDashboard'); + const metadata = PackTheMetadata(user); + + const result = await this.customersService.getAccessDashboardUrl(user.customer_name, metadata); + return result; + } } diff --git a/src/modules/customers/customers.service.ts b/src/modules/customers/customers.service.ts index 36df7c3..ed302fd 100644 --- a/src/modules/customers/customers.service.ts +++ b/src/modules/customers/customers.service.ts @@ -5,6 +5,7 @@ import { HttpException, HttpStatus, InternalServerErrorException, + ForbiddenException, } from '@nestjs/common'; import { firstValueFrom, lastValueFrom } from 'rxjs'; @@ -173,4 +174,33 @@ export class CustomersService implements OnModuleInit { return res; } + + async getAccessDashboardUrl(customerName: string, metadata: Metadata) { + /* + * TODO(Refactor): dar um jeito de exibir o dash da sbm diferente dos outros customer + * pois o signicado de department para sbm significa as instituições do usuários + */ + if (customerName !== 'sbmoffshorecom') { + throw new ForbiddenException(); + } + logger.info('CustomersService - getAccessDashboardUrl'); + + const res = await this.getDashboardUrl('105', metadata); + logger.info('Done'); + + return res; + } + + private async getDashboardUrl(dashboardId: string, metadata: Metadata) { + return await lastValueFrom( + this.pipelineReadService.PipelineV2GetDashboardUrl( + { + dashboard_id: dashboardId, + exp: '15m', + metabase_customer_name: 'dadosferatech', + }, + metadata + ) + ); + } }