using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using QuotifyBE.Data; using QuotifyBE.Entities; using QuotifyBE.DTOs; using QuotifyBE.Mapping; using Microsoft.AspNetCore.Cors; namespace QuotifyBE.Controllers; [ApiController] [EnableCors] [Route("api/v1/auth")] [Produces("application/json")] public class AuthController : ControllerBase { private readonly IConfiguration _appsettings; private readonly ApplicationDbContext _db; private readonly GeneralUseHelpers guhf; public AuthController(IConfiguration appsettings, ApplicationDbContext db, GeneralUseHelpers GUHF) { _db = db; _appsettings = appsettings; guhf = GUHF; } // POST /api/v1/auth/login /// /// Log-in endpoint /// /// /// Allows to generate a JWT valid for 5 minutes. /// The token needs to be passed to other, secured endpoints /// in the Authorization header, e.g.: Authorization: bearer {jwt} /// /// User's credentials (email and password) /// JWT valid for 5 minutes and basic user data. /// Returned on request with valid credentials. Contains the token, but also user data. /// Returned on request with missing form data (email, password or both) /// Returned on request with unknown pair of email and password (wrong password) /// Returned on request with unknwon email [HttpPost("login")] [EnableCors] [ProducesResponseType(typeof(SuccessfulLoginDTO), 200)] [ProducesResponseType(typeof(ErrorDTO), 400)] [ProducesResponseType(typeof(ErrorDTO), 401)] [ProducesResponseType(typeof(ErrorDTO), 404)] public async Task Login([FromBody] UserLoginDTO formUser) { // Ensure the form is complete if (formUser.Email == null || formUser.Password == null) { return BadRequest(new {status = "error", error_msg = "Form contains missing data"}); } // Find the user with retrieved e-mail User? user = await guhf.GetUserFromEmail(formUser.Email); if (user == null) { return NotFound(new {status = "error", error_msg = "User not found"}); } // Hash the password and compare with the user-provided one string hashedFormPassword = guhf.HashWithSHA512(formUser.Password); if (hashedFormPassword == user.PasswordHash) { // All set - generate the token and return it var token = guhf.GenerateJwtToken(user); SuccessfulLoginDTO response = user.ToSuccessfulLoginDTO(token, guhf.UserRoleAsStr(user)); return Ok(response); } else return Unauthorized(new {status = "error", error_msg = "Unknown pair of email and password"}); } // GET /api/v1/auth/some_values /// /// [AUTHED] Dummy, authed endpoint /// /// /// Dummy, authed endpoint used to test JWTs. ///

/// Important! /// Authed endpoints expect Authorization header, e.g.: /// Authorization: bearer {jwt} ///
/// Dummy json /// Returned on request with valid credentials /// Returned on request with invalid JWT [HttpGet("some_values")] [Authorize] [EnableCors] [ProducesResponseType(200)] [ProducesResponseType(401)] public IActionResult GetValues() { return Ok(new string[] { "value1", "value2" }); } // GET /api/v1/auth/user_role /// /// [AUTHED] Get user role as a string /// /// /// Authed endpoint used to check human-readable user role. /// /// Json containing single field "role" /// Returned on request with valid credentials /// Returned on request with JWT whose user could not be found (sanity check) [HttpGet("user_role")] [Authorize] [EnableCors] [ProducesResponseType(200)] [ProducesResponseType(typeof(ErrorDTO), 400)] public IActionResult GetUserRole() { // Get user from token User? u = guhf.GetUserFromToken(Request.Headers.Authorization!); if (u == null) return BadRequest(new ErrorDTO { Status = "error", Error_msg = "User not found" }); // Return the role as a string return Ok(new { Role = guhf.UserRoleAsStr(u) }); } // GET /api/v1/auth/me /// /// [AUTHED] Get user info /// /// /// Authed endpoint used to get info about the user. /// /// Json containing user info DTO /// Returned on request with valid credentials /// Returned on request with JWT whose user could not be found (sanity check) [HttpGet("me")] [Authorize] [EnableCors] [ProducesResponseType(typeof(UserInfoDTO), 200)] [ProducesResponseType(typeof(ErrorDTO), 400)] public IActionResult GetUserData() { // Get user token from Authorization header User? u = guhf.GetUserFromToken(Request.Headers.Authorization!); if (u == null) // sanity check return BadRequest(new ErrorDTO { Status = "error", Error_msg = "User not found" }); // Return user data as a DTO return Ok(u.ToUserInfoDTO(guhf.UserRoleAsStr(u))); } }