--consumo de api auth
This commit is contained in:
parent
f81a1d5a81
commit
bbc517d256
14
.env
14
.env
@ -8,7 +8,7 @@ DB_MAX_OPEN_CONNS=25
|
|||||||
DB_MAX_IDLE_CONNS=10
|
DB_MAX_IDLE_CONNS=10
|
||||||
DB_CONN_MAX_LIFETIME=30m
|
DB_CONN_MAX_LIFETIME=30m
|
||||||
#Redis
|
#Redis
|
||||||
REDIS_HOST=10.0.0.112
|
REDIS_HOST=localhost
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
REDIS_PASSWORD=TuPasswordSegura123
|
REDIS_PASSWORD=TuPasswordSegura123
|
||||||
REDIS_DB=0
|
REDIS_DB=0
|
||||||
@ -35,6 +35,16 @@ ENVIRONMENT=development
|
|||||||
# Elastic
|
# Elastic
|
||||||
#ELASTIC_URL=http://host.docker.internal:9200
|
#ELASTIC_URL=http://host.docker.internal:9200
|
||||||
ELASTIC_URL=http://10.0.0.124:9200
|
ELASTIC_URL=http://10.0.0.124:9200
|
||||||
ELASTIC_ENABLED=true
|
ELASTIC_ENABLED=false
|
||||||
|
|
||||||
ENCRYPTION_KEY=12345678901234567890123456789012
|
ENCRYPTION_KEY=12345678901234567890123456789012
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AUTH_ENDPOINT= http://localhost:8085/auth/headers
|
||||||
|
AUTH_AUTORIZATION= 'Basic d29ya2VyLXJlbmRpY2lvbjpwcnVlYmE='
|
||||||
|
AUTH_METHOD=POST
|
||||||
|
|
||||||
|
TM_HEADER_ORIGIN=https://azure-function.timemanagerweb.com
|
||||||
|
TM_HEADER_TENANT_NAME=pruebas-dos
|
||||||
|
TM_HEADER_USER_AGENT='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36'
|
||||||
|
|||||||
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
@ -44,6 +44,17 @@ type Config struct {
|
|||||||
TLSSkipVerify bool `mapstructure:"TLS_SKIP_VERIFY"`
|
TLSSkipVerify bool `mapstructure:"TLS_SKIP_VERIFY"`
|
||||||
LogRequests bool `mapstructure:"LOG_REQUESTS"`
|
LogRequests bool `mapstructure:"LOG_REQUESTS"`
|
||||||
EnableDebug bool `mapstructure:"ENABLE_DEBUG"`
|
EnableDebug bool `mapstructure:"ENABLE_DEBUG"`
|
||||||
|
|
||||||
|
//AUTH
|
||||||
|
AUTH_ENDPOINT string `mapstructure:"AUTH_ENDPOINT"`
|
||||||
|
AUTH_AUTORIZATION string `mapstructure:"AUTH_AUTORIZATION"`
|
||||||
|
AUTH_METHOD string `mapstructure:"AUTH_METHOD"`
|
||||||
|
|
||||||
|
//TM
|
||||||
|
|
||||||
|
TM_HEADER_ORIGIN string `mapstructure:"TM_HEADER_ORIGIN"`
|
||||||
|
TM_HEADER_TENANT_NAME string `mapstructure:"TM_HEADER_TENANT_NAME"`
|
||||||
|
TM_HEADER_USER_AGENT string `mapstructure:"TM_HEADER_USER_AGENT"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var GlobalConfig *Config
|
var GlobalConfig *Config
|
||||||
|
|||||||
22
internal/domain/dto/auth.go
Normal file
22
internal/domain/dto/auth.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Data struct {
|
||||||
|
SourceID int `json:"source_id"`
|
||||||
|
SourceName string `json:"source_name"`
|
||||||
|
ExpiresAt time.Time `json:"expires_at"`
|
||||||
|
Headers map[string]string `json:"headers"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Response struct {
|
||||||
|
Status int `json:"status"`
|
||||||
|
Success bool `json:"success"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Data Data `json:"data"`
|
||||||
|
TraceID string `json:"trace_id"`
|
||||||
|
Timestamp time.Time `json:"timestamp"`
|
||||||
|
}
|
||||||
@ -3,7 +3,8 @@ package dto
|
|||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
type SessionData struct {
|
type SessionData struct {
|
||||||
SessionId string `json:"session_id"`
|
//SessionId string `json:"session_id"`
|
||||||
ExpiresAt time.Time `json:"expires_at"`
|
Headers map[string]string `json:"headers"`
|
||||||
EndPoint string `json:"end_point"`
|
ExpiresAt time.Time `json:"expires_at"`
|
||||||
|
EndPoint string `json:"end_point"`
|
||||||
}
|
}
|
||||||
|
|||||||
16
internal/domain/dto/trace.go
Normal file
16
internal/domain/dto/trace.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type RequestTrace struct {
|
||||||
|
Method string
|
||||||
|
URL string
|
||||||
|
Headers map[string]string
|
||||||
|
RequestBody string
|
||||||
|
Response string
|
||||||
|
StatusCode int
|
||||||
|
Duration time.Duration
|
||||||
|
Retries int
|
||||||
|
StartedAt time.Time
|
||||||
|
EndedAt time.Time
|
||||||
|
}
|
||||||
100
internal/http/external_api/sap_cliente.go
Normal file
100
internal/http/external_api/sap_cliente.go
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
package external_api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/tls"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"github.com/tuusuario/go-sync-service/internal/domain/dto"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Estructura para guardar trazabilidad
|
||||||
|
|
||||||
|
// Client genérico con reintentos
|
||||||
|
type GenericClient struct {
|
||||||
|
Client *http.Client
|
||||||
|
MaxRetries int
|
||||||
|
RetryDelay time.Duration
|
||||||
|
EnableTrace bool // true = guarda trazabilidad
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
func NewGenericClient(maxRetries int, retryDelay time.Duration) *GenericClient {
|
||||||
|
return &GenericClient{
|
||||||
|
Client: &http.Client{Timeout: 30 * time.Second, Transport: &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
}},
|
||||||
|
MaxRetries: maxRetries,
|
||||||
|
RetryDelay: retryDelay,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Método genérico
|
||||||
|
func (gc *GenericClient) DoRequest(method, url string, headers map[string]string, body []byte) (map[string]interface{}, *dto.RequestTrace, error) {
|
||||||
|
trace := &dto.RequestTrace{
|
||||||
|
Method: method,
|
||||||
|
URL: url,
|
||||||
|
Headers: headers,
|
||||||
|
RequestBody: string(body),
|
||||||
|
StartedAt: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastErr error
|
||||||
|
var resp *http.Response
|
||||||
|
|
||||||
|
for attempt := 0; attempt <= gc.MaxRetries; attempt++ {
|
||||||
|
trace.Retries = attempt
|
||||||
|
|
||||||
|
req, err := http.NewRequest(method, url, bytes.NewReader(body))
|
||||||
|
if err != nil {
|
||||||
|
lastErr = err
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Headers
|
||||||
|
for k, v := range headers {
|
||||||
|
req.Header.Set(k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
start := time.Now()
|
||||||
|
resp, err = gc.Client.Do(req)
|
||||||
|
trace.Duration = time.Since(start)
|
||||||
|
|
||||||
|
if err == nil && resp.StatusCode < 500 {
|
||||||
|
break // éxito o error de cliente, no reintentar
|
||||||
|
}
|
||||||
|
|
||||||
|
lastErr = err
|
||||||
|
time.Sleep(gc.RetryDelay * (1 << attempt)) // backoff exponencial
|
||||||
|
}
|
||||||
|
|
||||||
|
if lastErr != nil {
|
||||||
|
trace.EndedAt = time.Now()
|
||||||
|
return nil, trace, lastErr
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
trace.StatusCode = resp.StatusCode
|
||||||
|
bodyResp, _ := io.ReadAll(resp.Body)
|
||||||
|
trace.Response = string(bodyResp)
|
||||||
|
trace.EndedAt = time.Now()
|
||||||
|
|
||||||
|
if resp.StatusCode >= 400 {
|
||||||
|
return nil, trace, errors.New("HTTP error: " + resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si el código de estado es 204 (No Content), no hay cuerpo de respuesta
|
||||||
|
if resp.StatusCode == http.StatusNoContent {
|
||||||
|
return nil, trace, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var result map[string]interface{}
|
||||||
|
if err := json.Unmarshal(bodyResp, &result); err != nil {
|
||||||
|
return nil, trace, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, trace, nil
|
||||||
|
}
|
||||||
@ -3,6 +3,8 @@ package http
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt" // NEW
|
"fmt" // NEW
|
||||||
|
"github.com/tuusuario/go-sync-service/internal/http/external_api"
|
||||||
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -10,7 +12,6 @@ import (
|
|||||||
"github.com/tuusuario/go-sync-service/internal/domain/dto"
|
"github.com/tuusuario/go-sync-service/internal/domain/dto"
|
||||||
"github.com/tuusuario/go-sync-service/internal/domain/model"
|
"github.com/tuusuario/go-sync-service/internal/domain/model"
|
||||||
"github.com/tuusuario/go-sync-service/internal/domain/ports"
|
"github.com/tuusuario/go-sync-service/internal/domain/ports"
|
||||||
"github.com/tuusuario/go-sync-service/internal/security"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -21,90 +22,108 @@ var (
|
|||||||
type SAPSessionProvider struct{}
|
type SAPSessionProvider struct{}
|
||||||
|
|
||||||
func GetSession(cfg ports.RedisConfigProvider, job dto.CronJob, auth dto.ServiceConfig, dbcore ports.Database, logPrefix string) (*dto.SessionData, error) {
|
func GetSession(cfg ports.RedisConfigProvider, job dto.CronJob, auth dto.ServiceConfig, dbcore ports.Database, logPrefix string) (*dto.SessionData, error) {
|
||||||
mutex.Lock()
|
//CLIENT HTTP
|
||||||
defer mutex.Unlock()
|
authenticacion, _, err := Authenticacion(job.UnidadNegocio.CompanyDB)
|
||||||
redisKey = "session:" + job.UnidadNegocio.CompanyName + ":" + job.UnidadNegocio.CompanyDB
|
|
||||||
|
|
||||||
if sess, err := loadSessionFromRedis(cfg, logPrefix); err == nil && time.Now().Before(sess.ExpiresAt) {
|
|
||||||
config.Log.Printf("%v 🔑 Sesión obtenida de Redis %v", logPrefix, redisKey)
|
|
||||||
return sess, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
parametros := map[string]interface{}{
|
|
||||||
"company_name": job.UnidadNegocio.CompanyName,
|
|
||||||
"company_db": job.UnidadNegocio.CompanyDB,
|
|
||||||
}
|
|
||||||
|
|
||||||
credencial, err := dbcore.GetCredencialesFromTemplate(config.GlobalConfig.WhereUnitsBusiness, parametros)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
config.Log.Printf("%v ❌ Error al obtener credenciales: %v", logPrefix, err)
|
log.Printf("Error en autenticacion: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==============================
|
return &dto.SessionData{
|
||||||
// DESCIFRAR PASSWORD (AES-GCM)
|
Headers: authenticacion.Data.Headers,
|
||||||
// ==============================
|
ExpiresAt: authenticacion.Data.ExpiresAt,
|
||||||
key, err := security.LoadEncryptionKey()
|
EndPoint: authenticacion.Data.URL,
|
||||||
if err != nil {
|
}, nil
|
||||||
return nil, fmt.Errorf("%s %v", logPrefix, err)
|
|
||||||
}
|
|
||||||
// Suponemos que credencial.Password viene como base64(nonce||cipher) generado por EncryptAESGCM
|
|
||||||
plainPass, err := security.DecryptAESGCM(credencial.Password, key)
|
|
||||||
if err != nil {
|
|
||||||
config.Log.Printf("%v ❌ Error al descifrar password: %v", logPrefix, err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
credencial.Password = plainPass
|
|
||||||
|
|
||||||
// No loguees secretos. Si necesitas log, hazlo sin password:
|
/*
|
||||||
config.Log.Debugf("%v Obteniendo credenciales para CompanyDB=%s UserName=%s (password oculto)",
|
mutex.Lock()
|
||||||
logPrefix, credencial.CompanyDB, credencial.UserName)
|
defer mutex.Unlock()
|
||||||
|
redisKey = "session:" + job.UnidadNegocio.CompanyName + ":" + job.UnidadNegocio.CompanyDB
|
||||||
config.Log.Printf("%v 🔑 Realizando login...", logPrefix)
|
//REDIS
|
||||||
|
if sess, err := loadSessionFromRedis(cfg, logPrefix); err == nil && time.Now().Before(sess.ExpiresAt) {
|
||||||
mySession := &dto.SessionData{EndPoint: credencial.EndPoint}
|
config.Log.Printf("%v 🔑 Sesión obtenida de Redis %v", logPrefix, redisKey)
|
||||||
|
return sess, nil
|
||||||
if auth.Rest == nil {
|
|
||||||
auth.Rest = &dto.RestOptions{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Preparar el body del login (usa cred.Password en claro ya descifrado)
|
|
||||||
auth = prepareAuthBody(auth, credencial, logPrefix)
|
|
||||||
|
|
||||||
config.Log.Debugf(" %v Url: %v + %v", logPrefix, credencial.EndPoint, auth.Path)
|
|
||||||
resp, err := SendRequest(credencial.EndPoint, auth)
|
|
||||||
if err != nil || resp.IsError() {
|
|
||||||
config.Log.Printf("%v ❌ Error al autenticar: %v", logPrefix, err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if auth.GQL {
|
|
||||||
var dataGraphql struct {
|
|
||||||
Token string `json:"token"`
|
|
||||||
RefreshToken string `json:"refresh_token"`
|
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(resp.Body(), &dataGraphql); err != nil {
|
|
||||||
config.Log.Printf("%v ❌ Error al parsear sesión graphql: %v", logPrefix, err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
mySession.SessionId = dataGraphql.Token
|
|
||||||
mySession.ExpiresAt = time.Now().Add(10 * time.Minute)
|
|
||||||
} else {
|
|
||||||
var dataRest struct {
|
|
||||||
SessionId string `json:"SessionId"`
|
|
||||||
SessionTimeout int `json:"SessionTimeout"`
|
|
||||||
}
|
|
||||||
if err := json.Unmarshal(resp.Body(), &dataRest); err != nil {
|
|
||||||
config.Log.Printf("%v ❌ Error al parsear sesión rest: %v", logPrefix, err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
mySession.SessionId = dataRest.SessionId
|
|
||||||
mySession.ExpiresAt = time.Now().Add(time.Duration(dataRest.SessionTimeout) * time.Minute)
|
|
||||||
}
|
|
||||||
|
|
||||||
config.Log.Printf("%v ✅ Sesión obtenida", logPrefix)
|
|
||||||
saveSessionToRedis(mySession, cfg, logPrefix)
|
|
||||||
return mySession, nil
|
|
||||||
|
parametros := map[string]interface{}{
|
||||||
|
"company_name": job.UnidadNegocio.CompanyName,
|
||||||
|
"company_db": job.UnidadNegocio.CompanyDB,
|
||||||
|
}
|
||||||
|
|
||||||
|
credencial, err := dbcore.GetCredencialesFromTemplate(config.GlobalConfig.WhereUnitsBusiness, parametros)
|
||||||
|
if err != nil {
|
||||||
|
config.Log.Printf("%v ❌ Error al obtener credenciales: %v", logPrefix, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==============================
|
||||||
|
// DESCIFRAR PASSWORD (AES-GCM)
|
||||||
|
// ==============================
|
||||||
|
key, err := security.LoadEncryptionKey()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("%s %v", logPrefix, err)
|
||||||
|
}
|
||||||
|
// Suponemos que credencial.Password viene como base64(nonce||cipher) generado por EncryptAESGCM
|
||||||
|
plainPass, err := security.DecryptAESGCM(credencial.Password, key)
|
||||||
|
if err != nil {
|
||||||
|
config.Log.Printf("%v ❌ Error al descifrar password: %v", logPrefix, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
credencial.Password = plainPass
|
||||||
|
|
||||||
|
// No loguees secretos. Si necesitas log, hazlo sin password:
|
||||||
|
config.Log.Debugf("%v Obteniendo credenciales para CompanyDB=%s UserName=%s (password oculto)",
|
||||||
|
logPrefix, credencial.CompanyDB, credencial.UserName)
|
||||||
|
|
||||||
|
config.Log.Printf("%v 🔑 Realizando login...", logPrefix)
|
||||||
|
|
||||||
|
mySession := &dto.SessionData{EndPoint: credencial.EndPoint}
|
||||||
|
|
||||||
|
if auth.Rest == nil {
|
||||||
|
auth.Rest = &dto.RestOptions{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Preparar el body del login (usa cred.Password en claro ya descifrado)
|
||||||
|
auth = prepareAuthBody(auth, credencial, logPrefix)
|
||||||
|
|
||||||
|
config.Log.Debugf(" %v Url: %v + %v", logPrefix, credencial.EndPoint, auth.Path)
|
||||||
|
resp, err := SendRequest(credencial.EndPoint, auth)
|
||||||
|
if err != nil || resp.IsError() {
|
||||||
|
config.Log.Printf("%v ❌ Error al autenticar: %v", logPrefix, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if auth.GQL {
|
||||||
|
var dataGraphql struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
RefreshToken string `json:"refresh_token"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(resp.Body(), &dataGraphql); err != nil {
|
||||||
|
config.Log.Printf("%v ❌ Error al parsear sesión graphql: %v", logPrefix, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
mySession.SessionId = dataGraphql.Token
|
||||||
|
mySession.ExpiresAt = time.Now().Add(10 * time.Minute)
|
||||||
|
} else {
|
||||||
|
var dataRest struct {
|
||||||
|
SessionId string `json:"SessionId"`
|
||||||
|
SessionTimeout int `json:"SessionTimeout"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(resp.Body(), &dataRest); err != nil {
|
||||||
|
config.Log.Printf("%v ❌ Error al parsear sesión rest: %v", logPrefix, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
mySession.SessionId = dataRest.SessionId
|
||||||
|
mySession.ExpiresAt = time.Now().Add(time.Duration(dataRest.SessionTimeout) * time.Minute)
|
||||||
|
}
|
||||||
|
|
||||||
|
config.Log.Printf("%v ✅ Sesión obtenida", logPrefix)
|
||||||
|
saveSessionToRedis(mySession, cfg, logPrefix)
|
||||||
|
return mySession, nil
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadSessionFromRedis(cfg ports.RedisConfigProvider, logPrefix string) (*dto.SessionData, error) {
|
func loadSessionFromRedis(cfg ports.RedisConfigProvider, logPrefix string) (*dto.SessionData, error) {
|
||||||
@ -151,3 +170,53 @@ func prepareAuthBody(auth dto.ServiceConfig, cred *model.CredencialesSAP, logPre
|
|||||||
}
|
}
|
||||||
return auth
|
return auth
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Authenticacion(company string) (*dto.Response, *dto.RequestTrace, error) {
|
||||||
|
url := config.GlobalConfig.AUTH_ENDPOINT
|
||||||
|
|
||||||
|
headers := map[string]string{
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Authorization": config.GlobalConfig.AUTH_AUTORIZATION,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Crea el cuerpo de la solicitud con el id recibido
|
||||||
|
body := []byte(fmt.Sprintf(`{"name": "%s"}`, company))
|
||||||
|
|
||||||
|
client := external_api.NewGenericClient(3, 3*time.Second)
|
||||||
|
// Hacer la solicitud usando el cliente genérico
|
||||||
|
response, trace, err := client.DoRequest(config.GlobalConfig.AUTH_METHOD, url, headers, body)
|
||||||
|
|
||||||
|
// Manejo de errores
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error en la solicitud: ", err)
|
||||||
|
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deserializar la respuesta en el modelo de dto.Response
|
||||||
|
var responseModel dto.Response
|
||||||
|
err = mapToModel(response, &responseModel)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error al deserializar la respuesta: ", err)
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
log.Printf("TRACE: %+v", trace)
|
||||||
|
log.Printf("RESPUESTA MAP: %+v", response)
|
||||||
|
return &responseModel, trace, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// mapToModel convierte un mapa genérico en el modelo ResponseModel
|
||||||
|
func mapToModel(data map[string]interface{}, model *dto.Response) error {
|
||||||
|
// Utiliza json.Marshal y json.Unmarshal para convertir el mapa en el modelo
|
||||||
|
jsonData, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(jsonData, model)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@ -47,16 +47,17 @@ func SyncData(redis ports.RedisConfigProvider, database *gorm.DB, job dto.CronJo
|
|||||||
hasError = true
|
hasError = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if session == nil || session.SessionId == "" {
|
if session == nil || session.Headers == nil {
|
||||||
config.Log.Println(logPrefix + " ❌ Sesión inválida o vacía")
|
config.Log.Println(logPrefix + " ❌ Sesión inválida o vacía")
|
||||||
hasError = true
|
hasError = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jobIndividual.Service.Headers = session.Headers
|
||||||
if jobIndividual.Service.GQL {
|
if jobIndividual.Service.GQL {
|
||||||
jobIndividual.Service.Headers["Authorization"] = "Bearer " + session.SessionId
|
jobIndividual.Service.Headers["origin"] = config.GlobalConfig.TM_HEADER_ORIGIN
|
||||||
} else {
|
jobIndividual.Service.Headers["tenant-name"] = config.GlobalConfig.TM_HEADER_TENANT_NAME
|
||||||
jobIndividual.Service.Headers["Cookie"] = "B1SESSION=" + session.SessionId
|
jobIndividual.Service.Headers["User-Agent"] = config.GlobalConfig.TM_HEADER_USER_AGENT
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := FetchAllPaginatedManual[map[string]interface{}](session.EndPoint, jobIndividual.Service, logPrefix)
|
response, err := FetchAllPaginatedManual[map[string]interface{}](session.EndPoint, jobIndividual.Service, logPrefix)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user