diff --git a/APIFicheros/APIFicheros.csproj b/APIFicheros/APIFicheros.csproj
index 505c4bc..db4869c 100644
--- a/APIFicheros/APIFicheros.csproj
+++ b/APIFicheros/APIFicheros.csproj
@@ -7,6 +7,9 @@
+
+
+
diff --git a/APIFicheros/Controllers/AuthController.cs b/APIFicheros/Controllers/AuthController.cs
new file mode 100644
index 0000000..29890e7
--- /dev/null
+++ b/APIFicheros/Controllers/AuthController.cs
@@ -0,0 +1,58 @@
+using APIFicheros.DTOs;
+using bdAsegasa;
+using bdAsegasa.db;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.IdentityModel.Tokens;
+using System.IdentityModel.Tokens.Jwt;
+using System.Security.Claims;
+using System.Text;
+using tsUtilidades;
+
+namespace APIFicheros.Controllers
+{
+ [ApiController]
+ [Route("[controller]")]
+ public class AuthController : Controller
+ {
+
+ private readonly IConfiguration _configuration;
+
+ public AuthController(IConfiguration configuration)
+ {
+ _configuration = configuration;
+ }
+
+ [AllowAnonymous]
+ [HttpPost("login")]
+ public IActionResult Login([FromBody] DatosAuth loginDto)
+ {
+
+ string token = "";
+ string datosLoginUser = _configuration["DatosLogin:Usuario"];
+ string datosLoginPassword = _configuration["DatosLogin:Password"];
+
+ if (!ModelState.IsValid)
+ {
+ return BadRequest(ModelState);
+ }
+
+ if (loginDto.usuario == datosLoginUser && loginDto.password == datosLoginPassword)
+ {
+ token = Utilidades.AuthenticateUser(loginDto, _configuration);
+ }
+ else
+ {
+ return Unauthorized("Nombre de usuario o contraseña incorrectos.");
+ }
+
+ return Ok(new
+ {
+ Token = token
+ });
+ }
+
+
+ }
+}
diff --git a/APIFicheros/Controllers/ObtenerFicherosController.cs b/APIFicheros/Controllers/ManipularFicherosController.cs
similarity index 54%
rename from APIFicheros/Controllers/ObtenerFicherosController.cs
rename to APIFicheros/Controllers/ManipularFicherosController.cs
index a483c83..7407189 100644
--- a/APIFicheros/Controllers/ObtenerFicherosController.cs
+++ b/APIFicheros/Controllers/ManipularFicherosController.cs
@@ -1,6 +1,8 @@
using APIFicheros.DTOs;
using bdAsegasa;
using bdAsegasa.db;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
@@ -10,11 +12,11 @@ namespace APIFicheros.Controllers
{
[ApiController]
[Route("[controller]")]
- public class ObtenerFicherosController : Controller
+ public class ManipularFicherosController : Controller
{
private readonly IConfiguration _configuration;
private bdAsegasa.tscgestionasegasa bd;
- public ObtenerFicherosController(IConfiguration configuration)
+ public ManipularFicherosController(IConfiguration configuration)
{
_configuration = configuration;
@@ -25,14 +27,12 @@ namespace APIFicheros.Controllers
}
-
[HttpPost("ObtenerFicherosFaltantes")]
- public ActionResult PostNombreBD([FromBody] string numeroPoliza)
+ [Authorize]
+ public ActionResult PostComprobarFicheros([FromBody] string numeroPoliza)
{
-
try
{
-
int idPoliza = bd.polizassg.First(x => x.NumeroPoliza!.Contains(numeroPoliza)).idPoliza;
@@ -54,8 +54,9 @@ namespace APIFicheros.Controllers
return Ok(listadoFicherosFaltantes);
}
- catch (Exception ex) {
-
+ catch (Exception ex)
+ {
+
return BadRequest("Ha ocurrido un error. Mensaje de error: " + ex.Message);
}
@@ -63,5 +64,47 @@ namespace APIFicheros.Controllers
}
+
+
+ [HttpPost("SubirFicherosFaltantes")]
+ [Authorize]
+ public ActionResult PostSubirFicheros([FromBody] DatosFicheros datosFichero)
+ {
+
+ var transaction = bd.Database.BeginTransaction();
+
+ try
+ {
+
+ byte[] contenidoFichero;
+ var ms = new MemoryStream();
+ datosFichero.fichero.CopyTo(ms);
+ contenidoFichero = ms.ToArray();
+
+ int idFichero = Utilidades.guardarFichero(bd, contenidoFichero, datosFichero.fichero.FileName, datosFichero.descripcion);
+
+
+ documentospolizassg documentoObtenido = bd.documentospolizassg.First( x => x.idDocumento == datosFichero.idDocumento);
+
+ documentoObtenido.idFichero = idFichero;
+
+ bd.Update(documentoObtenido);
+
+ bd.SaveChanges();
+
+ transaction.Commit();
+ return Ok();
+
+ }
+ catch (Exception ex)
+ {
+ transaction.Rollback();
+ return BadRequest("Ha ocurrido un error. Mensaje de error: " + ex.Message);
+ }
+
+ }
+
+
+
}
}
diff --git a/APIFicheros/Controllers/WeatherForecastController.cs b/APIFicheros/Controllers/WeatherForecastController.cs
deleted file mode 100644
index 9216ce9..0000000
--- a/APIFicheros/Controllers/WeatherForecastController.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using Microsoft.AspNetCore.Mvc;
-
-namespace APIFicheros.Controllers;
-
-[ApiController]
-[Route("[controller]")]
-public class WeatherForecastController : ControllerBase
-{
- private static readonly string[] Summaries = new[]
- {
- "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
- };
-
- private readonly ILogger _logger;
-
- public WeatherForecastController(ILogger logger)
- {
- _logger = logger;
- }
-
- [HttpGet(Name = "GetWeatherForecast")]
- public IEnumerable Get()
- {
- return Enumerable.Range(1, 5).Select(index => new WeatherForecast
- {
- Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
- TemperatureC = Random.Shared.Next(-20, 55),
- Summary = Summaries[Random.Shared.Next(Summaries.Length)]
- })
- .ToArray();
- }
-}
diff --git a/APIFicheros/DTOs/DatosAuth.cs b/APIFicheros/DTOs/DatosAuth.cs
new file mode 100644
index 0000000..2ed71d7
--- /dev/null
+++ b/APIFicheros/DTOs/DatosAuth.cs
@@ -0,0 +1,8 @@
+namespace APIFicheros.DTOs
+{
+ public class DatosAuth
+ {
+ public string usuario { get; set; }
+ public string password { get; set; }
+ }
+}
diff --git a/APIFicheros/DTOs/DatosFicheros.cs b/APIFicheros/DTOs/DatosFicheros.cs
new file mode 100644
index 0000000..c0669a2
--- /dev/null
+++ b/APIFicheros/DTOs/DatosFicheros.cs
@@ -0,0 +1,9 @@
+namespace APIFicheros.DTOs
+{
+ public class DatosFicheros
+ {
+ public int idDocumento { get; set; }
+ public IFormFile fichero { get; set; }
+ public string descripcion { get; set; }
+ }
+}
diff --git a/APIFicheros/Program.cs b/APIFicheros/Program.cs
index 7bded67..cab2a27 100644
--- a/APIFicheros/Program.cs
+++ b/APIFicheros/Program.cs
@@ -1,32 +1,130 @@
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.IdentityModel.Tokens;
+using System.Text;
+using Microsoft.OpenApi.Models;
+using System.Reflection;
+using System.Text.Json.Serialization;
+
var builder = WebApplication.CreateBuilder(args);
-// Add services to the container.
-
-// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
-builder.Services.AddEndpointsApiExplorer();
-builder.Services.AddSwaggerGen();
-
+// 1. Configuración de Servicios
+// a. Configurar servicios de controladores
builder.Services.AddControllers()
- .AddJsonOptions(options =>
+.ConfigureApiBehaviorOptions(options =>
+{
+ options.SuppressModelStateInvalidFilter = true; // Desactiva la validación automática del estado del modelo
+})
+.AddJsonOptions(options =>
+{
+ options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
+});
+
+// b. Configuración de JWT
+var jwtSettings = builder.Configuration.GetSection("Jwt");
+var keyString = jwtSettings["Key"];
+if (string.IsNullOrEmpty(keyString))
+{
+ throw new ArgumentNullException("JWT Key is not configured.");
+}
+var key = Encoding.UTF8.GetBytes(keyString);
+
+builder.Services.AddAuthentication(options =>
+{
+ options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
+ options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
+})
+.AddJwtBearer(options =>
+{
+ options.TokenValidationParameters = new TokenValidationParameters
{
- options.JsonSerializerOptions.ReferenceHandler =
- System.Text.Json.Serialization.ReferenceHandler.IgnoreCycles;
+ ValidateIssuer = true,
+ ValidIssuer = jwtSettings["Issuer"],
+ ValidateAudience = true,
+ ValidAudience = jwtSettings["Audience"],
+ ValidateLifetime = true,
+ ValidateIssuerSigningKey = true,
+ IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings["Key"])),
+ ValidAlgorithms = new[] { SecurityAlgorithms.HmacSha256 }
+ };
+
+ options.Events = new JwtBearerEvents
+ {
+ OnAuthenticationFailed = ctx =>
+ {
+ var logger = ctx.HttpContext.RequestServices.GetRequiredService>();
+ logger.LogError("NOMBRE FALLO {0}", ctx.Exception.GetType().Name);
+ logger.LogError("MENSAJE FALLO {0}", ctx.Exception.Message);
+ return Task.CompletedTask;
+ },
+ };
+});
+
+// d. Configurar Swagger con soporte para JWT
+builder.Services.AddSwaggerGen(c =>
+{
+ c.SwaggerDoc("v1", new OpenApiInfo { Title = "SwaggerCamcue API", Version = "v1" });
+
+ // Definir el esquema de seguridad JWT
+ var securityScheme = new OpenApiSecurityScheme
+ {
+ Name = "Authorization",
+ Description = "Ingrese 'Bearer' seguido de su token en el campo de texto.\n\nEjemplo: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6...'",
+ In = ParameterLocation.Header,
+ Type = SecuritySchemeType.Http,
+ Scheme = "Bearer",
+ BearerFormat = "JWT"
+ };
+
+ c.AddSecurityDefinition("Bearer", securityScheme);
+
+
+ c.AddSecurityRequirement(new OpenApiSecurityRequirement
+ {
+ {
+ new OpenApiSecurityScheme
+ {
+ Reference = new OpenApiReference
+ {
+ Type = ReferenceType.SecurityScheme,
+ Id = "Bearer"
+ }
+ },
+ Array.Empty()
+ }
});
+});
var app = builder.Build();
-// Configure the HTTP request pipeline.
+// 2. Configuración del Pipeline HTTP
+
+// b. Habilitar Swagger solo en Desarrollo
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
- app.UseSwaggerUI();
+ app.UseSwaggerUI(c =>
+ {
+ c.SwaggerEndpoint("/swagger/v1/swagger.json", "SwaggerCamcue API V1");
+ c.RoutePrefix = string.Empty; // Swagger en la raíz
+ });
}
-app.UseHttpsRedirection();
+app.UseCors(policy =>
+{
+ policy.AllowAnyOrigin()
+ .AllowAnyMethod()
+ .AllowAnyHeader();
+});
+
+//app.UseHttpsRedirection();
+// d. Autenticación y Autorización
+app.UseAuthentication();
app.UseAuthorization();
+// e. Mapear Controladores
app.MapControllers();
+// f. Ejecutar la Aplicación
app.Run();
diff --git a/APIFicheros/Utilidades.cs b/APIFicheros/Utilidades.cs
new file mode 100644
index 0000000..0b95065
--- /dev/null
+++ b/APIFicheros/Utilidades.cs
@@ -0,0 +1,90 @@
+using APIFicheros.DTOs;
+using bdAsegasa;
+using bdAsegasa.db;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.IdentityModel.Tokens;
+using System.IdentityModel.Tokens.Jwt;
+using System.Security.Claims;
+using System.Text;
+using tsUtilidades;
+namespace APIFicheros
+{
+
+
+ public class Utilidades
+ {
+ public static string AuthenticateUser(DatosAuth loginDto, IConfiguration _configuration)
+ {
+ try
+ {
+
+ // Generar token JWT
+ var jwtSettings = _configuration.GetSection("Jwt");
+ var keyBytes = Encoding.UTF8.GetBytes(jwtSettings["Key"]);
+ var key = new SymmetricSecurityKey(keyBytes);
+ var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
+
+
+ var claims = new List
+ {
+ new Claim("usu", "1"),
+ new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
+ };
+
+
+ var expiration = DateTime.UtcNow.AddMinutes(int.Parse(jwtSettings["ExpireMinutes"]));
+
+ var token = new JwtSecurityToken(
+ issuer: jwtSettings["Issuer"],
+ audience: jwtSettings["Audience"],
+ claims: claims,
+ expires: expiration,
+ signingCredentials: creds
+ );
+
+ var tokenString = new JwtSecurityTokenHandler().WriteToken(token);
+
+ return tokenString;
+ }
+ catch (Exception ex)
+ {
+ throw new Exception($"Error en la autenticación: {ex.Message}");
+ }
+ }
+
+
+ public static int guardarFichero(bdAsegasa.tscgestionasegasa bd, byte[] fichero,string nombreFichero ,string? descripcion)
+ {
+ int idFichero = 0;
+
+ try
+ {
+
+ ficheros nuevoFichero = new ficheros();
+
+
+ nuevoFichero.Fichero = fichero;
+ nuevoFichero.NombreFichero = nombreFichero;
+ nuevoFichero.Descripcion = descripcion;
+
+
+
+ bd.ficheros.Add(nuevoFichero);
+
+ bd.SaveChanges();
+
+
+ idFichero = nuevoFichero.idFichero;
+ return idFichero;
+
+ }
+ catch (Exception ex) {
+
+ throw new Exception("Excepción: " + ex.Message);
+ }
+
+ }
+ }
+}
diff --git a/APIFicheros/WeatherForecast.cs b/APIFicheros/WeatherForecast.cs
deleted file mode 100644
index 4d1de37..0000000
--- a/APIFicheros/WeatherForecast.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace APIFicheros;
-
-public class WeatherForecast
-{
- public DateOnly Date { get; set; }
-
- public int TemperatureC { get; set; }
-
- public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
-
- public string? Summary { get; set; }
-}
diff --git a/APIFicheros/appsettings.json b/APIFicheros/appsettings.json
index 48353fb..a938d99 100644
--- a/APIFicheros/appsettings.json
+++ b/APIFicheros/appsettings.json
@@ -1,11 +1,20 @@
{
+ "Jwt": {
+ "Key": "Asegasa_APIFicheros2025_5849651882",
+ "Issuer": "MiAPI_AuthServer",
+ "Audience": "TuAudience",
+ "ExpireMinutes":1
+ },
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
-
+ "DatosLogin": {
+ "Usuario": "ASEGASA",
+ "Password": "Asegasa.2025"
+ },
"Configuracion": {
"SegundosMinimosEntreProcesos": "60",
"HoraProcesosDiarios": "06:30",