< Summary

Information
Class: CoWorkingApp.API.Infrastructure.Presentation.Controllers.LoginUserController
Assembly: CoWorkingApp.API
File(s): H:\Vicentico\Proyectos\CoWorkingApp Project\CoWorkingApp\CoWorkingApp.API\Infrastructure\Presentation\Controllers\LoginUserController.cs
Line coverage
100%
Covered lines: 47
Uncovered lines: 0
Coverable lines: 47
Total lines: 120
Line coverage: 100%
Branch coverage
100%
Covered branches: 6
Total branches: 6
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)100%4100%
Login()100%2100%
BuildToken(...)100%1100%

File(s)

H:\Vicentico\Proyectos\CoWorkingApp Project\CoWorkingApp\CoWorkingApp.API\Infrastructure\Presentation\Controllers\LoginUserController.cs

#LineLine coverage
 1using CoWorkingApp.Core.Application.Abstracts;
 2using CoWorkingApp.Core.Application.Contracts.Services;
 3using CoWorkingApp.Core.Domain.DTOs;
 4using Microsoft.AspNetCore.Authorization;
 5using Microsoft.AspNetCore.Cors;
 6using Microsoft.AspNetCore.Mvc;
 7using Microsoft.IdentityModel.Tokens;
 8using System.IdentityModel.Tokens.Jwt;
 9using System.Security.Claims;
 10using System.Text;
 11
 12namespace CoWorkingApp.API.Infrastructure.Presentation.Controllers
 13{
 14    /// <summary>
 15    /// Controlador para operaciones relacionadas con la autenticación de usuarios.
 16    /// </summary>
 17    [EnableCors("MyPolicy")] // Habilita CORS para este controlador específico
 18    [ApiController]
 19    [Route("[controller]s")] // Ruta del controlador, en plural por convención RESTful
 20    public class LoginUserController : ControllerBase
 21    {
 22        private readonly IUserService _service;
 23        private readonly IConfiguration _configuration;
 24
 25        /// <summary>
 26        /// Constructor de la clase LoginUserController.
 27        /// </summary>
 28        /// <param name="service">Instancia del servicio de usuarios.</param>
 29        /// <param name="configuration">Instancia de IConfiguration para acceder a la configuración de la aplicación.</p
 730        public LoginUserController(IUserService service, IConfiguration configuration)
 731        {
 732            _service = service ?? throw new ArgumentNullException(nameof(service));
 633            _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
 534        }
 35
 36        /// <summary>
 37        /// Método para realizar la autenticación de un usuario.
 38        /// </summary>
 39        /// <param name="user">Datos de usuario (correo y contraseña) para autenticación.</param>
 40        /// <returns>ActionResult con el token generado o un mensaje de error.</returns>
 41        [HttpPost]
 42        [AllowAnonymous] // Permite el acceso a este método sin autenticación
 43        [Route("validateuser")]
 44        public async Task<IActionResult> Login([FromBody] UserRequest user)
 445        {
 46            try
 447            {
 48                // Autenticar al usuario utilizando el servicio
 449                var authenticatedUser = await _service.AuthenticateAsync(user);
 50
 351                if (!authenticatedUser.Success)
 152                {
 53                    // Usuario no autenticado, devuelve un Unauthorized con un mensaje de error
 154                    authenticatedUser.Message = "Invalid email or password";
 155                    authenticatedUser.Errors.Add(authenticatedUser.Message);
 156                    return Unauthorized(authenticatedUser);
 57                }
 58
 59                // Usuario autenticado, generamos un token JWT
 260                var token = BuildToken(authenticatedUser);
 61
 62                // Retorna el token en la respuesta
 263                return Ok(new { Response = authenticatedUser, Token = token });
 64            }
 165            catch (Exception)
 166            {
 67                // Manejar cualquier error y devolver un mensaje de error
 168                var exception = new Exception("An unexpected error occurred while retrieving all entities");
 169                var response = ResponseMessage.HandleException<UserResponse>(exception);
 170                return StatusCode(500, response);
 71            }
 472        }
 73
 74        /// <summary>
 75        /// Método para construir el token JWT.
 76        /// </summary>
 77        /// <param name="user">Usuario autenticado para el cual se genera el token.</param>
 78        /// <returns>JsonResult con el token generado.</returns>
 79        private JsonResult BuildToken(UserResponse user)
 280        {
 81            // Obtener el origen del emisor y la audiencia desde la configuración
 282            string issuer = _configuration["Auth:Jwt:Issuer"];
 283            string audience = _configuration["Auth:Jwt:Audience"];
 84
 85            // Datos a incluir en el token
 286            var claims = new[]
 287            {
 288                new Claim(ClaimTypes.Name, user.Name),
 289                new Claim(ClaimTypes.Name, user.LastName),
 290                new Claim(ClaimTypes.Email, user.Email),
 291            };
 92
 93            // Generar la clave secreta para firmar el token
 294            string secretKey = _configuration["Auth:Jwt:SecretKey"];
 295            var key = Encoding.UTF8.GetBytes(secretKey);
 296            var symmetricSecurityKey = new SymmetricSecurityKey(key);
 297            var creds = new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha256);
 98
 99            // Calcular el tiempo de validez del token
 2100            DateTime now = DateTime.Now;
 2101            double minutes = Convert.ToDouble(_configuration["Auth:Jwt:TokenExpirationInMinutes"]);
 2102            DateTime expiredDateTime = now.AddMinutes(minutes);
 103
 104            // Generar el token JWT
 2105            var token = new JwtSecurityToken(issuer,
 2106                                             audience,
 2107                                             claims,
 2108                                             expires: expiredDateTime,
 2109                                             signingCredentials: creds
 2110            );
 111
 112            // Escribir el token como una cadena
 2113            var tokenSecurity = new JwtSecurityTokenHandler();
 2114            var tokenString = tokenSecurity.WriteToken(token);
 115
 116            // Retornar el token en un JsonResult
 2117            return new JsonResult(new { Token = tokenString });
 2118        }
 119    }
 120}