201 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			201 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using Elecciones.Database;
 | |
| using Microsoft.EntityFrameworkCore;
 | |
| using Serilog;
 | |
| using Elecciones.Core.Services;
 | |
| using Elecciones.Infrastructure.Services;
 | |
| using System.Text;
 | |
| using Microsoft.AspNetCore.Authentication.JwtBearer;
 | |
| using Microsoft.IdentityModel.Tokens;
 | |
| using Elecciones.Database.Entities;
 | |
| using System.Text.Json.Serialization;
 | |
| using Microsoft.AspNetCore.HttpOverrides;
 | |
| 
 | |
| // Esta es la estructura estándar y recomendada.
 | |
| var builder = WebApplication.CreateBuilder(args);
 | |
| 
 | |
| // 1. Configurar Serilog. Esta es la forma correcta de integrarlo.
 | |
| builder.Host.UseSerilog((context, services, configuration) => configuration
 | |
|     .ReadFrom.Configuration(context.Configuration)
 | |
|     .ReadFrom.Services(services)
 | |
|     .Enrich.FromLogContext()
 | |
|     .WriteTo.Console()
 | |
|     .WriteTo.File("logs/api-.log", rollingInterval: RollingInterval.Day));
 | |
| 
 | |
| // 2. Añadir servicios al contenedor.
 | |
| var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
 | |
| builder.Services.AddDbContext<EleccionesDbContext>(options =>
 | |
|     options.UseSqlServer(connectionString));
 | |
| 
 | |
| builder.Services.AddScoped<IPasswordHasher, PasswordHasher>();
 | |
| 
 | |
| builder.Services.AddControllers().AddJsonOptions(options =>
 | |
| {
 | |
|     // Esto le dice al serializador que maneje las referencias circulares
 | |
|     options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
 | |
| });
 | |
| 
 | |
| var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
 | |
| builder.Services.AddCors(options =>
 | |
| {
 | |
|     options.AddPolicy(name: MyAllowSpecificOrigins,
 | |
|                       policy =>
 | |
|                       {
 | |
|                           policy.WithOrigins(
 | |
|                               "http://localhost:5173",
 | |
|                               "http://localhost:5174",
 | |
|                               "http://192.168.5.128:8700",
 | |
|                               "https://www.eldia.com",
 | |
|                               "https://extras.eldia.com",
 | |
|                               "https://eldia.mustang.cloud"
 | |
|                           )
 | |
|                           .AllowAnyHeader()
 | |
|                           .AllowAnyMethod();
 | |
|                       });
 | |
| });
 | |
| 
 | |
| builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
 | |
|     .AddJwtBearer(options =>
 | |
|     {
 | |
|         options.TokenValidationParameters = new TokenValidationParameters
 | |
|         {
 | |
|             ValidateIssuer = true,
 | |
|             ValidateAudience = true,
 | |
|             ValidateLifetime = true,
 | |
|             ValidateIssuerSigningKey = true,
 | |
|             ValidIssuer = builder.Configuration["Jwt:Issuer"],
 | |
|             ValidAudience = builder.Configuration["Jwt:Audience"],
 | |
|             IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]!))
 | |
|         };
 | |
|     });
 | |
| 
 | |
| builder.Services.AddEndpointsApiExplorer();
 | |
| builder.Services.AddSwaggerGen();
 | |
| 
 | |
| 
 | |
| builder.Services.Configure<ForwardedHeadersOptions>(options =>
 | |
| {
 | |
|     options.ForwardedHeaders =
 | |
|         ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
 | |
|     options.KnownNetworks.Clear();
 | |
|     options.KnownProxies.Clear();
 | |
| });
 | |
| 
 | |
| // 3. Construir la aplicación.
 | |
| var app = builder.Build();
 | |
| 
 | |
| app.UseForwardedHeaders();
 | |
| 
 | |
| // Seeder para el usuario admin
 | |
| using (var scope = app.Services.CreateScope())
 | |
| {
 | |
|     var services = scope.ServiceProvider;
 | |
|     try
 | |
|     {
 | |
|         var context = services.GetRequiredService<EleccionesDbContext>();
 | |
|         var hasher = services.GetRequiredService<IPasswordHasher>();
 | |
|         if (!context.AdminUsers.Any())
 | |
|         {
 | |
|             var (hash, salt) = hasher.HashPassword("PTP847elec");
 | |
|             context.AdminUsers.Add(new Elecciones.Database.Entities.AdminUser
 | |
|             {
 | |
|                 Username = "admin",
 | |
|                 PasswordHash = hash,
 | |
|                 PasswordSalt = salt
 | |
|             });
 | |
|             context.SaveChanges();
 | |
|             Console.WriteLine("--> Admin user seeded.");
 | |
|         }
 | |
|     }
 | |
|     catch (Exception ex)
 | |
|     {
 | |
|         var logger = services.GetRequiredService<ILogger<Program>>();
 | |
|         logger.LogError(ex, "An error occurred while seeding the database.");
 | |
|     }
 | |
| }
 | |
| 
 | |
| // Seeder para las bancas vacías
 | |
| using (var scope = app.Services.CreateScope())
 | |
| {
 | |
|     var services = scope.ServiceProvider;
 | |
|     var context = services.GetRequiredService<EleccionesDbContext>();
 | |
|     if (!context.Bancadas.Any())
 | |
|     {
 | |
|         var bancas = new List<Bancada>();
 | |
|         // 92 bancas de diputados
 | |
|         for (int i = 1; i <= 92; i++) // Bucle de 1 a 92
 | |
|         {
 | |
|             bancas.Add(new Bancada
 | |
|             {
 | |
|                 Camara = Elecciones.Core.Enums.TipoCamara.Diputados,
 | |
|                 NumeroBanca = i // Asignamos el número de banca
 | |
|             });
 | |
|         }
 | |
|         // 46 bancas de senadores
 | |
|         for (int i = 1; i <= 46; i++) // Bucle de 1 a 46
 | |
|         {
 | |
|             bancas.Add(new Bancada
 | |
|             {
 | |
|                 Camara = Elecciones.Core.Enums.TipoCamara.Senadores,
 | |
|                 NumeroBanca = i // Asignamos el número de banca
 | |
|             });
 | |
|         }
 | |
|         context.Bancadas.AddRange(bancas);
 | |
|         context.SaveChanges();
 | |
|         Console.WriteLine("--> Seeded 138 bancas físicas.");
 | |
|     }
 | |
| }
 | |
| 
 | |
| // Seeder para las configuraciones por defecto
 | |
| using (var scope = app.Services.CreateScope())
 | |
| {
 | |
|     var services = scope.ServiceProvider;
 | |
|     var context = services.GetRequiredService<EleccionesDbContext>();
 | |
|     if (!context.Configuraciones.Any(c => c.Clave == "MostrarOcupantes"))
 | |
|     {
 | |
|         context.Configuraciones.Add(new Configuracion { Clave = "MostrarOcupantes", Valor = "true" });
 | |
|         context.SaveChanges();
 | |
|         Console.WriteLine("--> Seeded default configuration 'MostrarOcupantes'.");
 | |
|     }
 | |
|     if (!context.Configuraciones.Any(c => c.Clave == "TickerResultadosCantidad"))
 | |
|     {
 | |
|         context.Configuraciones.Add(new Configuracion { Clave = "TickerResultadosCantidad", Valor = "3" });
 | |
|         context.Configuraciones.Add(new Configuracion { Clave = "ConcejalesResultadosCantidad", Valor = "5" });
 | |
|         context.SaveChanges();
 | |
|         Console.WriteLine("--> Seeded default configuration 'TickerResultadosCantidad'.");
 | |
|     }
 | |
| }
 | |
| 
 | |
| // Configurar el pipeline de peticiones HTTP.
 | |
| // Añadimos el logging de peticiones de Serilog aquí.
 | |
| app.UseSerilogRequestLogging();
 | |
| 
 | |
| if (app.Environment.IsDevelopment())
 | |
| {
 | |
|     app.UseSwagger();
 | |
|     app.UseSwaggerUI();
 | |
| }
 | |
| 
 | |
| // 1. Redirección a HTTPS (si se usa)
 | |
| //app.UseHttpsRedirection();
 | |
| 
 | |
| // 2. Middleware de Enrutamiento. ¡CLAVE!
 | |
| //    Determina a qué endpoint irá la petición.
 | |
| app.UseRouting();
 | |
| 
 | |
| // 3. Middleware de CORS.
 | |
| //    Ahora se ejecuta sabiendo a qué endpoint se dirige la petición.
 | |
| app.UseCors(MyAllowSpecificOrigins);
 | |
| 
 | |
| // 4. Middleware de Autenticación.
 | |
| //    Identifica quién es el usuario a partir del token.
 | |
| app.UseAuthentication();
 | |
| 
 | |
| // 5. Middleware de Autorización.
 | |
| //    Verifica si el usuario identificado tiene permiso para acceder al endpoint.
 | |
| app.UseAuthorization();
 | |
| 
 | |
| // 6. Mapea los controladores a los endpoints que el enrutador descubrió.
 | |
| app.MapControllers();
 | |
| 
 | |
| // 5. Ejecutar la aplicación.
 | |
| app.Run(); |