mirror of
https://github.com/dadosfera/maestro.git
synced 2026-11-11 08:39:09 +00:00
Compare commits
23
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7f410831f | ||
|
|
cd2c53b5c5 | ||
|
|
adf1b3b97e | ||
|
|
d84b5e184b | ||
|
|
6d608a0457 | ||
|
|
b8be2c7803 | ||
|
|
24fce721e3 | ||
|
|
23a9a27db1 | ||
|
|
0f5ed50af9 | ||
|
|
5f8f6a64ab | ||
|
|
8800ac2736 | ||
|
|
bdb82c2ce4 | ||
|
|
6d9ecc3568 | ||
|
|
7764447adc | ||
|
|
576fdecf89 | ||
|
|
3de1e90fa8 | ||
|
|
5e90950660 | ||
|
|
3ed26e648f | ||
|
|
fff3523152 | ||
|
|
19e4daeea4 | ||
|
|
8624d3f016 | ||
|
|
dc1d1400d8 | ||
|
|
06ba759ea3 |
@@ -56,9 +56,9 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Helmfile
|
- name: Install Helmfile
|
||||||
run: |
|
run: |
|
||||||
wget https://github.com/helmfile/helmfile/releases/download/v0.148.0/helmfile_0.148.0_linux_amd64.tar.gz
|
curl -fsSLO https://github.com/helmfile/helmfile/releases/download/v0.148.0/helmfile_0.148.0_linux_amd64.tar.gz
|
||||||
tar -xzf helmfile_0.148.0_linux_amd64.tar.gz
|
tar -xzf helmfile_0.148.0_linux_amd64.tar.gz
|
||||||
mv helmfile /usr/local/bin/
|
sudo mv helmfile /usr/local/bin/
|
||||||
helmfile --version
|
helmfile --version
|
||||||
|
|
||||||
- name: Install Helm Diff Plugin
|
- name: Install Helm Diff Plugin
|
||||||
|
|||||||
@@ -4,9 +4,18 @@ metadata:
|
|||||||
annotations:
|
annotations:
|
||||||
nginx.ingress.kubernetes.io/whitelist-source-range: "69.49.241.121/32" # hostgator ip
|
nginx.ingress.kubernetes.io/whitelist-source-range: "69.49.241.121/32" # hostgator ip
|
||||||
nginx.ingress.kubernetes.io/proxy-body-size: "0"
|
nginx.ingress.kubernetes.io/proxy-body-size: "0"
|
||||||
|
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
|
||||||
|
nginx.ingress.kubernetes.io/proxy-connect-timeout: "300"
|
||||||
|
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
|
||||||
nginx.ingress.kubernetes.io/server-snippet: |
|
nginx.ingress.kubernetes.io/server-snippet: |
|
||||||
underscores_in_headers on;
|
underscores_in_headers on;
|
||||||
ignore_invalid_headers on;
|
ignore_invalid_headers on;
|
||||||
|
nginx.ingress.kubernetes.io/proxy-buffer-size: "16k"
|
||||||
|
nginx.ingress.kubernetes.io/proxy-buffers-number: "8"
|
||||||
|
nginx.ingress.kubernetes.io/proxy-busy-buffers-size: "64k"
|
||||||
|
{{- if .Values.maestro.restricted_ip}}
|
||||||
|
nginx.ingress.kubernetes.io/whitelist-source-range: {{ .Values.maestro.restricted_ip }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
generation: 1
|
generation: 1
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import jwt, { JwtPayload } from 'jsonwebtoken';
|
||||||
|
|
||||||
|
export function extractUserFrom(aRawJwt: string) {
|
||||||
|
const decodedToken = jwt.decode(aRawJwt, {
|
||||||
|
complete: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const payload = decodedToken.payload as JwtPayload;
|
||||||
|
|
||||||
|
return {
|
||||||
|
user_id: payload.user_id,
|
||||||
|
username: payload.username,
|
||||||
|
permissions: payload.permissions,
|
||||||
|
customer_id: payload.customer_id,
|
||||||
|
customer_name: payload.customer_name,
|
||||||
|
customer_tier: payload.customer_tier,
|
||||||
|
customer_modules: payload.customer_modules,
|
||||||
|
access_token: aRawJwt,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ async function bootstrap() {
|
|||||||
corsOrigins.push(
|
corsOrigins.push(
|
||||||
'https://app.stg.dadosfera.ai',
|
'https://app.stg.dadosfera.ai',
|
||||||
'https://app.dadosfera.ai',
|
'https://app.dadosfera.ai',
|
||||||
|
'https://private-frontend.stg.dadosfera.ai',
|
||||||
'https://unimed.dadosfera.ai',
|
'https://unimed.dadosfera.ai',
|
||||||
'https://boston-scientific.dadosfera.ai',
|
'https://boston-scientific.dadosfera.ai',
|
||||||
'https://plataforma.dadosfera.ai'
|
'https://plataforma.dadosfera.ai'
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Controller, Post, Body, Put, Get} from '@nestjs/common';
|
import { Controller, Body, Put, Get, NotFoundException} from '@nestjs/common';
|
||||||
import { AssignService } from './assign.service';
|
import { AssignService } from './assign.service';
|
||||||
import { CreateAssignDto } from './dto/create-assign.dto';
|
import { CreateAssignDto } from './dto/create-assign.dto';
|
||||||
import { Authenticated, RequireModule, RequireSomePermission } from 'src/decorators/authentication.decorator';
|
import { Authenticated, RequireModule, RequireSomePermission } from 'src/decorators/authentication.decorator';
|
||||||
@@ -28,6 +28,10 @@ export class AssignController {
|
|||||||
@RequireModule(DADOSFERA_MODULES_KEYS.EMBED_ASSIGNED)
|
@RequireModule(DADOSFERA_MODULES_KEYS.EMBED_ASSIGNED)
|
||||||
async get(@User() user: RequestUser) {
|
async get(@User() user: RequestUser) {
|
||||||
const metadata = PackTheMetadata(user);
|
const metadata = PackTheMetadata(user);
|
||||||
return await this.assignService.get(metadata);
|
try {
|
||||||
|
return await this.assignService.get(metadata);
|
||||||
|
} catch (error) {
|
||||||
|
throw new NotFoundException(error.message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ import jwt, { JwtPayload } from 'jsonwebtoken';
|
|||||||
import { LanguageEnum } from 'src/utils/languages.enum';
|
import { LanguageEnum } from 'src/utils/languages.enum';
|
||||||
import { Language } from 'src/decorators/language.decorator';
|
import { Language } from 'src/decorators/language.decorator';
|
||||||
import { ApiInternalOnlyEndpoint } from 'src/decorators/swagger.decorator';
|
import { ApiInternalOnlyEndpoint } from 'src/decorators/swagger.decorator';
|
||||||
import { Cookie } from 'express-session';
|
|
||||||
|
|
||||||
type CookiesValues = {
|
type CookiesValues = {
|
||||||
accessToken?: string;
|
accessToken?: string;
|
||||||
@@ -498,29 +497,10 @@ export class AuthController {
|
|||||||
const userId = req.cookies['ddf-user-id'];
|
const userId = req.cookies['ddf-user-id'];
|
||||||
|
|
||||||
this.logger.info('Has cookie: ' + Boolean(accessToken))
|
this.logger.info('Has cookie: ' + Boolean(accessToken))
|
||||||
let payload: any;
|
|
||||||
let userInfo: any = {};
|
|
||||||
try {
|
try {
|
||||||
// Decodifica e valida o JWT de acesso
|
// Decodifica e valida o JWT de acesso
|
||||||
const decoded: any = accessToken && jwt.decode(accessToken, { complete: true });
|
const userDto = await this.authClient.extractUserFrom(accessToken);
|
||||||
if (!decoded) throw new Error('Invalid token')
|
return res.status(200).json(userDto);
|
||||||
const { kid } = decoded.header;
|
|
||||||
// Busca a chave pública
|
|
||||||
const { keys } = await this.authClient.getPublicKeys();
|
|
||||||
const pemValue = keys.find((k) => k.kid === kid)?.pem;
|
|
||||||
if (!pemValue) throw new Error('Public key not found');
|
|
||||||
jwt.verify(accessToken, pemValue);
|
|
||||||
payload = decoded.payload;
|
|
||||||
userInfo = {
|
|
||||||
id: payload.user_id,
|
|
||||||
name: payload.username,
|
|
||||||
customer: {
|
|
||||||
id: payload.customer_id,
|
|
||||||
name: payload.customer_name,
|
|
||||||
tier: payload.customer_tier,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return res.status(200).json(userInfo);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error(err.message);
|
this.logger.error(err.message);
|
||||||
const refreshToken = req.cookies['ddf-refresh-auth'];
|
const refreshToken = req.cookies['ddf-refresh-auth'];
|
||||||
@@ -545,18 +525,8 @@ export class AuthController {
|
|||||||
userId
|
userId
|
||||||
});
|
});
|
||||||
// Decodifica novo token
|
// Decodifica novo token
|
||||||
const decoded: any = jwt.decode(data.accessToken, { complete: true });
|
const userDto = await this.authClient.extractUserFrom(accessToken);
|
||||||
const payload = decoded.payload;
|
return res.status(200).json(userDto);
|
||||||
userInfo = {
|
|
||||||
id: payload.user_id,
|
|
||||||
name: payload.username,
|
|
||||||
customer: {
|
|
||||||
id: payload.customer_id,
|
|
||||||
name: payload.customer_name,
|
|
||||||
tier: payload.customer_tier,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return res.status(200).json(userInfo);
|
|
||||||
} catch (refreshErr) {
|
} catch (refreshErr) {
|
||||||
this.logger.error(refreshErr)
|
this.logger.error(refreshErr)
|
||||||
return res.status(401).json({ error: 'Not authenticated' });
|
return res.status(401).json({ error: 'Not authenticated' });
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { DadosferaLogger } from '@dadosfera/dadosfera-logs';
|
|||||||
import { lastValueFrom } from 'rxjs';
|
import { lastValueFrom } from 'rxjs';
|
||||||
|
|
||||||
import { ProtoServices } from '@dadosfera/protospack-v2/dist/lib/Duc';
|
import { ProtoServices } from '@dadosfera/protospack-v2/dist/lib/Duc';
|
||||||
import { AuthProtoService as AuthServiceInterface, IdentityProviderProtoService } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/write-service';
|
import { AuthProtoService as AuthServiceInterface, IdentityProviderProtoService, UsersProtoService } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/write-service';
|
||||||
import {
|
import {
|
||||||
AuthSnowflakeSignInRequest,
|
AuthSnowflakeSignInRequest,
|
||||||
AuthSignInRequest,
|
AuthSignInRequest,
|
||||||
@@ -21,18 +21,18 @@ import {
|
|||||||
} from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/messages';
|
} from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/messages';
|
||||||
import { DucClient } from '../duc/client.config';
|
import { DucClient } from '../duc/client.config';
|
||||||
import { Metadata } from '@grpc/grpc-js';
|
import { Metadata } from '@grpc/grpc-js';
|
||||||
import { BulkEditResponse } from './dtos/login';
|
import { BulkEditResponse, UserDTO } from './dtos/login';
|
||||||
|
import jwt from 'jsonwebtoken';
|
||||||
|
import { PackTheMetadata } from 'src/utils/PackTheMetadata';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthClientService implements OnModuleInit {
|
export class AuthClientService implements OnModuleInit {
|
||||||
|
|
||||||
|
|
||||||
logger: DadosferaLogger;
|
logger: DadosferaLogger;
|
||||||
|
|
||||||
|
|
||||||
private authService: AuthServiceInterface;
|
private authService: AuthServiceInterface;
|
||||||
private identityProviderService: IdentityProviderProtoService;
|
private userService: UsersProtoService;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DadosferaLogger)
|
@Inject(DadosferaLogger)
|
||||||
dadosferaLogger: DadosferaLogger,
|
dadosferaLogger: DadosferaLogger,
|
||||||
@@ -46,8 +46,8 @@ export class AuthClientService implements OnModuleInit {
|
|||||||
ProtoServices.AuthProtoService,
|
ProtoServices.AuthProtoService,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.identityProviderService = this.grpcClient.getService<IdentityProviderProtoService>(
|
this.userService = this.grpcClient.getService<UsersProtoService>(
|
||||||
ProtoServices.IdentityProviderProtoService,
|
ProtoServices.UsersProtoService,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,4 +283,51 @@ export class AuthClientService implements OnModuleInit {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async getUser(id: string, metadata: Metadata) {
|
||||||
|
this.logger.info('getUser');
|
||||||
|
return await lastValueFrom(
|
||||||
|
this.userService.UserFindOneById({ id }, metadata),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async extractUserFrom(token: string) {
|
||||||
|
const decoded: any = token && jwt.decode(token, { complete: true });
|
||||||
|
if (!decoded) throw new Error('Invalid token');
|
||||||
|
|
||||||
|
const { kid } = decoded.header;
|
||||||
|
// Busca a chave pública
|
||||||
|
const { keys } = await this.getPublicKeys();
|
||||||
|
const pemValue = keys.find((k) => k.kid === kid)?.pem;
|
||||||
|
if (!pemValue)
|
||||||
|
throw new Error('Public key not found');
|
||||||
|
jwt.verify(token, pemValue);
|
||||||
|
|
||||||
|
const payload = decoded.payload;
|
||||||
|
const metadata = PackTheMetadata({
|
||||||
|
customer_id: payload.customer_id
|
||||||
|
})
|
||||||
|
|
||||||
|
const {
|
||||||
|
user
|
||||||
|
} = await this.getUser(
|
||||||
|
payload.user_id,
|
||||||
|
metadata
|
||||||
|
);
|
||||||
|
|
||||||
|
const userDto: UserDTO = {
|
||||||
|
id: user.id,
|
||||||
|
name: user.username,
|
||||||
|
jobTitle: user?.jobTitle || null,
|
||||||
|
department: user?.department || null,
|
||||||
|
hierarchy: user?.hierarchy || null,
|
||||||
|
customer: {
|
||||||
|
id: payload.customer_id,
|
||||||
|
name: payload.customer_name,
|
||||||
|
tier: payload.customer_tier,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return userDto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,3 +140,16 @@ export interface BulkEditResponse {
|
|||||||
successfulUsers: string[];
|
successfulUsers: string[];
|
||||||
failedUsers: string[];
|
failedUsers: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type UserDTO = {
|
||||||
|
id: string,
|
||||||
|
name: string,
|
||||||
|
jobTitle?: string,
|
||||||
|
department?: string,
|
||||||
|
hierarchy?: string,
|
||||||
|
customer: {
|
||||||
|
id: string,
|
||||||
|
name: string,
|
||||||
|
tier: string,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -197,9 +197,11 @@ class CatalogService implements OnModuleInit {
|
|||||||
async getUserRolesIds(userId: string) {
|
async getUserRolesIds(userId: string) {
|
||||||
const result = await this.userService.findOneById(userId).catch(() => null);
|
const result = await this.userService.findOneById(userId).catch(() => null);
|
||||||
|
|
||||||
const roles_ids = result.user.roles.map((role) => role.id);
|
if (result) {
|
||||||
|
return result.user.roles.map((role) => role.id);
|
||||||
|
}
|
||||||
|
|
||||||
return roles_ids;
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
async searchDataAssets(
|
async searchDataAssets(
|
||||||
|
|||||||
@@ -1,29 +1,46 @@
|
|||||||
import { Body, Controller, Inject, Param, Post, Req } from '@nestjs/common';
|
import { Body, Controller, Inject, Param, Post, Req } from '@nestjs/common';
|
||||||
import { init } from 'mixpanel';
|
|
||||||
import { Authenticated } from 'src/decorators/authentication.decorator';
|
|
||||||
import { ApiInternalOnlyController } from 'src/decorators/swagger.decorator';
|
import { ApiInternalOnlyController } from 'src/decorators/swagger.decorator';
|
||||||
import { RequestUser, User } from 'src/decorators/user.decorator';
|
import { RequestUser } from 'src/decorators/user.decorator';
|
||||||
import { MixpanelService } from './mixpanel.service';
|
import { MixpanelService } from './mixpanel.service';
|
||||||
|
import { extractUserFrom } from 'src/authentication/extract-user';
|
||||||
|
import DadosferaLogger from '@dadosfera/dadosfera-logs';
|
||||||
|
|
||||||
@ApiInternalOnlyController()
|
@ApiInternalOnlyController()
|
||||||
@Controller('trackEvent')
|
@Controller('trackEvent')
|
||||||
export class MixpanelController {
|
export class MixpanelController {
|
||||||
|
logger: DadosferaLogger;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private mixpanelService: MixpanelService
|
@Inject(DadosferaLogger)
|
||||||
) {}
|
dadosferaLogger: DadosferaLogger,
|
||||||
|
private mixpanelService: MixpanelService,
|
||||||
|
) {
|
||||||
|
this.logger = dadosferaLogger.logger;
|
||||||
|
}
|
||||||
|
|
||||||
@Post(':id')
|
@Post(':id')
|
||||||
async trackEvent(
|
async trackEvent(
|
||||||
@Param('id') id,
|
@Param('id') id,
|
||||||
@Body() body,
|
@Body() body,
|
||||||
@User() user: RequestUser,
|
|
||||||
@Req() request
|
@Req() request
|
||||||
) {
|
) {
|
||||||
|
this.logger.info(`POST Track Event: ${id}`)
|
||||||
delete body.info;
|
delete body.info;
|
||||||
|
|
||||||
|
const anonymousUser = {
|
||||||
|
username: "anonymous",
|
||||||
|
customer_name: "anonymous"
|
||||||
|
} as RequestUser
|
||||||
|
|
||||||
|
const hasToken = request.headers['authorization'];
|
||||||
|
|
||||||
|
const user = hasToken ? extractUserFrom(hasToken) : anonymousUser;
|
||||||
|
|
||||||
|
this.logger.info(`Has user: ${typeof hasToken == "string"}`)
|
||||||
|
|
||||||
await this.mixpanelService.track(id, user, request, body)
|
await this.mixpanelService.track(id, user, request, body)
|
||||||
|
|
||||||
|
this.logger.info(`Event successful`)
|
||||||
return { id, body, user: user.username };
|
return { id, body, user: user.username };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user