mirror of
https://github.com/dadosfera/maestro.git
synced 2026-11-10 01:39:08 +00:00
Compare commits
31
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb671a90d6 | ||
|
|
82290285d0 | ||
|
|
7616b1e32c | ||
|
|
adf1b3b97e | ||
|
|
6d608a0457 | ||
|
|
7764447adc | ||
|
|
576fdecf89 | ||
|
|
3de1e90fa8 | ||
|
|
5e90950660 | ||
|
|
3ed26e648f | ||
|
|
19e4daeea4 | ||
|
|
7f58dc7090 | ||
|
|
43aa379c06 | ||
|
|
c284f8753c | ||
|
|
3a8f2495c4 | ||
|
|
af248716ef | ||
|
|
a57ad41ad4 | ||
|
|
ffddceec3b | ||
|
|
b04d5bb402 | ||
|
|
53df3caf3f | ||
|
|
ab2e35b54f | ||
|
|
bfa77d8f7b | ||
|
|
cd55dc0dc4 | ||
|
|
f1d56e4c2c | ||
|
|
bc49f79cb3 | ||
|
|
00163ad894 | ||
|
|
a2fbeb97cc | ||
|
|
b5a1e93770 | ||
|
|
6eaf9cf6d0 | ||
|
|
b436d7de7a | ||
|
|
fa4267f54a |
@@ -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
|
||||||
@@ -105,7 +105,7 @@ 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
|
||||||
sudo mv helmfile /usr/local/bin/
|
sudo mv helmfile /usr/local/bin/
|
||||||
helmfile --version
|
helmfile --version
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -49,5 +49,8 @@ releases:
|
|||||||
value: dea2c27f-0973-4588-a2e0-9e31b64c7ffd
|
value: dea2c27f-0973-4588-a2e0-9e31b64c7ffd
|
||||||
- name: replicaCount
|
- name: replicaCount
|
||||||
value: 1
|
value: 1
|
||||||
# - name: maestro.restricted_ip
|
# 10.70.0.0/16 internal network
|
||||||
# value: "177.52.172.0/24,189.84.160.157/32,186.237.171.146/32,10.70.1.0/24"
|
# 137.131.167.254/32 loadbalancer
|
||||||
|
# 159.112.184.81/32 cluster ip for the uptime request ingest
|
||||||
|
- name: maestro.restricted_ip
|
||||||
|
value: "177.52.172.0/24, 189.84.160.157/32, 186.237.171.146/32, 137.131.167.254/32, 10.70.0.0/16, 159.112.184.81/32, 10.244.0.0/16"
|
||||||
|
|||||||
@@ -27,4 +27,4 @@ charts:
|
|||||||
- name: resources
|
- name: resources
|
||||||
value: null
|
value: null
|
||||||
- name: maestro.restricted_ip
|
- name: maestro.restricted_ip
|
||||||
value: "137.131.167.254/32,10.70.0.0/16,163.176.242.27/32"
|
value: "137.131.167.254/32, 10.70.0.0/16, 159.112.184.81/32, 10.244.0.0/16"
|
||||||
|
|||||||
+27
-9
@@ -42,6 +42,33 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/auth/sign-out": {
|
||||||
|
"post": {
|
||||||
|
"operationId": "AuthController_signOut",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "dadosfera-lang",
|
||||||
|
"in": "header",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"enum": [
|
||||||
|
"pt-br",
|
||||||
|
"en-us"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"Auth"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"/auth/refresh-access-token": {
|
"/auth/refresh-access-token": {
|
||||||
"post": {
|
"post": {
|
||||||
"operationId": "AuthController_refreshAccessToken",
|
"operationId": "AuthController_refreshAccessToken",
|
||||||
@@ -3415,9 +3442,6 @@
|
|||||||
"PipelinesV2"
|
"PipelinesV2"
|
||||||
],
|
],
|
||||||
"security": [
|
"security": [
|
||||||
{
|
|
||||||
"access-token": []
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"access-token": []
|
"access-token": []
|
||||||
}
|
}
|
||||||
@@ -3467,9 +3491,6 @@
|
|||||||
"PipelinesV2"
|
"PipelinesV2"
|
||||||
],
|
],
|
||||||
"security": [
|
"security": [
|
||||||
{
|
|
||||||
"access-token": []
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"access-token": []
|
"access-token": []
|
||||||
}
|
}
|
||||||
@@ -3519,9 +3540,6 @@
|
|||||||
"PipelinesV2"
|
"PipelinesV2"
|
||||||
],
|
],
|
||||||
"security": [
|
"security": [
|
||||||
{
|
|
||||||
"access-token": []
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"access-token": []
|
"access-token": []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,44 @@ export const PERMISSIONS_GROUPS = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
IMPORT_FILES: {
|
||||||
|
title: {
|
||||||
|
'pt-br': 'Coletar | Importar arquivos',
|
||||||
|
'en-us': 'Collect | Import files',
|
||||||
|
'es-es': 'Colecta | Importar archivos',
|
||||||
|
},
|
||||||
|
permissions: {
|
||||||
|
VIEW: {
|
||||||
|
seqid: 48,
|
||||||
|
claim: 'import-file:view',
|
||||||
|
usage: PermissionUsages.PUBLIC,
|
||||||
|
name: {
|
||||||
|
'pt-br': 'Importar arquivos',
|
||||||
|
'en-us': 'Import files',
|
||||||
|
'es-es': 'Importar archivos',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AI_CHAT: {
|
||||||
|
title: {
|
||||||
|
'pt-br': 'AutodriveDDF',
|
||||||
|
'en-us': 'AutodriveDDF',
|
||||||
|
'es-es': 'AutodriveDDF',
|
||||||
|
},
|
||||||
|
permissions: {
|
||||||
|
VIEW: {
|
||||||
|
seqid: 49,
|
||||||
|
claim: 'ai-chat:view',
|
||||||
|
usage: PermissionUsages.PUBLIC,
|
||||||
|
name: {
|
||||||
|
'pt-br': 'AutodriveDDF',
|
||||||
|
'en-us': 'AutodriveDDF',
|
||||||
|
'es-es': 'AutodriveDDF',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
CONNECTION: {
|
CONNECTION: {
|
||||||
title: {
|
title: {
|
||||||
'pt-br': 'Coletar | Fontes de dados',
|
'pt-br': 'Coletar | Fontes de dados',
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
Req,
|
Req,
|
||||||
Param,
|
Param,
|
||||||
Res,
|
Res,
|
||||||
|
UnauthorizedException,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import {
|
import {
|
||||||
ApiHeaders,
|
ApiHeaders,
|
||||||
@@ -54,7 +55,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;
|
||||||
@@ -103,14 +103,13 @@ export class AuthController {
|
|||||||
const data = await this.authClient.signIn({ username, password, totp }, metadata);
|
const data = await this.authClient.signIn({ username, password, totp }, metadata);
|
||||||
|
|
||||||
if (data.tokens) {
|
if (data.tokens) {
|
||||||
this.addTokenInCookie(res, {
|
this.authClient.writeAuthSession(res, {
|
||||||
accessToken: data.tokens.accessToken,
|
accessToken: data.tokens.accessToken,
|
||||||
refreshToken: data.tokens.refreshToken,
|
refreshToken: data.tokens.refreshToken,
|
||||||
userId: data.user.id
|
userId: data.user.id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return res.send(data);
|
return res.send(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error('/auth - SignIn - ERROR', error);
|
this.logger.error('/auth - SignIn - ERROR', error);
|
||||||
@@ -127,27 +126,8 @@ export class AuthController {
|
|||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
this.logger.info('/auth - SignOut');
|
this.logger.info('/auth - SignOut');
|
||||||
const exp = 1000 * 60 * 3;
|
|
||||||
|
this.authClient.cleanUpAuthSession(res);
|
||||||
res.cookie('ddf-auth', '', {
|
|
||||||
domain: 'dadosfera.local',
|
|
||||||
maxAge: Date.now() - exp,
|
|
||||||
expires: new Date(),
|
|
||||||
httpOnly: true,
|
|
||||||
secure: true,
|
|
||||||
sameSite: 'none', // Necessário para cookies em requisições cross-site
|
|
||||||
});
|
|
||||||
|
|
||||||
res.cookie('ddf-refresh-auth', '', {
|
|
||||||
domain: 'dadosfera.local',
|
|
||||||
maxAge: Date.now() - exp,
|
|
||||||
expires: new Date(),
|
|
||||||
httpOnly: true,
|
|
||||||
secure: true,
|
|
||||||
sameSite: 'none', // Necessário para cookies em requisições cross-site
|
|
||||||
});
|
|
||||||
|
|
||||||
this.logger.info('Clean cookie sessions');
|
|
||||||
|
|
||||||
return res.send();
|
return res.send();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -176,8 +156,9 @@ export class AuthController {
|
|||||||
|
|
||||||
const data = await this.authClient.refreshAccessToken({ refreshToken, userId }, metadata);
|
const data = await this.authClient.refreshAccessToken({ refreshToken, userId }, metadata);
|
||||||
|
|
||||||
this.addTokenInCookie(res, {
|
this.authClient.writeAuthSession(res, {
|
||||||
accessToken: data.accessToken,
|
accessToken: data.accessToken,
|
||||||
|
refreshToken: data.refreshToken,
|
||||||
userId
|
userId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -493,114 +474,36 @@ export class AuthController {
|
|||||||
@Get('me')
|
@Get('me')
|
||||||
async getMe(@Req() req: Request, @Res() res: Response) {
|
async getMe(@Req() req: Request, @Res() res: Response) {
|
||||||
this.logger.info('GET /auth/me ')
|
this.logger.info('GET /auth/me ')
|
||||||
// Lê cookies
|
|
||||||
|
// Get token and headers
|
||||||
const accessToken = req.cookies['ddf-auth'];
|
const accessToken = req.cookies['ddf-auth'];
|
||||||
const userId = req.cookies['ddf-user-id'];
|
const refreshToken = req.cookies['ddf-refresh-auth'];
|
||||||
|
const userId = req.cookies['ddf-user-id'];
|
||||||
|
const resourceHost = req.headers["host"]
|
||||||
|
|
||||||
|
const hasUserSession = Boolean(accessToken) && Boolean(userId);
|
||||||
|
this.logger.info('Has User Session: ' + hasUserSession);
|
||||||
|
|
||||||
|
if (!hasUserSession) {
|
||||||
|
throw new UnauthorizedException()
|
||||||
|
}
|
||||||
|
|
||||||
this.logger.info('Has cookie: ' + Boolean(accessToken))
|
|
||||||
let payload: any;
|
|
||||||
let userInfo: any = {};
|
|
||||||
try {
|
try {
|
||||||
// Decodifica e valida o JWT de acesso
|
const userDto = await this.authClient.validateUserSession(accessToken, resourceHost);
|
||||||
const decoded: any = accessToken && jwt.decode(accessToken, { complete: true });
|
return res.status(200).json(userDto);
|
||||||
if (!decoded) throw new Error('Invalid token')
|
} catch (error) {
|
||||||
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) {
|
|
||||||
this.logger.error(err.message);
|
|
||||||
const refreshToken = req.cookies['ddf-refresh-auth'];
|
|
||||||
|
|
||||||
this.logger.info('Token is invalid')
|
if (!refreshToken) {
|
||||||
this.logger.info('Has Refresh Token: '+ Boolean(refreshToken))
|
|
||||||
// Se access token inválido, tenta refresh
|
|
||||||
if (!refreshToken || !userId) {
|
|
||||||
this.logger.error('Invalid refresh token or customer name');
|
this.logger.error('Invalid refresh token or customer name');
|
||||||
return res.status(401).json({ error: 'Not authenticated' });
|
throw new UnauthorizedException("Invalid refresh token or customer name");
|
||||||
}
|
};
|
||||||
try {
|
|
||||||
// Chama refreshAccessToken
|
|
||||||
const metadata = PackTheMetadata({
|
|
||||||
});
|
|
||||||
this.logger.info('Call Refresh Token')
|
|
||||||
const data = await this.authClient.refreshAccessToken({ refreshToken, userId }, metadata);
|
|
||||||
this.logger.info('Finish Refresh Token')
|
|
||||||
// Retorna novo access token e dados mínimos
|
|
||||||
this.addTokenInCookie(res, {
|
|
||||||
accessToken: data.accessToken,
|
|
||||||
userId
|
|
||||||
});
|
|
||||||
// Decodifica novo token
|
|
||||||
const decoded: any = jwt.decode(data.accessToken, { complete: true });
|
|
||||||
const 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 (refreshErr) {
|
|
||||||
this.logger.error(refreshErr)
|
|
||||||
return res.status(401).json({ error: 'Not authenticated' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private addTokenInCookie(res: Response, data: CookiesValues) {
|
const {
|
||||||
let exp = 1000 * 60 * 5; // 5 minutes
|
authSession,
|
||||||
|
user
|
||||||
if (data.accessToken) {
|
} = await this.authClient.refreshUserSession(refreshToken, userId, resourceHost);
|
||||||
const { exp: expiration } = jwt.decode(data.accessToken) as JwtPayload;
|
this.authClient.writeAuthSession(res, authSession);
|
||||||
exp = (expiration - 30) * 1000; // exp em segundos, maxAge em ms
|
return res.status(200).json(user);
|
||||||
|
|
||||||
this.logger.info('Set Cookie ddf-auth')
|
|
||||||
res.cookie('ddf-auth', data.accessToken, {
|
|
||||||
domain: '.dadosfera.ai',
|
|
||||||
maxAge: exp,
|
|
||||||
httpOnly: true,
|
|
||||||
secure: true,
|
|
||||||
sameSite: 'none', // Necessário para cookies em requisições cross-site
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.refreshToken) {
|
|
||||||
this.logger.info('Set Cookie ddf-refresh-auth')
|
|
||||||
res.cookie('ddf-refresh-auth', data.refreshToken, {
|
|
||||||
domain: '.dadosfera.ai',
|
|
||||||
maxAge: exp,
|
|
||||||
httpOnly: true,
|
|
||||||
secure: true,
|
|
||||||
sameSite: 'none', // Necessário para cookies em requisições cross-site
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.userId) {
|
|
||||||
this.logger.info('Set Cookie ddf-refresh-auth')
|
|
||||||
res.cookie('ddf-user-id', data.userId, {
|
|
||||||
domain: '.dadosfera.ai',
|
|
||||||
maxAge: exp,
|
|
||||||
httpOnly: true,
|
|
||||||
secure: true,
|
|
||||||
sameSite: 'none', // Necessário para cookies em requisições cross-site
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,20 @@
|
|||||||
import { OnModuleInit, Inject, Injectable, ForbiddenException } from '@nestjs/common';
|
import {
|
||||||
|
OnModuleInit,
|
||||||
|
Inject,
|
||||||
|
Injectable,
|
||||||
|
ForbiddenException,
|
||||||
|
HttpException,
|
||||||
|
HttpStatus,
|
||||||
|
} from '@nestjs/common';
|
||||||
import { ClientGrpc } from '@nestjs/microservices';
|
import { ClientGrpc } from '@nestjs/microservices';
|
||||||
import { DadosferaLogger } from '@dadosfera/dadosfera-logs';
|
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,
|
||||||
|
UsersProtoService,
|
||||||
|
} from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/write-service';
|
||||||
import {
|
import {
|
||||||
AuthSnowflakeSignInRequest,
|
AuthSnowflakeSignInRequest,
|
||||||
AuthSignInRequest,
|
AuthSignInRequest,
|
||||||
@@ -21,18 +31,24 @@ 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, { JwtPayload } from 'jsonwebtoken';
|
||||||
|
import { PackTheMetadata } from 'src/utils/PackTheMetadata';
|
||||||
|
import { Request, Response } from 'express';
|
||||||
|
|
||||||
|
type AuthSession = {
|
||||||
|
accessToken?: string;
|
||||||
|
refreshToken?: string;
|
||||||
|
userId?: string;
|
||||||
|
};
|
||||||
|
|
||||||
@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 +62,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,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,11 +79,11 @@ export class AuthClientService implements OnModuleInit {
|
|||||||
return lastValueFrom(this.authService.AuthSnowflakeSignIn(input));
|
return lastValueFrom(this.authService.AuthSnowflakeSignIn(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
checkDedicatedProxy({
|
checkDedicatedProxy({ customer }: AuthSignInResponse) {
|
||||||
customer
|
|
||||||
}: AuthSignInResponse) {
|
|
||||||
const DEDICATED_PROXY = process.env.DEDICATED_PROXY || '';
|
const DEDICATED_PROXY = process.env.DEDICATED_PROXY || '';
|
||||||
this.logger.info('SignIn - Setting customer ID for dedicated proxy: ' + DEDICATED_PROXY);
|
this.logger.info(
|
||||||
|
'SignIn - Setting customer ID for dedicated proxy: ' + DEDICATED_PROXY,
|
||||||
|
);
|
||||||
this.logger.info('Customer ID: ' + customer.id);
|
this.logger.info('Customer ID: ' + customer.id);
|
||||||
|
|
||||||
if (DEDICATED_PROXY !== '' && DEDICATED_PROXY !== customer.id) {
|
if (DEDICATED_PROXY !== '' && DEDICATED_PROXY !== customer.id) {
|
||||||
@@ -75,7 +91,9 @@ export class AuthClientService implements OnModuleInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bloquear o customer de acesso o maestro publico
|
// Bloquear o customer de acesso o maestro publico
|
||||||
this.logger.info('Check if customer have network policy: ' + customer.modules);
|
this.logger.info(
|
||||||
|
'Check if customer have network policy: ' + customer.modules,
|
||||||
|
);
|
||||||
const hasNetworkPolicyModule = customer.modules.includes('network-policy');
|
const hasNetworkPolicyModule = customer.modules.includes('network-policy');
|
||||||
if (hasNetworkPolicyModule && DEDICATED_PROXY === '') {
|
if (hasNetworkPolicyModule && DEDICATED_PROXY === '') {
|
||||||
throw new ForbiddenException();
|
throw new ForbiddenException();
|
||||||
@@ -94,7 +112,6 @@ export class AuthClientService implements OnModuleInit {
|
|||||||
result = await lastValueFrom(
|
result = await lastValueFrom(
|
||||||
this.authService.AuthSignIn({ username, password, totp }, metadata),
|
this.authService.AuthSignIn({ username, password, totp }, metadata),
|
||||||
);
|
);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error('SignIn - Error during sign-in');
|
this.logger.error('SignIn - Error during sign-in');
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
@@ -105,7 +122,7 @@ export class AuthClientService implements OnModuleInit {
|
|||||||
this.checkDedicatedProxy(result);
|
this.checkDedicatedProxy(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
async refreshAccessToken(
|
async refreshAccessToken(
|
||||||
@@ -115,7 +132,10 @@ export class AuthClientService implements OnModuleInit {
|
|||||||
this.logger.info('RefreshAccessToken');
|
this.logger.info('RefreshAccessToken');
|
||||||
|
|
||||||
return lastValueFrom(
|
return lastValueFrom(
|
||||||
this.authService.AuthRefreshAccessToken({ refreshToken, userId }, metadata),
|
this.authService.AuthRefreshAccessToken(
|
||||||
|
{ refreshToken, userId },
|
||||||
|
metadata,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,4 +303,190 @@ export class AuthClientService implements OnModuleInit {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async validateUserSession(accessToken: any, resourceHost: string) {
|
||||||
|
const payload = await this.validateJwtToken(accessToken);
|
||||||
|
|
||||||
|
const userDto = await this.getUserfromPayload(payload);
|
||||||
|
|
||||||
|
this.validateResourceAccess(resourceHost, userDto);
|
||||||
|
return userDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async refreshUserSession(
|
||||||
|
refreshToken: string,
|
||||||
|
userId: string,
|
||||||
|
originHeader: string,
|
||||||
|
): Promise<{
|
||||||
|
user: UserDTO;
|
||||||
|
authSession: AuthSession;
|
||||||
|
}> {
|
||||||
|
const metadata = PackTheMetadata({});
|
||||||
|
|
||||||
|
this.logger.info('Call Refresh Token');
|
||||||
|
const refreshCredentials = await this.refreshAccessToken(
|
||||||
|
{ refreshToken, userId },
|
||||||
|
metadata,
|
||||||
|
);
|
||||||
|
this.logger.info('Finish Refresh Token');
|
||||||
|
|
||||||
|
const userDto = await this.validateUserSession(
|
||||||
|
refreshCredentials.accessToken,
|
||||||
|
originHeader,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
user: userDto,
|
||||||
|
authSession: {
|
||||||
|
accessToken: refreshCredentials.accessToken,
|
||||||
|
refreshToken: refreshCredentials.refreshToken,
|
||||||
|
userId,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public writeAuthSession(res: Response, data: AuthSession) {
|
||||||
|
let exp = 1000 * 60 * 5; // 5 minutes
|
||||||
|
|
||||||
|
if (data.accessToken) {
|
||||||
|
const { exp: expiration } = jwt.decode(data.accessToken) as JwtPayload;
|
||||||
|
exp = (expiration - 30) * 1000; // exp em segundos, maxAge em ms
|
||||||
|
|
||||||
|
this.logger.info('Set Cookie ddf-auth');
|
||||||
|
res.cookie('ddf-auth', data.accessToken, {
|
||||||
|
domain: '.dadosfera.ai',
|
||||||
|
maxAge: exp,
|
||||||
|
httpOnly: true,
|
||||||
|
secure: true,
|
||||||
|
sameSite: 'none', // Necessário para cookies em requisições cross-site
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.refreshToken) {
|
||||||
|
this.logger.info('Set Cookie ddf-refresh-auth');
|
||||||
|
res.cookie('ddf-refresh-auth', data.refreshToken, {
|
||||||
|
domain: '.dadosfera.ai',
|
||||||
|
maxAge: exp,
|
||||||
|
httpOnly: true,
|
||||||
|
secure: true,
|
||||||
|
sameSite: 'none', // Necessário para cookies em requisições cross-site
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.userId) {
|
||||||
|
this.logger.info('Set Cookie ddf-refresh-auth');
|
||||||
|
res.cookie('ddf-user-id', data.userId, {
|
||||||
|
domain: '.dadosfera.ai',
|
||||||
|
maxAge: exp,
|
||||||
|
httpOnly: true,
|
||||||
|
secure: true,
|
||||||
|
sameSite: 'none', // Necessário para cookies em requisições cross-site
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public cleanUpAuthSession(res: Response) {
|
||||||
|
const exp = 1000 * 60 * 3;
|
||||||
|
|
||||||
|
res.cookie('ddf-auth', '', {
|
||||||
|
domain: 'dadosfera.ai',
|
||||||
|
maxAge: Date.now() - exp,
|
||||||
|
expires: new Date(),
|
||||||
|
httpOnly: true,
|
||||||
|
secure: true,
|
||||||
|
sameSite: 'none', // Necessário para cookies em requisições cross-site
|
||||||
|
});
|
||||||
|
|
||||||
|
res.cookie('ddf-refresh-auth', '', {
|
||||||
|
domain: 'dadosfera.ai',
|
||||||
|
maxAge: Date.now() - exp,
|
||||||
|
expires: new Date(),
|
||||||
|
httpOnly: true,
|
||||||
|
secure: true,
|
||||||
|
sameSite: 'none', // Necessário para cookies em requisições cross-site
|
||||||
|
});
|
||||||
|
|
||||||
|
this.logger.info('Clean cookie sessions');
|
||||||
|
}
|
||||||
|
|
||||||
|
private async validateJwtToken(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);
|
||||||
|
|
||||||
|
return decoded.payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getUserfromPayload(payload: JwtPayload): Promise<UserDTO> {
|
||||||
|
this.logger.info('getUser');
|
||||||
|
|
||||||
|
const metadata = PackTheMetadata({
|
||||||
|
customer_id: payload.customer_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { user } = await lastValueFrom(
|
||||||
|
this.userService.UserFindOneById({ id: 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private validateResourceAccess(host: string, user: UserDTO) {
|
||||||
|
this.logger.info(
|
||||||
|
"Validate whether the source URL is a resource belonging to the user's client",
|
||||||
|
);
|
||||||
|
this.logger.info('Host: ' + host);
|
||||||
|
this.logger.info('Customer: ' + user.customer.name);
|
||||||
|
|
||||||
|
const hostParts = host.split('.');
|
||||||
|
const domain = hostParts[0];
|
||||||
|
const isResouceStg = hostParts[1] === 'stg';
|
||||||
|
|
||||||
|
const notFoundCustomerInDomain = !domain.includes('-')
|
||||||
|
|
||||||
|
if (notFoundCustomerInDomain) {
|
||||||
|
this.logger.info(`Not found Customer Name in domain`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const domainParts = domain.split('-');
|
||||||
|
|
||||||
|
const customerInDomain = domainParts[domainParts.length - 1];
|
||||||
|
|
||||||
|
if (isResouceStg && process.env.ENV !== 'stg') {
|
||||||
|
this.logger.error(`Customer ${user.customer.name} cannot access ${host}`);
|
||||||
|
throw new HttpException(
|
||||||
|
`Customer ${user.customer.name} cannot access ${host}`,
|
||||||
|
HttpStatus.FORBIDDEN
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (customerInDomain != user.customer.name) {
|
||||||
|
this.logger.error(`Customer ${user.customer.name} cannot access ${host}`);
|
||||||
|
throw new HttpException(
|
||||||
|
`Customer ${user.customer.name} cannot access ${host}`,
|
||||||
|
HttpStatus.FORBIDDEN
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -406,11 +406,14 @@ class CatalogService implements OnModuleInit {
|
|||||||
|
|
||||||
const roles = [];
|
const roles = [];
|
||||||
const users = [];
|
const users = [];
|
||||||
for (const role_id of data_asset.roles) {
|
const data_asset_roles = data_asset?.roles || []
|
||||||
|
for (const role_id of data_asset_roles) {
|
||||||
const role = customer_roles.find((r) => r.id === role_id);
|
const role = customer_roles.find((r) => r.id === role_id);
|
||||||
if (role) roles.push({ id: role.id, name: role.name });
|
if (role) roles.push({ id: role.id, name: role.name });
|
||||||
}
|
}
|
||||||
for (const user_id of data_asset.users) {
|
|
||||||
|
const data_asset_users = data_asset?.users || []
|
||||||
|
for (const user_id of data_asset_users) {
|
||||||
const user = customer_users.find((r) => r.id === user_id);
|
const user = customer_users.find((r) => r.id === user_id);
|
||||||
if (user) users.push({ id: user.id, username: user.username });
|
if (user) users.push({ id: user.id, username: user.username });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
|||||||
import {
|
import {
|
||||||
AuthenticateCondition,
|
AuthenticateCondition,
|
||||||
Authenticated,
|
Authenticated,
|
||||||
|
RequireSomePermission,
|
||||||
} from 'src/decorators/authentication.decorator';
|
} from 'src/decorators/authentication.decorator';
|
||||||
import { PERMISSIONS_GROUPS } from '../../authentication/permissions.enum';
|
import { PERMISSIONS_GROUPS } from '../../authentication/permissions.enum';
|
||||||
import { PipelinesService } from './pipelines.service';
|
import { PipelinesService } from './pipelines.service';
|
||||||
@@ -13,26 +14,6 @@ import { ApiInternalOnlyController } from 'src/decorators/swagger.decorator';
|
|||||||
@ApiTags('Pipelines')
|
@ApiTags('Pipelines')
|
||||||
@Controller('pipelines')
|
@Controller('pipelines')
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
@AuthenticateCondition((req, user) => {
|
|
||||||
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.PIPELINE.permissions[action].seqid,
|
|
||||||
);
|
|
||||||
})
|
|
||||||
export class PipelinesController {
|
export class PipelinesController {
|
||||||
logger: DadosferaLogger;
|
logger: DadosferaLogger;
|
||||||
constructor(
|
constructor(
|
||||||
@@ -44,6 +25,7 @@ export class PipelinesController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Post('start/:id')
|
@Post('start/:id')
|
||||||
|
@RequireSomePermission(PERMISSIONS_GROUPS.PIPELINE.permissions.CREATE)
|
||||||
@ApiOperation({
|
@ApiOperation({
|
||||||
deprecated: true,
|
deprecated: true,
|
||||||
description:
|
description:
|
||||||
@@ -71,6 +53,7 @@ export class PipelinesController {
|
|||||||
description:
|
description:
|
||||||
'This method is deprecated. Please use route /pipelinesV2/:id/status instead',
|
'This method is deprecated. Please use route /pipelinesV2/:id/status instead',
|
||||||
})
|
})
|
||||||
|
@RequireSomePermission(PERMISSIONS_GROUPS.IMPORT_FILES.permissions.VIEW, PERMISSIONS_GROUPS.PIPELINE.permissions.GET)
|
||||||
async getPipelineStatus(@Body() body, @Param('id') id: string) {
|
async getPipelineStatus(@Body() body, @Param('id') id: string) {
|
||||||
body.id = id;
|
body.id = id;
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
AuthenticateCondition,
|
AuthenticateCondition,
|
||||||
RequireAllPermissions,
|
RequireAllPermissions,
|
||||||
|
RequireSomePermission,
|
||||||
} from 'src/decorators/authentication.decorator';
|
} from 'src/decorators/authentication.decorator';
|
||||||
import { PERMISSIONS_GROUPS } from '../../authentication/permissions.enum';
|
import { PERMISSIONS_GROUPS } from '../../authentication/permissions.enum';
|
||||||
import { PipelinesService } from './pipelines.service';
|
import { PipelinesService } from './pipelines.service';
|
||||||
@@ -52,30 +53,6 @@ import { ApiInternalOnlyEndpoint } from 'src/decorators/swagger.decorator';
|
|||||||
@ApiHeaders([{ name: 'dadosfera-lang', enum: LanguageEnum, required: false }])
|
@ApiHeaders([{ name: 'dadosfera-lang', enum: LanguageEnum, required: false }])
|
||||||
@UseFilters(new GrpcToHttpExceptionFilter())
|
@UseFilters(new GrpcToHttpExceptionFilter())
|
||||||
@Controller('pipelinesV2')
|
@Controller('pipelinesV2')
|
||||||
@AuthenticateCondition((req, user) => {
|
|
||||||
let action;
|
|
||||||
|
|
||||||
switch (req.method) {
|
|
||||||
case 'POST':
|
|
||||||
action = 'CREATE';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'PUT':
|
|
||||||
action = 'UPDATE';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'PATCH':
|
|
||||||
action = 'UPDATE';
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
action = req.method;
|
|
||||||
}
|
|
||||||
|
|
||||||
return user.permissions.includes(
|
|
||||||
PERMISSIONS_GROUPS.PIPELINE.permissions[action].seqid,
|
|
||||||
);
|
|
||||||
})
|
|
||||||
export class PipelinesController {
|
export class PipelinesController {
|
||||||
logger: DadosferaLogger;
|
logger: DadosferaLogger;
|
||||||
constructor(
|
constructor(
|
||||||
@@ -88,6 +65,7 @@ export class PipelinesController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Get('monitoring-dashboard')
|
@Get('monitoring-dashboard')
|
||||||
|
@RequireSomePermission(PERMISSIONS_GROUPS.PIPELINE.permissions.GET)
|
||||||
async getMonitoringDashboard(@User() user: RequestUser) {
|
async getMonitoringDashboard(@User() user: RequestUser) {
|
||||||
this.logger.info('PipelinesController - getMonitoringDashboard', { user });
|
this.logger.info('PipelinesController - getMonitoringDashboard', { user });
|
||||||
|
|
||||||
@@ -100,6 +78,7 @@ export class PipelinesController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
|
@RequireSomePermission(PERMISSIONS_GROUPS.PIPELINE.permissions.CREATE)
|
||||||
@ApiCreatedResponse({ type: IPipelineV2 })
|
@ApiCreatedResponse({ type: IPipelineV2 })
|
||||||
async create(
|
async create(
|
||||||
@Language() language: LanguageEnum,
|
@Language() language: LanguageEnum,
|
||||||
@@ -126,6 +105,7 @@ export class PipelinesController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
|
@RequireSomePermission(PERMISSIONS_GROUPS.IMPORT_FILES.permissions.VIEW, PERMISSIONS_GROUPS.PIPELINE.permissions.GET)
|
||||||
async findAll(
|
async findAll(
|
||||||
@User() user: RequestUser,
|
@User() user: RequestUser,
|
||||||
@Language() language: LanguageEnum,
|
@Language() language: LanguageEnum,
|
||||||
@@ -150,6 +130,7 @@ export class PipelinesController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Get('/download-logs')
|
@Get('/download-logs')
|
||||||
|
@RequireSomePermission(PERMISSIONS_GROUPS.PIPELINE.permissions.GET)
|
||||||
async downloadLogs(
|
async downloadLogs(
|
||||||
@User() user: RequestUser,
|
@User() user: RequestUser,
|
||||||
@Language() language: LanguageEnum,
|
@Language() language: LanguageEnum,
|
||||||
@@ -180,6 +161,7 @@ export class PipelinesController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Get(':id/config')
|
@Get(':id/config')
|
||||||
|
@RequireSomePermission(PERMISSIONS_GROUPS.IMPORT_FILES.permissions.VIEW,PERMISSIONS_GROUPS.PIPELINE.permissions.GET)
|
||||||
async getPipelineproperties(
|
async getPipelineproperties(
|
||||||
@Language() language: LanguageEnum,
|
@Language() language: LanguageEnum,
|
||||||
@User() user: RequestUser,
|
@User() user: RequestUser,
|
||||||
@@ -191,6 +173,7 @@ export class PipelinesController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Get(':id/objects')
|
@Get(':id/objects')
|
||||||
|
@RequireSomePermission(PERMISSIONS_GROUPS.PIPELINE.permissions.GET)
|
||||||
async getPipelineObjects(
|
async getPipelineObjects(
|
||||||
@Language() language: LanguageEnum,
|
@Language() language: LanguageEnum,
|
||||||
@User() user: RequestUser,
|
@User() user: RequestUser,
|
||||||
@@ -202,6 +185,7 @@ export class PipelinesController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Get(':id/status')
|
@Get(':id/status')
|
||||||
|
@RequireSomePermission(PERMISSIONS_GROUPS.IMPORT_FILES.permissions.VIEW, PERMISSIONS_GROUPS.PIPELINE.permissions.GET)
|
||||||
async getPipelineStatus(@Body() body, @Param('id') id: string) {
|
async getPipelineStatus(@Body() body, @Param('id') id: string) {
|
||||||
body.id = id;
|
body.id = id;
|
||||||
|
|
||||||
@@ -216,6 +200,7 @@ export class PipelinesController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Get('/:id')
|
@Get('/:id')
|
||||||
|
@RequireSomePermission(PERMISSIONS_GROUPS.IMPORT_FILES.permissions.VIEW, PERMISSIONS_GROUPS.PIPELINE.permissions.GET)
|
||||||
async findOne(
|
async findOne(
|
||||||
@Language() language: LanguageEnum,
|
@Language() language: LanguageEnum,
|
||||||
@User() user: RequestUser,
|
@User() user: RequestUser,
|
||||||
@@ -258,6 +243,7 @@ export class PipelinesController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Patch('/:id')
|
@Patch('/:id')
|
||||||
|
@RequireSomePermission(PERMISSIONS_GROUPS.PIPELINE.permissions.UPDATE)
|
||||||
async update(
|
async update(
|
||||||
@Language() language: LanguageEnum,
|
@Language() language: LanguageEnum,
|
||||||
@Body() updatePipelineDto,
|
@Body() updatePipelineDto,
|
||||||
@@ -297,6 +283,7 @@ export class PipelinesController {
|
|||||||
deprecated: true,
|
deprecated: true,
|
||||||
description: 'This method is deprecated. Please use PATCH instead',
|
description: 'This method is deprecated. Please use PATCH instead',
|
||||||
})
|
})
|
||||||
|
@RequireSomePermission(PERMISSIONS_GROUPS.IMPORT_FILES.permissions.VIEW, PERMISSIONS_GROUPS.PIPELINE.permissions.UPDATE)
|
||||||
async updateDeprecated(
|
async updateDeprecated(
|
||||||
@Language() language: LanguageEnum,
|
@Language() language: LanguageEnum,
|
||||||
@Body() updatePipelineDto,
|
@Body() updatePipelineDto,
|
||||||
@@ -312,6 +299,7 @@ export class PipelinesController {
|
|||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@ApiNoContentResponse()
|
@ApiNoContentResponse()
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
|
@RequireSomePermission(PERMISSIONS_GROUPS.PIPELINE.permissions.DELETE)
|
||||||
async delete(@Param('id') id: string, @User() user: RequestUser) {
|
async delete(@Param('id') id: string, @User() user: RequestUser) {
|
||||||
this.logger.info('PipelinesController - delete', { user });
|
this.logger.info('PipelinesController - delete', { user });
|
||||||
const metadata = PackTheMetadata({
|
const metadata = PackTheMetadata({
|
||||||
@@ -325,7 +313,7 @@ export class PipelinesController {
|
|||||||
|
|
||||||
@ApiInternalOnlyEndpoint()
|
@ApiInternalOnlyEndpoint()
|
||||||
@Post('/init-upload')
|
@Post('/init-upload')
|
||||||
@RequireAllPermissions(PERMISSIONS_GROUPS.PIPELINE.permissions.CREATE)
|
@RequireAllPermissions(PERMISSIONS_GROUPS.IMPORT_FILES.permissions.VIEW)
|
||||||
async initUploadFile(
|
async initUploadFile(
|
||||||
@User() user: RequestUser,
|
@User() user: RequestUser,
|
||||||
@Body() body: IInitUploadCSVFile,
|
@Body() body: IInitUploadCSVFile,
|
||||||
@@ -357,7 +345,7 @@ export class PipelinesController {
|
|||||||
|
|
||||||
@ApiInternalOnlyEndpoint()
|
@ApiInternalOnlyEndpoint()
|
||||||
@Post('/complete-upload')
|
@Post('/complete-upload')
|
||||||
@RequireAllPermissions(PERMISSIONS_GROUPS.PIPELINE.permissions.CREATE)
|
@RequireAllPermissions(PERMISSIONS_GROUPS.IMPORT_FILES.permissions.VIEW)
|
||||||
async completeUploadFile(
|
async completeUploadFile(
|
||||||
@User() user: RequestUser,
|
@User() user: RequestUser,
|
||||||
@Body() body: ICompleteUploadCSVFile,
|
@Body() body: ICompleteUploadCSVFile,
|
||||||
@@ -375,7 +363,7 @@ export class PipelinesController {
|
|||||||
|
|
||||||
@ApiInternalOnlyEndpoint()
|
@ApiInternalOnlyEndpoint()
|
||||||
@Post('/file')
|
@Post('/file')
|
||||||
@RequireAllPermissions(PERMISSIONS_GROUPS.PIPELINE.permissions.CREATE)
|
@RequireAllPermissions(PERMISSIONS_GROUPS.IMPORT_FILES.permissions.VIEW)
|
||||||
async uploadedFile(
|
async uploadedFile(
|
||||||
@User() user: RequestUser,
|
@User() user: RequestUser,
|
||||||
@Body() body: ICreatePipelineCSVFile,
|
@Body() body: ICreatePipelineCSVFile,
|
||||||
@@ -425,6 +413,7 @@ export class PipelinesController {
|
|||||||
|
|
||||||
@ApiInternalOnlyEndpoint()
|
@ApiInternalOnlyEndpoint()
|
||||||
@Post('start/:id')
|
@Post('start/:id')
|
||||||
|
@RequireSomePermission(PERMISSIONS_GROUPS.PIPELINE.permissions.CREATE)
|
||||||
async activate(@Param('id') id: string, @Body() body) {
|
async activate(@Param('id') id: string, @Body() body) {
|
||||||
const { info } = body;
|
const { info } = body;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user