import { Body, Controller, Get, Headers, HttpException, Inject, Param, Post, Put, Query, UnsupportedMediaTypeException, } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { AuthenticateCondition, Authenticated, } from '../../authentication/authentication.decorator'; 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'; import { ICatalogAllResponse, IColumnsMetadataResponse, IDocsResponse, IPreviewResponse, } from './dtos'; @ApiTags('Catalog') @Controller('catalog') @Authenticated() @AuthenticateCondition((req, user) => { if (req.path.includes('/manage_permissions/')) return true; let action; switch (req.method) { case 'POST': action = 'CREATE'; break; case 'PUT': action = 'UPDATE'; break; default: action = req.method; } return user.permissions.includes( PERMISSIONS_GROUPS.CATALOG.permissions[action].seqid, ); }) export class CatalogController { logger: DadosferaLogger; constructor( @Inject(DadosferaLogger) dadosferaLogger: DadosferaLogger, private catalogService: CatalogService, ) { this.logger = dadosferaLogger.logger; } @Get() async catalogAll( @User() user: RequestUser, @Query() query, ): Promise { const { user_id, customer_name, customer_id, username, permissions } = user; this.logger.info(`/catalog - Catalog all data assets`, { user_id, customer_name, }); const is_data_manager = permissions.includes( PERMISSIONS_GROUPS.CATALOG.permissions.DATA_MANAGER.seqid, ); const roles = await this.catalogService.getUserRolesIds(user_id); const metadata = PackTheMetadata({ user_id, customer_id, customer_name, username, roles, is_data_manager, }); const res = await this.catalogService.getAllOpenSearchDataAssets( query, metadata, customer_id, ); return { ...res }; } @Get('tags') async findAllTags(@Body() body) { this.logger.info(`/catalog - ON FIND ALL TAGS ROUTE`, { user: body.info.user_id, customer: body.info.customer, }); 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; } @Get('data-asset/:id') async getDataAsset( @User() user: RequestUser, @Headers() headers, @Param('id') id, ) { const { username, user_id, customer_id, customer_name, permissions } = user; const [data_asset_type, data_asset_id] = id.split('-'); this.logger.info(`/catalog - ON GET ONE DASHBOARD METABASE ROUTE`, { username, customer_name, }); const is_data_manager = permissions.includes( PERMISSIONS_GROUPS.CATALOG.permissions.DATA_MANAGER.seqid, ); let has_permission = false; const metadata = PackTheMetadata({ username, user_id, customer_id, customer_name, }); const user_roles = await this.catalogService.getUserRolesIds(user_id); const { data_asset } = await this.catalogService.getOneDataAsset({ customer_id, data_asset_id, data_asset_type, metadata, }); if (data_asset?.owner === username) has_permission = true; for (const role of user_roles) { if (data_asset.p_roles.includes(role)) has_permission = true; } if (data_asset.p_users.includes(user_id)) has_permission = true; if (is_data_manager || has_permission) { delete data_asset.p_roles; delete data_asset.p_users; return { data_asset }; } throw new HttpException( 'You do not have permission to access this data asset.', 403, ); } @Get('data-asset/:id/columns-metadata') async getDataAssetColumnsMetadata( @User() user: RequestUser, @Headers('Dadosfera-Lang') language, @Param('id') id, ): Promise { const { customer_name, customer_id, user_id, username } = user; const data_asset_type = id.split('-')[0]; const supported_data_assets = ['dataset']; if (!supported_data_assets.includes(data_asset_type)) { throw new UnsupportedMediaTypeException( `${data_asset_type} does not have a preview function for the time being.`, ); } this.logger.info(`/catalog - ON GET DATA DOCS ROUTE`, { user_id, customer_name, }); const metadata = PackTheMetadata({ customer_name, customer_id, user_id, username, language, }); const columns_metadata = await this.catalogService.getDatasetColumnsMetadata(id, metadata); return { columns_metadata }; } @Get('data-asset/:id/preview') async getDataAssetPreview( @User() user: RequestUser, @Headers('Dadosfera-lang') language, @Param('id') id, ): Promise { const { customer_name, customer_id, user_id, username } = user; const data_asset_type = id.split('-')[0]; const supported_data_assets = ['dataset']; if (!supported_data_assets.includes(data_asset_type)) { throw new UnsupportedMediaTypeException( `${data_asset_type} does not have a preview function for the time being.`, ); } this.logger.info(`/catalog - ON GET DATA DOCS ROUTE`, { user_id, customer_name, }); const metadata = PackTheMetadata({ customer_name, customer_id, user_id, username, language, }); const preview = await this.catalogService.getDatasetPreview(id, metadata); return { preview }; } @Get('data-asset/:id/docs') async getDataAssetDocs( @User() user: RequestUser, @Headers('Dadosfera-Lang') language, @Param('id') id, ): Promise { const { customer_name, customer_id, user_id, username } = user; const data_asset_type = id.split('-')[0]; const supported_data_assets = ['dataset']; if (!supported_data_assets.includes(data_asset_type)) { throw new UnsupportedMediaTypeException( `${data_asset_type} does not have a documentation function for the time being.`, ); } this.logger.info(`/catalog - ON GET DATA DOCS ROUTE`, { user_id, customer_name, }); const metadata = PackTheMetadata({ customer_name, customer_id, user_id, username, language, }); const docs = await this.catalogService.getDataDocs(id, metadata); return { docs }; } @Put('data-asset/:id') async updateDataAsset( @User() user: RequestUser, @Headers() headers, @Param('id') id, ) { console.log(user, headers); return { data_asset_id: id, message: 'Under development' }; } @Post('data-asset/:id/docs') async manageDataAssetDocs( @User() user: RequestUser, @Headers() headers, @Param('id') data_asset_id, @Body('docs') docs: string, ) { const { user_id, customer_name } = user; const [data_asset_type, id] = data_asset_id.split('-'); this.logger.info(`/catalog - ON GET DATA DOCS ROUTE`, { user_id, customer_name, }); const res = await this.catalogService.createDataDocs({ table_id: id, docs, info: { customer: customer_name, }, }); return res; } @Post('data-asset/:id/comment') async makeAComment( @User() user: RequestUser, @Headers() headers, @Param('id') id, ) { console.log(user, headers); return { data_asset_id: id, message: 'Under development' }; } @Put('data-asset/:id/manage-permissions') 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('data-asset/:id/revoke-permissions') 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 }; } }