diff --git a/docsfera.json b/docsfera.json index 1b2e1cd..7ec6259 100644 --- a/docsfera.json +++ b/docsfera.json @@ -3541,6 +3541,61 @@ ] } }, + "/pipelinesV2/{id}/data-assets": { + "get": { + "operationId": "PipelinesController_findAllDataAssetByPipeline", + "parameters": [ + { + "name": "dadosfera-lang", + "in": "header", + "required": false, + "schema": { + "enum": [ + "pt-br", + "en-us" + ], + "type": "string" + } + }, + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "object", + "required": true, + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + } + }, + "tags": [ + "PipelinesV2" + ], + "security": [ + { + "access-token": [] + } + ] + } + }, "/pipelinesV2/{pipelineId}/inputs/{id}": { "patch": { "operationId": "PipelinesController_updatePipelineInput", @@ -5431,6 +5486,48 @@ ] } }, + "/catalog/schemas": { + "get": { + "operationId": "CatalogController_findSchemas", + "parameters": [ + { + "name": "dadosfera-lang", + "in": "header", + "required": false, + "schema": { + "enum": [ + "pt-br", + "en-us" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + }, + "tags": [ + "Catalog" + ], + "security": [ + { + "access-token": [] + }, + { + "access-token": [] + } + ] + } + }, "/catalog/data-asset/{id}": { "get": { "operationId": "CatalogController_getDataAsset", diff --git a/package-lock.json b/package-lock.json index 8fd7864..a5470e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@aws-sdk/signature-v4": "^3.370.0", "@dadosfera/dadosfera-logs": "^1.0.0-beta.4", "@dadosfera/protospack": "2.5.3", - "@dadosfera/protospack-v2": "^3.40.0-beta.5", + "@dadosfera/protospack-v2": "3.40.0-beta.8", "@grpc/grpc-js": "^1.9.3", "@grpc/proto-loader": "^0.7.9", "@nestjs/cli": "^9.5.0", @@ -1745,9 +1745,10 @@ } }, "node_modules/@dadosfera/protospack-v2": { - "version": "3.40.0-beta.5", - "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com/npm/dadosfera-npm/@dadosfera/protospack-v2/-/protospack-v2-3.40.0-beta.5.tgz", - "integrity": "sha512-iocKv/XXp2jKAasO5ONgm31cKfLgNsU4pEKZMr6YnR7nQaH11WcW7rnuagNxWoik++wLUqbYyf0bZWRDzMlCPA==", + "version": "3.40.0-beta.8", + "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com/npm/dadosfera-npm/@dadosfera/protospack-v2/-/protospack-v2-3.40.0-beta.8.tgz", + "integrity": "sha512-JE5qMjqB3UOM+tCUxB1EwYLQW0PecsaQIa1KDpKEaG3lrzG/H13z8iJi3WH/DuVav2EI94i9VcJWJ1Y0F7ribw==", + "license": "ISC", "dependencies": { "@grpc/grpc-js": "^1.9.3", "rxjs": "^7.5.5" diff --git a/package.json b/package.json index b750c0e..ab6d629 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "@aws-sdk/signature-v4": "^3.370.0", "@dadosfera/dadosfera-logs": "^1.0.0-beta.4", "@dadosfera/protospack": "2.5.3", - "@dadosfera/protospack-v2": "^3.40.0-beta.5", + "@dadosfera/protospack-v2": "3.40.0-beta.8", "@grpc/grpc-js": "^1.9.3", "@grpc/proto-loader": "^0.7.9", "@nestjs/cli": "^9.5.0", diff --git a/src/authentication/authentication.guard.ts b/src/authentication/authentication.guard.ts index f30ce09..168e61a 100644 --- a/src/authentication/authentication.guard.ts +++ b/src/authentication/authentication.guard.ts @@ -153,6 +153,7 @@ export class AuthenticationGuard user_id: accessTokenPayload.user_id, username: accessTokenPayload.username, permissions: accessTokenPayload.permissions, + roles: accessTokenPayload.roles, customer_id: accessTokenPayload.customer_id, customer_name: accessTokenPayload.customer_name, customer_tier: accessTokenPayload.customer_tier, diff --git a/src/authentication/extract-user.ts b/src/authentication/extract-user.ts index 96a3602..07c194d 100644 --- a/src/authentication/extract-user.ts +++ b/src/authentication/extract-user.ts @@ -11,6 +11,7 @@ export function extractUserFrom(aRawJwt: string) { user_id: payload.user_id, username: payload.username, permissions: payload.permissions, + roles: payload.roles, customer_id: payload.customer_id, customer_name: payload.customer_name, customer_tier: payload.customer_tier, diff --git a/src/decorators/user.decorator.ts b/src/decorators/user.decorator.ts index 2ce38ae..3108dbd 100644 --- a/src/decorators/user.decorator.ts +++ b/src/decorators/user.decorator.ts @@ -12,6 +12,7 @@ export interface RequestUser { customer_tier: string; access_token: string; customer_modules: string[]; + roles: string[]; } export const User: (options?: { required?: boolean }) => ParameterDecorator = diff --git a/src/modules/catalog/catalog.controller.ts b/src/modules/catalog/catalog.controller.ts index 83c1386..f097115 100644 --- a/src/modules/catalog/catalog.controller.ts +++ b/src/modules/catalog/catalog.controller.ts @@ -241,6 +241,34 @@ export class CatalogController { return res; } + @Get('schemas') + @RequireSomePermission( + PERMISSIONS_GROUPS.CATALOG.permissions.GET, + PERMISSIONS_GROUPS.CATALOG.permissions.DATA_MANAGER, + ) + async findSchemas(@User() user: RequestUser) { + const { username, user_id, customer_id, customer_name } = user; + this.logger.info(`/catalog - ON FIND SCHEMAS ROUTE`, { + username, + customer_name, + }); + + const metadata = PackTheMetadata({ + username, + user_id, + customer_id, + customer_name, + }); + + try { + const res = await this.catalogService.findSchemas(metadata); + return res; + } catch (error) { + throw new HttpException(error.message, HttpStatus.NOT_FOUND); + } + + } + @Get('data-asset/:id') @RequireSomePermission( PERMISSIONS_GROUPS.CATALOG.permissions.GET, diff --git a/src/modules/catalog/catalog.service.ts b/src/modules/catalog/catalog.service.ts index ebb888c..638e7b4 100644 --- a/src/modules/catalog/catalog.service.ts +++ b/src/modules/catalog/catalog.service.ts @@ -214,15 +214,6 @@ class CatalogService implements OnModuleInit { this.logger.debug('Extracted filters:', { filters }); - console.log('MAESTRO VAI CHAMAR PI-FACTORY COM (ANTES AJUSTE):', { - search, - page, - size, - sort_by, - order, - filters, - }); - if ( filters.manually !== undefined && filters.manually !== null && @@ -233,15 +224,6 @@ class CatalogService implements OnModuleInit { delete filters.manually; } - console.log('MAESTRO VAI CHAMAR PI-FACTORY COM (DEPOIS AJUSTE):', { - search, - page, - size, - sort_by, - order, - filters, - }); - if (filters.owner) { const { users: customer_users } = await this.userService.findAllUsersByCustomerId(customer_id); @@ -517,6 +499,22 @@ class CatalogService implements OnModuleInit { return response; } + async findSchemas(metadata: Metadata) { + this.logger.info('CatalogService - findSchemas'); + + try { + const response = await lastValueFrom( + this.catalogReadService.GetSchemas({}, metadata), + ); + + return response; + + } catch (error) { + this.logger.error('Error fetching schemas:', error); + throw error; + } + } + async getAssetsUsersAndRoles(data_assets: Array, customer_id: string) { const { users: customer_users } = await this.userService.findAllUsersByCustomerId(customer_id); diff --git a/src/modules/catalog/share/share.service.ts b/src/modules/catalog/share/share.service.ts index 7c45128..2531dce 100644 --- a/src/modules/catalog/share/share.service.ts +++ b/src/modules/catalog/share/share.service.ts @@ -262,6 +262,7 @@ export class ShareService implements OnModuleInit { user_id: accessTokenPayload.user_id, username: accessTokenPayload.username, permissions: accessTokenPayload.permissions, + roles: accessTokenPayload.roles, customer_id: accessTokenPayload.customer_id, customer_name: accessTokenPayload.customer_name, customer_tier: accessTokenPayload.customer_tier, diff --git a/src/modules/pipelinesV2/pipelines.controller.ts b/src/modules/pipelinesV2/pipelines.controller.ts index 22dcd05..c424f51 100644 --- a/src/modules/pipelinesV2/pipelines.controller.ts +++ b/src/modules/pipelinesV2/pipelines.controller.ts @@ -193,6 +193,7 @@ export class PipelinesController { @Get(':id/status') @RequireSomePermission(PERMISSIONS_GROUPS.IMPORT_FILES.permissions.VIEW, PERMISSIONS_GROUPS.PIPELINE.permissions.GET) async getPipelineStatus(@Body() body, @Param('id') id: string) { + body.id = id; this.logger.info(`/pipeline/${id} - ON GET PIPELINE STATUS ROUTE`, { @@ -247,6 +248,31 @@ export class PipelinesController { return pipelineRes; } + @Get("/:id/data-assets") + @RequireSomePermission( + PERMISSIONS_GROUPS.PIPELINE.permissions.GET, + PERMISSIONS_GROUPS.CATALOG.permissions.DATA_MANAGER, + PERMISSIONS_GROUPS.CATALOG.permissions.GET + ) + async findAllDataAssetByPipeline( + @Language() language: LanguageEnum, + @Param('id') id: string, + @User() user: RequestUser, + @Query('object') object: string + ) { + const payload = { + pipeline: id, + object: object, + }; + + this.logger.info(`GET pipelinesV2/:id/data-assets` + JSON.stringify(payload)); + + const result = + await this.pipelinesClientService.findAllDataAssetByPipeline(payload, user); + + return result; + } + @Patch('/:id') @RequireSomePermission(PERMISSIONS_GROUPS.PIPELINE.permissions.UPDATE) async update( diff --git a/src/modules/pipelinesV2/pipelines.module.ts b/src/modules/pipelinesV2/pipelines.module.ts index d0007b8..24562c9 100644 --- a/src/modules/pipelinesV2/pipelines.module.ts +++ b/src/modules/pipelinesV2/pipelines.module.ts @@ -14,6 +14,7 @@ import { TransformationsModule } from '../transformations/transformations.module import { PlatformApiModule } from '../platform-api/platform-api.module'; import { NimbusServicesModule } from 'src/services/nimbus/nimbus.module'; import { NimbusService } from 'src/services/nimbus/nimbus.service'; +import { CatalogModule } from '../catalog/catalog.module'; const client = new PipelinesClientConfiguration(); @@ -25,7 +26,8 @@ const client = new PipelinesClientConfiguration(); InputsModule, TransformationsModule, PlatformApiModule, - NimbusServicesModule + NimbusServicesModule, + CatalogModule ], controllers: [PipelinesController], providers: [PipelinesService, DadosferaLogger, NimbusService], diff --git a/src/modules/pipelinesV2/pipelines.service.ts b/src/modules/pipelinesV2/pipelines.service.ts index 650bb1c..b07330f 100644 --- a/src/modules/pipelinesV2/pipelines.service.ts +++ b/src/modules/pipelinesV2/pipelines.service.ts @@ -32,6 +32,10 @@ import { Info } from '@dadosfera/protospack-v2/dist/lib/Input/interfaces/entitie import { TableUpdate } from '@dadosfera/protospack-v2/dist/lib/Input/interfaces/messages'; import { AxiosError } from 'axios'; import { NimbusService } from 'src/services/nimbus/nimbus.service'; +import { PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum'; +import { PackTheMetadata } from 'src/utils/PackTheMetadata'; +import { IDataAsset } from '../catalog/dtos'; +import { CatalogService } from '../catalog/catalog.service'; type RollbackPromise = () => Promise; @@ -48,7 +52,8 @@ export class PipelinesService implements OnModuleInit { private readonly inputsService: InputsService, private readonly transformationsService: TransformationsService, private readonly platformAPI: PlatformApiService, - private readonly nimbusService: NimbusService + private readonly nimbusService: NimbusService, + private readonly catalogService: CatalogService ) { this.logger = dadosferaLogger.logger; } @@ -577,4 +582,45 @@ export class PipelinesService implements OnModuleInit { this.logger.info('Platform api response: ' + JSON.stringify(response)); } + async findAllDataAssetByPipeline(data: { + pipeline: string, + object?: string + }, user: RequestUser) { + const metadata = PackTheMetadata(user); + + const isDataAdmin = user.permissions.includes( + PERMISSIONS_GROUPS.CATALOG.permissions.DATA_MANAGER.seqid, + ); + + let has_permission = false; + + const { + data_assets: resultString + } = await lastValueFrom( + this.pipelineReadService.FindAllDataAssetByPipeline(data, metadata) + ); + + const result = JSON.parse(resultString) as any; + const data_assets: IDataAsset[] = [] + result.forEach(data_asset => { + if (data_asset?.owner === user.username) has_permission = true; + + for (const role of user.roles) { + if (data_asset.roles.includes(role)) has_permission = true; + } + + if (data_asset.users.includes(user.user_id)) has_permission = true; + + if (isDataAdmin || has_permission) { + delete data_asset.p_roles; + delete data_asset.p_users; + data_assets.push(data_asset as IDataAsset); + } + }); + + const assets = await this.catalogService.getAssetsUsersAndRoles(data_assets, user.customer_id); + + return assets; + } + }