Compare commits

...
43 Commits
Author SHA1 Message Date
Gabriel Amorim cad1e4b3de Merge pull request #144 from dadosfera/fix/delete-connection-permission
FIX: delete connection permission
2022-10-04 15:40:14 -03:00
Gabriel Rosa b311a84bde FIX: delete route reimplemented 2022-10-04 15:22:43 -03:00
Gabriel Rosa 28280dca8d FIX: Delete connections permission 2022-10-04 14:46:52 -03:00
Victor Radael 450c82446e Merge pull request #143 from dadosfera/fix/dadoferademo
FIX: unkown error get user by id
2022-10-03 16:56:55 -03:00
Victor Radael beb27a0f60 FIX: unkown error get user by id 2022-10-03 16:52:42 -03:00
Victor Radael 0360711ab4 Merge pull request #141 from dadosfera/feat/openSearchCatalog
Feat/open search catalog
2022-09-30 15:38:17 -03:00
Victor Radael b6ec2a83b2 FIX: Swagger 2022-09-30 15:15:24 -03:00
Victor Radael 812dc0c735 FIX: Swagger 2022-09-30 15:12:45 -03:00
Victor Radael 11715dd528 FIX: Swagger 2022-09-30 15:12:19 -03:00
Victor Radael be476c1a6d FIX: data asset owner 2022-09-30 14:38:42 -03:00
Victor Radael a8414f780a FIX: data asset owner 2022-09-30 14:28:06 -03:00
Victor Radael 1da61a4c13 FIX: Data asset permission owner 2022-09-30 12:27:55 -03:00
Victor Radael 7e8f5c49b5 FIX: Data asset permission owner 2022-09-30 11:11:59 -03:00
Victor Radael 96a485afd1 FIX: Revoke Permissions 2022-09-29 18:05:27 -03:00
Victor Radael e3c203d673 FIX: Data assets permissions 2022-09-29 15:04:31 -03:00
Gabriel Amorim d7da68241e Merge pull request #140 from dadosfera/fix/create-user
FIX: create user
2022-09-29 09:19:20 -03:00
Victor Radael 5d924f8a92 FIX: Manage Permissions Catalog 2022-09-28 23:06:52 -03:00
Victor Radael f9b4ddd070 FIX: Manage Permissions Catalog 2022-09-28 17:02:22 -03:00
Victor Radael c0e0732b7e FIX: Manage Permissions Catalog 2022-09-28 17:00:15 -03:00
Gabriel Rosa 37ea7c2f4d FIX: GetOneDataAsset only when table metadata has only one result 2022-09-28 16:59:45 -03:00
Victor Radael d42584fcfc FIX: Manage Permissions Catalog 2022-09-28 16:58:52 -03:00
Victor Radael a28781423c FIX: Manage Permissions Catalog 2022-09-28 14:39:25 -03:00
Gabriel Rosa 8c638610c7 Update description on open search 2022-09-28 11:52:59 -03:00
Victor Radael 55ff485fd0 FIX: Catalog Manage Permissions 2022-09-28 11:48:41 -03:00
Gabriel Rosa 4877fab945 new protospack 2022-09-28 11:20:17 -03:00
rodrigo.zamboni e724ef5ccc FIX: fix get all tags route 2022-09-27 16:33:56 -03:00
rodrigo.zamboni 9dc96416e8 Merge branch 'feat/openSearchCatalog' of https://github.com/dadosfera/maestro into feat/openSearchCatalog 2022-09-27 09:43:32 -03:00
rodrigo.zamboni 49663c4115 UPDATE: modifyed catalog tags route to use opensearch instead of nimbus 2022-09-27 09:35:48 -03:00
Gabriel Rosa c16664c7f9 new protospack version 2022-09-23 14:58:26 -03:00
Gabriel Rosa 7245942707 Function to synchronize user 2022-09-23 09:25:41 -03:00
Gabriel Rosa c29cf5aee1 FIX: sending metadata on creation of users 2022-09-20 17:48:27 -03:00
rodrigo.zamboni d96658c9cd FIX: fix catalog response 2022-09-19 17:42:30 -03:00
rodrigo.zamboni cbd736b87d FIX: fix catalog return response/ adding empty dashboard array 2022-09-19 16:28:33 -03:00
rodrigo.zamboni e4e6d95f8a Merge branch 'feat/openSearchCatalog' of https://github.com/dadosfera/maestro into feat/openSearchCatalog 2022-09-19 15:08:35 -03:00
rodrigo.zamboni a8e13c01d2 FIX: passing params with query params 2022-09-19 15:06:16 -03:00
Gabriel Rosa cdf2ce3cc2 FIX: create credentials on catalog's pi-factory client 2022-09-19 14:51:28 -03:00
rodrigo.zamboni c3877657ef FIX: fix catalog route to use openSearch 2022-09-19 11:14:23 -03:00
Gabriel Amorim 3d39affc61 Merge pull request #139 from dadosfera/fix/network-config-permissions
FIX: remove permission to delete VPNS
2022-09-16 11:55:50 -03:00
Gabriel Rosa 5d045b675c FIX: remove permission to delete VPNS 2022-09-15 09:48:37 -03:00
Gabriel Amorim bb61990f6e Merge pull request #138 from dadosfera/fix/permission-delete-connection
FIX: remove permission to delete connection
2022-09-15 08:50:41 -03:00
Gabriel Rosa 80442c509a FIX: remove permission to delete connection 2022-09-15 08:33:47 -03:00
Gabriel Amorim 8551239038 Merge pull request #137 from dadosfera/fix/update-user-email
FIX: update user email
2022-09-14 11:32:58 -03:00
Gabriel Rosa 4cf7c6e17b FIX: update user email 2022-09-14 10:18:03 -03:00
19 changed files with 614 additions and 160 deletions
+34 -32
View File
@@ -11,8 +11,8 @@
"license": "UNLICENSED",
"dependencies": {
"@aws-sdk/client-secrets-manager": "^3.112.0",
"@dadosfera/dadosfera-logs": "^1.0.0-beta.3",
"@dadosfera/protospack-v2": "3.17.2",
"@dadosfera/dadosfera-logs": "^1.0.0-beta.4",
"@dadosfera/protospack-v2": "3.18.7",
"@grpc/grpc-js": "^1.6.7",
"@grpc/proto-loader": "^0.6.13",
"@nestjs/common": "^8.4.7",
@@ -1716,9 +1716,9 @@
}
},
"node_modules/@dadosfera/dadosfera-logs": {
"version": "1.0.0-beta.3",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/@dadosfera/dadosfera-logs/-/dadosfera-logs-1.0.0-beta.3.tgz",
"integrity": "sha512-VuGiQlpDulcl1+FSFoT4/6PA9Pr+DAzbFHAYesz9rPinR46ejG7ZBZk3m86NYqQtgMyurqXvgCR8GPy9FpwqFw==",
"version": "1.0.0-beta.4",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/@dadosfera/dadosfera-logs/-/dadosfera-logs-1.0.0-beta.4.tgz",
"integrity": "sha512-fFncbNVMbfQa2EFl7NJgmtuSRWHGtmwCbl5p++lSLvGcTIMjLGJ4HAMzSMemQhSxiiYlokdwweb7jJY7Ms62SQ==",
"dependencies": {
"@elastic/ecs-winston-format": "^1.3.1",
"winston": "^3.7.2",
@@ -1726,9 +1726,9 @@
}
},
"node_modules/@dadosfera/protospack-v2": {
"version": "3.17.2",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/@dadosfera/protospack-v2/-/protospack-v2-3.17.2.tgz",
"integrity": "sha512-N1hn7lIBWgc4JPEAdlQ3jt+++y61XYb9amDmgOUbfSt4803oSdAnCktrcxq3/0e/ZuSYm0qESOkKn0uNLDlGcg==",
"version": "3.18.7",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/@dadosfera/protospack-v2/-/protospack-v2-3.18.7.tgz",
"integrity": "sha512-MloW230CUyK+g+HFkSv1OuaJNT5mfEGRh7tpZjjKxO2Qxm4eKkmI9uh/cNXCDzUpRBFXzBJ+5w12bxw2UnMRSw==",
"dependencies": {
"@grpc/grpc-js": "^1.6.7",
"rxjs": "^7.5.5",
@@ -7975,9 +7975,9 @@
}
},
"node_modules/logform": {
"version": "2.4.1",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/logform/-/logform-2.4.1.tgz",
"integrity": "sha512-7XB/tqc3VRbri9pRjU6E97mQ8vC27ivJ3lct4jhyT+n0JNDd4YKldFl0D75NqDp46hk8RC7Ma1Vjv/UPf67S+A==",
"version": "2.4.2",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/logform/-/logform-2.4.2.tgz",
"integrity": "sha512-W4c9himeAwXEdZ05dQNerhFz2XG80P9Oj0loPUMV23VC2it0orMHQhJm4hdnnor3rd1HsGf6a2lPwBM1zeXHGw==",
"dependencies": {
"@colors/colors": "1.5.0",
"fecha": "^4.2.0",
@@ -10337,9 +10337,9 @@
}
},
"node_modules/ts-proto": {
"version": "1.125.0",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/ts-proto/-/ts-proto-1.125.0.tgz",
"integrity": "sha512-ADXnF+Psk3SaLzxtXrhvKUDrNNpg7LnL5rQuQL+u9PiOQ4C2ktWLvJM0VtL4zqQ9/OHROmXjebpR0KMZAkI93w==",
"version": "1.126.1",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/ts-proto/-/ts-proto-1.126.1.tgz",
"integrity": "sha512-PKrcgd0mCQJDY7tp+th349uYhnjs2Tz7wSqm9+DBcodl3YCKPt1pFtFmApOZdQ8WlghhgKAuJDIRQJBd6jD5YA==",
"dependencies": {
"@types/object-hash": "^1.3.0",
"dataloader": "^1.4.0",
@@ -10856,10 +10856,11 @@
}
},
"node_modules/winston": {
"version": "3.7.2",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/winston/-/winston-3.7.2.tgz",
"integrity": "sha512-QziIqtojHBoyzUOdQvQiar1DH0Xp9nF1A1y7NVy2DGEsz82SBDtOalS0ulTRGVT14xPX3WRWkCsdcJKqNflKng==",
"version": "3.8.2",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/winston/-/winston-3.8.2.tgz",
"integrity": "sha512-MsE1gRx1m5jdTTO9Ld/vND4krP2To+lgDoMEHGGa4HIlAUyXJtfc7CxQcGXVyz2IBpw5hbFkj2b/AtUdQwyRew==",
"dependencies": {
"@colors/colors": "1.5.0",
"@dabh/diagnostics": "^2.0.2",
"async": "^3.2.3",
"is-stream": "^2.0.0",
@@ -12295,9 +12296,9 @@
}
},
"@dadosfera/dadosfera-logs": {
"version": "1.0.0-beta.3",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/@dadosfera/dadosfera-logs/-/dadosfera-logs-1.0.0-beta.3.tgz",
"integrity": "sha512-VuGiQlpDulcl1+FSFoT4/6PA9Pr+DAzbFHAYesz9rPinR46ejG7ZBZk3m86NYqQtgMyurqXvgCR8GPy9FpwqFw==",
"version": "1.0.0-beta.4",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/@dadosfera/dadosfera-logs/-/dadosfera-logs-1.0.0-beta.4.tgz",
"integrity": "sha512-fFncbNVMbfQa2EFl7NJgmtuSRWHGtmwCbl5p++lSLvGcTIMjLGJ4HAMzSMemQhSxiiYlokdwweb7jJY7Ms62SQ==",
"requires": {
"@elastic/ecs-winston-format": "^1.3.1",
"winston": "^3.7.2",
@@ -12305,9 +12306,9 @@
}
},
"@dadosfera/protospack-v2": {
"version": "3.17.2",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/@dadosfera/protospack-v2/-/protospack-v2-3.17.2.tgz",
"integrity": "sha512-N1hn7lIBWgc4JPEAdlQ3jt+++y61XYb9amDmgOUbfSt4803oSdAnCktrcxq3/0e/ZuSYm0qESOkKn0uNLDlGcg==",
"version": "3.18.7",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/@dadosfera/protospack-v2/-/protospack-v2-3.18.7.tgz",
"integrity": "sha512-MloW230CUyK+g+HFkSv1OuaJNT5mfEGRh7tpZjjKxO2Qxm4eKkmI9uh/cNXCDzUpRBFXzBJ+5w12bxw2UnMRSw==",
"requires": {
"@grpc/grpc-js": "^1.6.7",
"rxjs": "^7.5.5",
@@ -16568,9 +16569,9 @@
}
},
"logform": {
"version": "2.4.1",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/logform/-/logform-2.4.1.tgz",
"integrity": "sha512-7XB/tqc3VRbri9pRjU6E97mQ8vC27ivJ3lct4jhyT+n0JNDd4YKldFl0D75NqDp46hk8RC7Ma1Vjv/UPf67S+A==",
"version": "2.4.2",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/logform/-/logform-2.4.2.tgz",
"integrity": "sha512-W4c9himeAwXEdZ05dQNerhFz2XG80P9Oj0loPUMV23VC2it0orMHQhJm4hdnnor3rd1HsGf6a2lPwBM1zeXHGw==",
"requires": {
"@colors/colors": "1.5.0",
"fecha": "^4.2.0",
@@ -18130,9 +18131,9 @@
}
},
"ts-proto": {
"version": "1.125.0",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/ts-proto/-/ts-proto-1.125.0.tgz",
"integrity": "sha512-ADXnF+Psk3SaLzxtXrhvKUDrNNpg7LnL5rQuQL+u9PiOQ4C2ktWLvJM0VtL4zqQ9/OHROmXjebpR0KMZAkI93w==",
"version": "1.126.1",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/ts-proto/-/ts-proto-1.126.1.tgz",
"integrity": "sha512-PKrcgd0mCQJDY7tp+th349uYhnjs2Tz7wSqm9+DBcodl3YCKPt1pFtFmApOZdQ8WlghhgKAuJDIRQJBd6jD5YA==",
"requires": {
"@types/object-hash": "^1.3.0",
"dataloader": "^1.4.0",
@@ -18486,10 +18487,11 @@
}
},
"winston": {
"version": "3.7.2",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/winston/-/winston-3.7.2.tgz",
"integrity": "sha512-QziIqtojHBoyzUOdQvQiar1DH0Xp9nF1A1y7NVy2DGEsz82SBDtOalS0ulTRGVT14xPX3WRWkCsdcJKqNflKng==",
"version": "3.8.2",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/winston/-/winston-3.8.2.tgz",
"integrity": "sha512-MsE1gRx1m5jdTTO9Ld/vND4krP2To+lgDoMEHGGa4HIlAUyXJtfc7CxQcGXVyz2IBpw5hbFkj2b/AtUdQwyRew==",
"requires": {
"@colors/colors": "1.5.0",
"@dabh/diagnostics": "^2.0.2",
"async": "^3.2.3",
"is-stream": "^2.0.0",
+2 -2
View File
@@ -26,8 +26,8 @@
},
"dependencies": {
"@aws-sdk/client-secrets-manager": "^3.112.0",
"@dadosfera/dadosfera-logs": "^1.0.0-beta.3",
"@dadosfera/protospack-v2": "3.17.2",
"@dadosfera/dadosfera-logs": "^1.0.0-beta.4",
"@dadosfera/protospack-v2": "3.18.7",
"@grpc/grpc-js": "^1.6.7",
"@grpc/proto-loader": "^0.6.13",
"@nestjs/common": "^8.4.7",
+1
View File
@@ -53,6 +53,7 @@ import { PipelinesV2Module } from './modules/pipelinesV2/pipelines.module';
InputsModule,
OauthModule,
PipelinesV2Module,
CatalogModule,
],
})
export class AppModule {}
+22 -12
View File
@@ -128,7 +128,7 @@ export const PERMISSIONS_GROUPS = {
DELETE: {
seqid: 38,
claim: 'connection:delete',
usage: PermissionUsages.PUBLIC,
usage: PermissionUsages.INTERNAL,
name: {
'pt-br': 'Excluir Fonte',
'en-us': 'Remove Source',
@@ -165,16 +165,16 @@ export const PERMISSIONS_GROUPS = {
'es-es': 'Crear VPN',
},
},
DELETE: {
seqid: 36,
claim: 'network_config:delete',
usage: PermissionUsages.PUBLIC,
name: {
'pt-br': 'Excluir VPN',
'en-us': 'Remove VPN',
'es-es': 'Eliminar VPN',
},
},
// DELETE: {
// seqid: 36,
// claim: 'network_config:delete',
// usage: PermissionUsages.PUBLIC,
// name: {
// 'pt-br': 'Excluir VPN',
// 'en-us': 'Remove VPN',
// 'es-es': 'Eliminar VPN',
// },
// },
},
},
@@ -503,7 +503,7 @@ export const PERMISSIONS_GROUPS = {
'es-es': 'Usuarios',
},
permissions: {
ADMIN: {
CONNECTIONS_MIGRATION: {
seqid: 40,
claim: 'dadosfera:connections-migration',
usage: PermissionUsages.INTERNAL,
@@ -513,6 +513,16 @@ export const PERMISSIONS_GROUPS = {
'es-es': 'connections-migration',
},
},
SYNC_USER: {
seqid: 41,
claim: 'dadosfera:sync-user',
usage: PermissionUsages.INTERNAL,
name: {
'pt-br': 'sync-user',
'en-us': 'sync-user',
'es-es': 'sync-user',
},
},
},
},
};
+38
View File
@@ -0,0 +1,38 @@
import {
ClientsProviderAsyncOptions,
GrpcOptions,
Transport,
} from '@nestjs/microservices';
import { credentials } from '@grpc/grpc-js';
import { Catalog } from '@dadosfera/protospack-v2';
export class CatalogClientConfiguration {
public name = 'CatalogClientConfiguration';
private config: GrpcOptions = {
transport: Transport.GRPC,
options: {
url: process.env.PIFACTORY_URL,
package: [
Catalog.ProtoPackages.ReadPackage,
Catalog.ProtoPackages.WritePackage,
],
credentials:
process.env.LOCAL_ENV || process.env.ENV === 'local'
? undefined
: credentials.createSsl(),
protoPath: [
Catalog.ProtoPaths.ReadFilePath,
Catalog.ProtoPaths.WriteFilePath,
],
loader: {
keepCase: true,
enums: String,
defaults: false,
},
},
};
providerOptions: ClientsProviderAsyncOptions = {
name: this.name,
...this.config,
};
}
+144 -27
View File
@@ -6,6 +6,7 @@ import {
Inject,
Param,
Post,
Put,
Query,
} from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
@@ -13,6 +14,8 @@ import { AuthenticateCondition } from '../../authentication/authentication.decor
import { PERMISSIONS_GROUPS } from '../../authentication/permissions.enum';
import { CatalogService } from './catalog.service';
import { DadosferaLogger } from '@dadosfera/dadosfera-logs';
import { PackTheMetadata } from 'src/utils/ PackTheMetadata';
import { RequestUser, User } from 'src/authentication/user.decorator';
@ApiTags('Catalog')
@Controller('catalog')
@@ -46,16 +49,72 @@ export class CatalogController {
this.logger = dadosferaLogger.logger;
}
@Put('manage_permissions/:id')
async manageDataAssetPermissions(
@Param('id') id: string,
@User() user: RequestUser,
@Body() body,
) {
const { customer_id, customer_name, user_id, username } = user;
const metadata = PackTheMetadata({
customer_id,
customer_name,
user_id,
username,
});
const response = await this.catalogService.managePermissions(
{ ...body, id },
metadata,
);
return { data_asset: JSON.parse(response.data_asset) };
}
@Put('revoke_permissions/:id')
async revokeDataAssetPermissions(
@Param('id') id: string,
@User() user: RequestUser,
@Body() body,
) {
const { customer_id, customer_name, user_id, username } = user;
const metadata = PackTheMetadata({
customer_id,
customer_name,
user_id,
username,
});
const response = await this.catalogService.revokePermissions(
{ ...body, id },
metadata,
);
return { message: response.message };
}
@Get('all')
async catalogAll(@Body() body) {
async catalogAll(@User() user: RequestUser, @Body() body, @Query() params) {
const { user_id, customer_name, customer_id, username } = user;
this.logger.info(`/catalog - ON CATALOG ALL ROUTE`, {
user: body.info.user_id,
customer: body.info.customer,
});
const res = await this.catalogService.catalogAll(body);
const roles = await this.catalogService.getUserRolesIds(user_id);
return res;
const metadata = PackTheMetadata({
user_id,
customer_id,
customer_name,
username,
roles,
});
const res = await this.catalogService.getAllOpenSearchDataAssets(
params,
metadata,
);
return res.data_assets;
}
@Get('data_apps')
@@ -96,30 +155,60 @@ export class CatalogController {
}
@Get('dashboard-metabase/:id')
async getOneDashboardMetabase(@Body() body, @Param() params) {
async getOneDashboardMetabase(
@Body() body,
@Param() params,
@User() user: RequestUser,
) {
const { id } = params;
this.logger.info(`/catalog - ON GET ONE DASHBOARD METABASE ROUTE`, {
user: body.info.user_id,
customer: body.info.customer,
});
const res = await this.catalogService.getOneDashboardMetabase(id, body);
const { username, user_id, customer_id, customer_name } = user;
const metadata = PackTheMetadata({
username,
user_id,
customer_id,
customer_name,
});
const res = await this.catalogService.getOneDashboardMetabase(
id,
body,
metadata,
);
return res;
}
@Get('table-metadata')
async getAllTableMetadata(@Body() body, @Query() query) {
async getAllTableMetadata(
@Body() body,
@Query() query,
@User() user: RequestUser,
) {
this.logger.info(`/catalog - ON GET ALL TABLES METADATA ROUTE`, {
user: body.info.user_id,
customer: body.info.customer,
user: user.user_id,
customer: user.customer_name,
});
const { user_id, customer_name, customer_id } = user;
const metadata = PackTheMetadata({
user_id,
customer_id,
customer_name,
});
if (!query) {
const res = await this.catalogService.getAllTableMetadata(body);
return res;
} else {
const res = await this.catalogService.getOneTableMetadata(body, query);
const res = await this.catalogService.getOneTableMetadata(
body,
query,
metadata,
);
return res;
}
}
@@ -211,15 +300,19 @@ export class CatalogController {
}
@Post('data-description')
async createDataDescription(@Body() body) {
async createDataDescription(@Body() body, @User() user: RequestUser) {
this.logger.info(`/catalog - ON CREATE DATA DESCRIPTION ROUTE`, {
user: body.info.user_id,
customer: body.info.customer,
user: user.user_id,
customer: user.customer_name,
});
const res = await this.catalogService.createDataDescription(body);
return res;
const { user_id, customer_name, customer_id } = user;
const metadata = PackTheMetadata({
user_id,
customer_id,
customer_name,
});
return await this.catalogService.createDataDescription(body, metadata);
}
@Get('data-docs')
@@ -322,15 +415,21 @@ export class CatalogController {
}
@Post('tags')
async createTags(@Body() body) {
async createTags(@Body() body, @User() user: RequestUser) {
this.logger.info(`/catalog - ON CREATE TAG ROUTE`, {
user: body.info.user_id,
customer: body.info.customer,
user: user.user_id,
customer: user.customer_name,
});
const { user_id, customer_name, customer_id } = user;
const metadata = PackTheMetadata({
user_id,
customer_id,
customer_name,
});
const res = await this.catalogService.createTags(body);
const res = await this.catalogService.createTags(body, metadata);
return res;
return res.data_assets;
}
@Get('tags')
@@ -340,7 +439,14 @@ export class CatalogController {
customer: body.info.customer,
});
const res = await this.catalogService.findAllTags(body);
const { user_id, customer, customer_id } = body.info;
const metadata = PackTheMetadata({
user_id,
customer_id,
customer_name: customer,
});
const res = await this.catalogService.findAllTags(body, metadata);
return res;
}
@@ -352,8 +458,14 @@ export class CatalogController {
customer: body.info.customer,
});
const { id } = params;
const res = await this.catalogService.deleteTags(id, body);
body.data_asset_id = id;
const { user_id, customer, customer_id } = body.info;
const metadata = PackTheMetadata({
user_id,
customer_id,
customer_name: customer,
});
const res = await this.catalogService.deleteTags(body, metadata);
return res;
}
@@ -370,14 +482,19 @@ export class CatalogController {
return res;
}
@Get('table-tags')
async getAllTableTags(@Body() body) {
@Get('table-tags/:data_asset_id')
async getAllTableTags(@Body() body, @Param() params) {
this.logger.info(`/catalog - ON GET ALL TABLE TAGS ROUTE`, {
user: body.info.user_id,
customer: body.info.customer,
});
const res = await this.catalogService.findAllTableTags(body);
const { user_id, customer, customer_id } = body.info;
const metadata = PackTheMetadata({
user_id,
customer_id,
customer_name: customer,
});
const res = await this.catalogService.findAllTableTags(params, metadata);
return res;
}
+12
View File
@@ -4,9 +4,21 @@ import { DadosferaLogger } from '@dadosfera/dadosfera-logs';
import { CatalogController } from './catalog.controller';
import { CatalogService } from './catalog.service';
import { CatalogClientConfiguration } from './catalog-client';
import { ClientsModule } from '@nestjs/microservices';
import { PipelinesModule as OldPipelineModule } from 'src/modules/pipelines/pipelines.module';
import { UsersModule } from '../users/users.module';
const client = new CatalogClientConfiguration();
@Module({
imports: [
ClientsModule.register([client.providerOptions]),
OldPipelineModule,
UsersModule,
],
controllers: [CatalogController],
providers: [CatalogService, DadosferaLogger],
exports: [CatalogService],
})
export class CatalogModule {}
+262 -33
View File
@@ -1,6 +1,45 @@
import DadosferaLogger from '@dadosfera/dadosfera-logs/dist';
import { ReadService } from '@dadosfera/protospack-v2/dist/lib/Catalog';
import { ProtoServices } from '@dadosfera/protospack-v2/dist/lib/Catalog';
import { Messages } from '@dadosfera/protospack-v2/dist/lib/Catalog';
import { WriteService } from '@dadosfera/protospack-v2/dist/lib/Catalog';
import {
HttpException,
HttpStatus,
Inject,
OnModuleInit,
} from '@nestjs/common';
import { ClientGrpc } from '@nestjs/microservices';
import axios from 'axios';
import { lastValueFrom } from 'rxjs';
import { CatalogClientConfiguration } from './catalog-client';
import { UsersService } from '../users/users.service';
class CatalogService implements OnModuleInit {
catalogReadService: ReadService.CatalogReadServices;
catalogWriteService: WriteService.CatalogWriteServices;
logger: any;
constructor(
@Inject(DadosferaLogger)
dadosferaLogger: DadosferaLogger,
@Inject(CatalogClientConfiguration.name)
private readonly grpcClient: ClientGrpc,
private readonly userService: UsersService,
) {
this.logger = dadosferaLogger.logger;
}
onModuleInit() {
this.catalogReadService =
this.grpcClient.getService<ReadService.CatalogReadServices>(
ProtoServices.CatalogReadServices,
);
this.catalogWriteService =
this.grpcClient.getService<WriteService.CatalogWriteServices>(
ProtoServices.CatalogWriteServices,
);
}
class CatalogService {
_getNimbusUrl(body) {
const customer = body.info.customer.toLowerCase();
@@ -8,7 +47,36 @@ class CatalogService {
return `https://nimbus-${customer}.dadosfera.ai`;
}
return `https://nimbus-${customer}.${process.env.ENV}.dadosfera.ai`;
return `https://nimbus-${customer}.${process.env.ENV.replace(
'local',
'stg',
)}.dadosfera.ai`;
}
async managePermissions(data: Messages.ManagePermissionRequest, metadata) {
this.logger.info('CatalogService - Manage Data assets permissions');
return lastValueFrom(
this.catalogWriteService.ManagePermission(data, metadata),
).catch((err) => {
throw new HttpException(
err.details,
err.code === 6 ? HttpStatus.CONFLICT : 404,
);
});
}
async revokePermissions(data: Messages.RevokePermissionRequest, metadata) {
this.logger.info('CatalogService - Manage Data assets permissions');
return lastValueFrom(
this.catalogWriteService.RevokePermission(data, metadata),
).catch((err) => {
throw new HttpException(
err.details,
err.code === 6 ? HttpStatus.CONFLICT : 404,
);
});
}
async catalogAll(body) {
@@ -41,17 +109,87 @@ class CatalogService {
return data;
}
async getOneDashboardMetabase(id, body) {
async getUserRolesIds(userId: string) {
const result = await this.userService.findOneById(userId).catch(() => null);
const roles_ids = result.user.roles.map((role) => role.id);
return roles_ids;
}
async getAllOpenSearchDataAssets(
data: Messages.GetAllDataAssetsRequest,
metadata,
) {
this.logger.info('CatalogService - getAllOpenSearchDashboard');
const response = await lastValueFrom(
this.catalogReadService.GetAllDataAssets(data, metadata),
)
.then((res) => {
this.logger.info('Done');
return JSON.parse(res.data_assets);
})
.catch((err) => {
this.logger.error(err.message);
throw new Error(err);
});
for (const asset of response.tables) {
const condition =
asset.owner && !asset.owner.includes('@') ? true : false;
const result = condition
? await this.userService.findOneById(asset.owner).catch(() => null)
: null;
const owner = result !== null ? result.user.username : null;
Object.assign(asset, { ...asset, owner });
}
for (const asset of response.dashboards) {
const condition =
asset.owner && !asset.owner.includes('@') ? true : false;
const result = condition
? await this.userService.findOneById(asset.owner).catch(() => null)
: null;
const owner = result !== null ? result.user.username : null;
Object.assign(asset, { ...asset, owner });
}
return { data_assets: response };
}
async getOneDashboardMetabase(id, body, metadata) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(
`${nimbusUrl}/api/catalog/dashboard-metabase/${id}`,
);
// const [, path] = data.iframe_url.split('.dadosfera');
// const host = `httpss://metabase-${body.info.customer.toLowerCase()}.dadosfera.ai`;
// data.iframe_url = host + path;
const { data_asset } = await lastValueFrom(
this.catalogReadService.GetOneDataAsset(
{ id, type: 'dashboard' },
metadata,
),
);
const opensearchTable = JSON.parse(data_asset);
return data;
const result = opensearchTable.user_id
? await this.userService
.findOneById(opensearchTable.owner)
.catch(() => null)
: null;
const owner = result !== null ? result.user.username : null;
return {
...data,
tags: opensearchTable.tags,
description: opensearchTable.description || null,
owner,
};
}
async getAllTableMetadata(body) {
@@ -62,12 +200,37 @@ class CatalogService {
return data;
}
async getOneTableMetadata(body, params) {
async getOneTableMetadata(body, params, metadata) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(
`${nimbusUrl}/api/catalog/table-metadata/`,
{ params: params },
);
if (data?.length === 1) {
const { data_asset } = await lastValueFrom(
this.catalogReadService.GetOneDataAsset(
{ id: data[0].id, type: 'dataset' },
metadata,
),
);
const opensearchTable = JSON.parse(data_asset);
const result = opensearchTable.user_id
? await this.userService
.findOneById(opensearchTable.owner)
.catch(() => null)
: null;
const owner = result !== null ? result.user.username : null;
return [
{
...data[0],
tags: opensearchTable.tags,
table_description: opensearchTable.description,
owner,
},
];
}
return data;
}
@@ -127,13 +290,34 @@ class CatalogService {
return data;
}
async createDataDescription(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.post(
`${nimbusUrl}/api/catalog/data-description/`,
body,
async createDataDescription(body, metadata) {
const response = await lastValueFrom(
this.catalogWriteService.UpdateDataAsset(
{
id: `dataset-${body.table_id}`,
description: body.description,
tags: undefined,
},
metadata,
),
);
return data;
// {
// description: 'descrição nova';
// id: 5;
// table_id: 4;
// }
// const nimbusUrl = this._getNimbusUrl(body);
// const { data } = await axios.post(
// `${nimbusUrl}/api/catalog/data-description/`,
// body,
// );
// {"id":5,"description":"descrição nova","updated_at":"2022-09-28T14:35:15.618750Z","table_id":4}
return {
id: 0,
description: body.description,
updated_at: new Date().toISOString(),
table_id: body.table_id,
};
}
async getDataDocs(body) {
@@ -197,31 +381,76 @@ class CatalogService {
return data;
}
async createTags(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.post(`${nimbusUrl}/api/catalog/tags/`, body);
return data;
async createTags(data: Messages.TagTableRequest, metadata) {
this.logger.info('CatalogService - createTags');
const response = await lastValueFrom(
this.catalogWriteService.TagTable(data, metadata),
)
.then((res) => {
this.logger.info('Done');
return res;
})
.catch((err) => {
this.logger.error(err.message);
throw new Error(err);
});
return { data_assets: response };
}
async findAllTags(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(`${nimbusUrl}/api/catalog/tags/`, body);
return data;
async findAllTags(data, metadata) {
this.logger.info('CatalogService - findAllCustomerTags');
const response = await lastValueFrom(
this.catalogReadService.GetCustomerTags(data, metadata),
)
.then((res) => {
this.logger.info('Done');
return res;
})
.catch((err) => {
this.logger.error(err.message);
throw new Error(err);
});
return response;
}
async findAllTableTags(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(
`${nimbusUrl}/api/catalog/table-tags/`,
body,
);
return data;
async findAllTableTags(data, metadata) {
this.logger.info('CatalogService - findAllTableTags');
const response = await lastValueFrom(
this.catalogReadService.GetTableTags(data, metadata),
)
.then((res) => {
this.logger.info('Done');
return res;
})
.catch((err) => {
this.logger.error(err.message);
throw new Error(err);
});
return response;
}
async deleteTags(id, body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.delete(`${nimbusUrl}/api/catalog/tags/${id}`);
return data;
async deleteTags(data, metadata) {
this.logger.info('CatalogService - deleteTags');
const response = await lastValueFrom(
this.catalogWriteService.UntagTable(data, metadata),
)
.then((res) => {
this.logger.info('Done');
return res;
})
.catch((err) => {
this.logger.error(err.message);
throw new Error(err);
});
return response;
}
async createTableTags(body) {
@@ -45,7 +45,9 @@ export class ConnectionController {
}
@Get('connections-migration')
@RequireAllPermissions(PERMISSIONS_GROUPS.DADOSFERA.permissions.ADMIN)
@RequireAllPermissions(
PERMISSIONS_GROUPS.DADOSFERA.permissions.CONNECTIONS_MIGRATION,
)
async synchronizeConnections(@Query('apply') apply: string) {
return this.clientService.synchronizeConnections(apply === 'true');
}
-2
View File
@@ -45,7 +45,6 @@ export class ConnectorClientService implements OnModuleInit {
return lastValueFrom(
this.connectorServiceWrite.RegisterConnector(serviceBody),
).catch((err) => {
console.log(err.details);
throw new HttpException(
err.details,
err.code === 6 ? HttpStatus.CONFLICT : 400,
@@ -64,7 +63,6 @@ export class ConnectorClientService implements OnModuleInit {
return lastValueFrom(this.connectorServiceWrite.UploadFile(body)).catch(
(err) => {
console.log(err.details);
throw new HttpException(
err.details,
err.code === 6 ? HttpStatus.CONFLICT : 400,
@@ -86,7 +86,7 @@ export class ConnectorController {
@ApiConsumes('multipart/form-data')
@UseInterceptors(FileInterceptor('file'))
async uploadConnectorsFile(@UploadedFile() file: UploadConnectorsFileDto) {
console.log(`/upload`, 'Upload Connector Route');
this.logger.info(`/upload`, 'Upload Connector Route');
const response = await this.connectorClientService.uploadConnectorsFile({
file,
@@ -25,7 +25,10 @@ import {
UpdateNetworkConfigRes,
} from './dto/network-config';
import { FileInterceptor } from '@nestjs/platform-express';
import { PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum';
import { RequireAllPermissions } from 'src/authentication/authentication.decorator';
const networkConfigPermissions = PERMISSIONS_GROUPS.NETWORK_CONFIG.permissions;
@ApiTags('Network Config')
@Controller('network-config')
export class NetworkConfigController {
@@ -92,6 +95,7 @@ export class NetworkConfigController {
@Post()
@ApiOkResponse({ type: CreateNetworkConfigRes })
@RequireAllPermissions(networkConfigPermissions.CREATE)
@ApiConsumes('multipart/form-data')
@UseInterceptors(FileInterceptor('ovpn_file'))
async createNetworkConfigs(
@@ -111,36 +115,37 @@ export class NetworkConfigController {
});
}
@Patch(':id')
@ApiOkResponse({ type: UpdateNetworkConfigRes })
async updateNetworkConfig(
@User() user: RequestUser,
@Param('id') network_config_id: string,
@Body() body: UpdateNetworkConfigReq,
) {
this.logger.info('PATCH /network-config/:id', {
user: user.user_id,
customer: user.customer_name,
});
return this.networkConfigService.updateNetworkConfig(
body,
network_config_id,
);
}
// @Patch(':id')
// @ApiOkResponse({ type: UpdateNetworkConfigRes })
// @RequireAllPermissions(networkConfigPermissions.CREATE)
// async updateNetworkConfig(
// @User() user: RequestUser,
// @Param('id') network_config_id: string,
// @Body() body: UpdateNetworkConfigReq,
// ) {
// this.logger.info('PATCH /network-config/:id', {
// user: user.user_id,
// customer: user.customer_name,
// });
// return this.networkConfigService.updateNetworkConfig(
// body,
// network_config_id,
// );
// }
@Delete(':id')
@ApiOkResponse({ type: DeleteNetworkConfigRes })
async deleteNetworkConfig(
@User() user: RequestUser,
@Param('id') network_config_id: string,
) {
this.logger.info('DELETE /network-config', {
user: user.user_id,
customer: user.customer_name,
});
return this.networkConfigService.deleteNetworkConfig(network_config_id, {
customer_name: user.customer_name,
customer_id: user.customer_id,
});
}
// @Delete(':id')
// @ApiOkResponse({ type: DeleteNetworkConfigRes })
// async deleteNetworkConfig(
// @User() user: RequestUser,
// @Param('id') network_config_id: string,
// ) {
// this.logger.info('DELETE /network-config', {
// user: user.user_id,
// customer: user.customer_name,
// });
// return this.networkConfigService.deleteNetworkConfig(network_config_id, {
// customer_name: user.customer_name,
// customer_id: user.customer_id,
// });
// }
}
+2
View File
@@ -98,6 +98,8 @@ export class UpdateUserReq {
@ApiPropertyOptional()
name?: string;
@ApiPropertyOptional()
email?: string;
@ApiPropertyOptional()
jobTitle?: string;
@ApiPropertyOptional()
department?: string;
+16 -2
View File
@@ -45,6 +45,7 @@ import {
UserByCustomer,
} from './dtos/entities';
import { UsersService } from './users.service';
import { Metadata } from '@grpc/grpc-js';
// TODO GET de hierarquias e do PATCH em usuário
@ApiTags('Users')
@@ -141,9 +142,12 @@ export class UsersController {
@Body() body: CreateUserReq,
@Headers('dadosfera-lang') language,
) {
const meta = new Metadata();
meta.add('access_token', user.access_token);
this.logger.info('createUser', { user });
this.userService.setLanguage(language);
return await this.userService.createUser(body);
return await this.userService.createUser(body, meta);
}
@Post('batch')
@@ -154,9 +158,11 @@ export class UsersController {
@Body() body: BatchCreateUserReq,
@Headers('dadosfera-lang') language,
) {
const meta = new Metadata();
meta.add('access_token', user.access_token);
this.logger.info('batchCreateUser', { user });
this.userService.setLanguage(language);
return await this.userService.batchCreateUser(body);
return await this.userService.batchCreateUser(body, meta);
}
@Post(':id/resend-invite')
@@ -235,4 +241,12 @@ export class UsersController {
this.userService.setLanguage(language);
return await this.userService.updateUser(body, id, user.customer_id);
}
@Post('synchronize/:id')
@RequireAllPermissions(PERMISSIONS_GROUPS.DADOSFERA.permissions.SYNC_USER)
@ApiOkResponse({ type: UpdateUserRes })
async synchronizeUser(@User() user: RequestUser, @Param('id') id: string) {
this.logger.info('synchronizeUser', { user });
return await this.userService.synchronizeUser(id);
}
}
+30 -16
View File
@@ -27,6 +27,7 @@ import { LanguageEnum } from 'src/utils/languages.enum';
import { UserByCustomer } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/entities';
import { EnrichErrorCode } from 'src/utils/ErrorBuilder';
import { DucClient } from '../duc/client.config';
import { Metadata } from '@grpc/grpc-js';
@Injectable()
export class UsersService implements OnModuleInit {
@@ -83,24 +84,27 @@ export class UsersService implements OnModuleInit {
return { user: this.adjustUsersPayload([user])[0] };
}
async createUser(req: CreateUserReq) {
async createUser(req: CreateUserReq, meta?: Metadata) {
const { email, department, hierarchy, jobTitle, name, roleNames } = req;
const { user } = await lastValueFrom(
this.usersClientService.UserCreate({
email,
hierarchy,
name,
roleIds: [],
department,
jobTitle,
roleNames,
}),
this.usersClientService.UserCreate(
{
email,
hierarchy,
name,
roleIds: [],
department,
jobTitle,
roleNames,
},
meta,
),
);
return { user: this.adjustUsersPayload([user])[0] };
}
async updateUser(req: UpdateUserReq, id: string, customerId: string) {
const { department, hierarchy, jobTitle, name, roleNames } = req;
const { department, hierarchy, jobTitle, name, roleNames, email } = req;
if (roleNames) {
await this.setRoles({ roleNames, userId: id }, customerId);
}
@@ -112,6 +116,7 @@ export class UsersService implements OnModuleInit {
department,
hierarchy,
jobTitle,
email,
}),
);
return { user: this.adjustUsersPayload([user])[0] };
@@ -133,7 +138,8 @@ export class UsersService implements OnModuleInit {
return { user: this.adjustUsersPayload([user])[0] };
}
async batchCreateUser({ users }: BatchCreateUserReq) {
async batchCreateUser(req: BatchCreateUserReq, meta?: Metadata) {
const { users } = req;
const usersToCreate: UserCreateRequest[] = users.map(
({ roleNames, email, department, hierarchy, jobTitle, name }) => ({
roleNames,
@@ -146,14 +152,16 @@ export class UsersService implements OnModuleInit {
}),
);
const { errorUsers, usersCreated } = await lastValueFrom(
this.usersClientService.UserBatchCreate({
users: usersToCreate,
}),
this.usersClientService.UserBatchCreate(
{
users: usersToCreate,
},
meta,
),
);
return {
usersCreated: this.adjustUsersPayload(usersCreated),
// mapping error code to message
errorUsers: errorUsers.map(({ user, error }) => ({
user,
error: EnrichErrorCode(error).message,
@@ -211,4 +219,10 @@ export class UsersService implements OnModuleInit {
async findAllCustomers() {
return await lastValueFrom(this.customersClientService.CustomerFindAll({}));
}
async synchronizeUser(userId: string) {
return await lastValueFrom(
this.usersClientService.INTERNAL_UserSynchronize({ userId }),
);
}
}
+1
View File
@@ -7,6 +7,7 @@ interface IMetadata {
user_id?: string;
language?: string;
details?: string;
roles?: string[];
}
export function PackTheMetadata(info: IMetadata): Metadata {
+8
View File
@@ -185,6 +185,14 @@ export function EnrichErrorCode(code: string) {
code,
};
case ErrorCodes.USER.NOT_CREATED:
return {
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
error: 'Ocorreu um erro ao criar seu usúario',
message: 'Tente novamente ou entre em contato com o suporte',
code,
};
case ErrorCodes.USER.NOT_FOUND:
return {
statusCode: HttpStatus.NOT_FOUND,
+1
View File
@@ -31,6 +31,7 @@ export const USER = {
ALREADY_EXISTS: 'USER.ALREADY_EXISTS',
ROLE_ALREADY_ASSIGNED: 'USER.ROLE_ALREADY_ASSIGNED',
ROLE_NOT_ASSIGNED: 'USER.ROLE_NOT_ASSIGNED',
NOT_CREATED: 'USER.NOT_CREATED',
};
export const CUSTOMER = {
+1 -1
View File
File diff suppressed because one or more lines are too long