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.AssemblyConfigurationAttribute("Debug")] | ||||
| [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.AssemblyTitleAttribute("Elecciones.Infrastructure")] | ||||
| [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 --- | ||||
| # 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 | ||||
| # 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 | ||||
| COPY --from=build /app/publish . | ||||
| ENTRYPOINT ["dotnet", "Elecciones.Worker.dll"] | ||||
| @@ -32,38 +32,7 @@ builder.Services.AddDbContext<EleccionesDbContext>(options => | ||||
| #if DEBUG | ||||
| builder.Services.AddSingleton<IElectoralApiService, FakeElectoralApiService>(); | ||||
| #else | ||||
| // --- SECCIÓN MODIFICADA (FINAL) --- | ||||
| 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 --- | ||||
| builder.Services.AddSingleton<IElectoralApiService, CurlElectoralApiService>(); | ||||
| #endif | ||||
|  | ||||
| builder.Services.AddHostedService<Worker>(); | ||||
|   | ||||
| @@ -4,5 +4,10 @@ | ||||
|       "Default": "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