Fix 1807
This commit is contained in:
@@ -0,0 +1,83 @@
|
|||||||
|
using Elecciones.Core.DTOs;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Elecciones.Core.DTOs.BancaDto;
|
||||||
|
|
||||||
|
namespace Elecciones.Infrastructure.Services;
|
||||||
|
|
||||||
|
// Implementación de emergencia que usa el comando 'curl' del sistema operativo
|
||||||
|
public class CurlElectoralApiService : IElectoralApiService
|
||||||
|
{
|
||||||
|
private readonly ILogger<CurlElectoralApiService> _logger;
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
private readonly string _baseUrl;
|
||||||
|
|
||||||
|
public CurlElectoralApiService(ILogger<CurlElectoralApiService> logger, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_configuration = configuration;
|
||||||
|
_baseUrl = _configuration["ElectoralApi:BaseUrl"] ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<(int, string)> ExecuteCurlCommand(string arguments)
|
||||||
|
{
|
||||||
|
var process = new Process
|
||||||
|
{
|
||||||
|
StartInfo = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = "curl",
|
||||||
|
Arguments = arguments,
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
RedirectStandardError = true,
|
||||||
|
UseShellExecute = false,
|
||||||
|
CreateNoWindow = true,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
process.Start();
|
||||||
|
string output = await process.StandardOutput.ReadToEndAsync();
|
||||||
|
string error = await process.StandardError.ReadToEndAsync();
|
||||||
|
await process.WaitForExitAsync();
|
||||||
|
|
||||||
|
if (process.ExitCode != 0)
|
||||||
|
{
|
||||||
|
_logger.LogError("Error al ejecutar curl. Exit Code: {ExitCode}. Error: {Error}", process.ExitCode, error);
|
||||||
|
return (-1, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extraemos el código de estado HTTP del final del stderr si usamos -w
|
||||||
|
// (Simplificación: asumimos 200 si el ExitCode es 0)
|
||||||
|
return (200, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string?> GetAuthTokenAsync()
|
||||||
|
{
|
||||||
|
var username = _configuration["ElectoralApi:Username"];
|
||||||
|
var password = _configuration["ElectoralApi:Password"];
|
||||||
|
var arguments = $"-s -H \"username: {username}\" -H \"password: {password}\" \"{_baseUrl}/api/createtoken\"";
|
||||||
|
|
||||||
|
var (status, output) = await ExecuteCurlCommand(arguments);
|
||||||
|
if (status != 200) return null;
|
||||||
|
|
||||||
|
var tokenResponse = JsonSerializer.Deserialize<TokenResponse>(output);
|
||||||
|
return tokenResponse?.Data?.AccessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementa los demás métodos de la interfaz usando el mismo patrón
|
||||||
|
// ...
|
||||||
|
// Por ahora, solo necesitamos GetAuthTokenAsync para validar la conexión.
|
||||||
|
public Task<List<CategoriaDto>?> GetCategoriasAsync(string authToken) => Task.FromResult<List<CategoriaDto>?>(null);
|
||||||
|
public Task<List<CatalogoDto>?> GetCatalogoCompletoAsync(string authToken) => Task.FromResult<List<CatalogoDto>?>(null);
|
||||||
|
public Task<List<AgrupacionDto>?> GetAgrupacionesAsync(string authToken, string distritoId, int categoriaId) => Task.FromResult<List<AgrupacionDto>?>(null);
|
||||||
|
public Task<ResultadosDto?> GetResultadosAsync(string authToken, string distritoId, string seccionId, string municipioId) => Task.FromResult<ResultadosDto?>(null);
|
||||||
|
public Task<RepartoBancasDto?> GetBancasAsync(string authToken, string distritoId, string seccionId) => Task.FromResult<RepartoBancasDto?>(null);
|
||||||
|
public Task<List<string[]>?> GetTelegramasTotalizadosAsync(string authToken, string distritoId, string seccionId) => Task.FromResult<List<string[]>?>(null);
|
||||||
|
public Task<TelegramaFileDto?> GetTelegramaFileAsync(string authToken, string mesaId) => Task.FromResult<TelegramaFileDto?>(null);
|
||||||
|
public Task<ResumenDto?> GetResumenAsync(string authToken, string distritoId) => Task.FromResult<ResumenDto?>(null);
|
||||||
|
public Task<EstadoRecuentoGeneralDto?> GetEstadoRecuentoGeneralAsync(string authToken, string distritoId) => Task.FromResult<EstadoRecuentoGeneralDto?>(null);
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ using System.Reflection;
|
|||||||
[assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Infrastructure")]
|
[assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Infrastructure")]
|
||||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+39b1e9707275ed59ac4a7d32e26b951186a346bb")]
|
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+75ff9d5593b957c5ae0d08223a689a95181172d5")]
|
||||||
[assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Infrastructure")]
|
[assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Infrastructure")]
|
||||||
[assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Infrastructure")]
|
[assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Infrastructure")]
|
||||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||||
|
|||||||
@@ -19,6 +19,12 @@ RUN dotnet publish "Elecciones.Worker.csproj" -c Release -o /app/publish
|
|||||||
# --- Etapa 2: Final ---
|
# --- Etapa 2: Final ---
|
||||||
# Usamos la imagen de runtime genérica de .NET, ya que no necesita ASP.NET
|
# Usamos la imagen de runtime genérica de .NET, ya que no necesita ASP.NET
|
||||||
FROM mcr.microsoft.com/dotnet/runtime:9.0 AS final
|
FROM mcr.microsoft.com/dotnet/runtime:9.0 AS final
|
||||||
|
# Instalamos curl y ca-certificates para las peticiones HTTP
|
||||||
|
USER root
|
||||||
|
RUN apt-get update && apt-get install -y curl ca-certificates
|
||||||
|
USER app
|
||||||
|
# --- FIN DE LA SECCIÓN ---
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=build /app/publish .
|
COPY --from=build /app/publish .
|
||||||
ENTRYPOINT ["dotnet", "Elecciones.Worker.dll"]
|
ENTRYPOINT ["dotnet", "Elecciones.Worker.dll"]
|
||||||
@@ -32,38 +32,7 @@ builder.Services.AddDbContext<EleccionesDbContext>(options =>
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
builder.Services.AddSingleton<IElectoralApiService, FakeElectoralApiService>();
|
builder.Services.AddSingleton<IElectoralApiService, FakeElectoralApiService>();
|
||||||
#else
|
#else
|
||||||
// --- SECCIÓN MODIFICADA (FINAL) ---
|
builder.Services.AddSingleton<IElectoralApiService, CurlElectoralApiService>();
|
||||||
builder.Services.AddHttpClient("ElectoralApiClient", client =>
|
|
||||||
{
|
|
||||||
var baseUrl = builder.Configuration["ElectoralApi:BaseUrl"];
|
|
||||||
if (!string.IsNullOrEmpty(baseUrl))
|
|
||||||
{
|
|
||||||
client.BaseAddress = new Uri(baseUrl);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.ConfigurePrimaryHttpMessageHandler(() =>
|
|
||||||
{
|
|
||||||
return new SocketsHttpHandler
|
|
||||||
{
|
|
||||||
SslOptions = new SslClientAuthenticationOptions
|
|
||||||
{
|
|
||||||
// Forzamos el protocolo TLS 1.3
|
|
||||||
EnabledSslProtocols = SslProtocols.Tls13,
|
|
||||||
|
|
||||||
// --- ¡¡¡LA LÍNEA CLAVE CORREGIDA!!! ---
|
|
||||||
// Forzamos explícitamente los únicos 3 cipher suites que el servidor acepta.
|
|
||||||
CipherSuitesPolicy = new CipherSuitesPolicy(new[]
|
|
||||||
{
|
|
||||||
TlsCipherSuite.TLS_AES_128_GCM_SHA256,
|
|
||||||
TlsCipherSuite.TLS_AES_256_GCM_SHA384,
|
|
||||||
TlsCipherSuite.TLS_CHACHA20_POLY1305_SHA256
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.Services.AddSingleton<IElectoralApiService, ElectoralApiService>();
|
|
||||||
// --- FIN DE LA SECCIÓN MODIFICADA ---
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
builder.Services.AddHostedService<Worker>();
|
builder.Services.AddHostedService<Worker>();
|
||||||
|
|||||||
@@ -4,5 +4,10 @@
|
|||||||
"Default": "Information",
|
"Default": "Information",
|
||||||
"Microsoft.Hosting.Lifetime": "Information"
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"ElectoralApi": {
|
||||||
|
"BaseUrl": "https://api.eleccionesbonaerenses.gba.gob.ar",
|
||||||
|
"Username": "30500094156@elecciones2025.onmicrosoft.com",
|
||||||
|
"Password": "PTP847elec"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user