Skip to content
Snippets Groups Projects
UserController.cs 3.84 KiB
Newer Older
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using UserMicroservice.Models;
using UserMicroservice.Services;

namespace UserMicroservice.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class UserController : ControllerBase
    {
        private readonly IUserService _userService;
        private readonly IAuthService _authService;

        public UserController(IUserService userService, IAuthService authService)
        {
            _userService = userService;
            _authService = authService;
        }

        #region Auth Endpoints

        // POST: api/Users/register
        [HttpPost("register")]
        public IActionResult Register([FromBody] RegisterModel model)
        {
            User user = _userService.CreateUser(model.Email, model.Username, model.Password);
            if(user == null)
                return BadRequest();

            return authenticateUser(user);
        }

        // POST: api/Users/login
        [HttpPost("login")]
        public IActionResult Login([FromBody] LoginModel model)
        {
            User? user = _userService.GetUser(model.Username, model.Password);
            if(user == null)
                return Unauthorized();

            return authenticateUser(user);
        }

        private IActionResult authenticateUser(User user)
        {
            AuthTokenPair authToken = _authService.AuthenticateUser(user);
            if (authToken == null)
                return BadRequest();

            // Set the access token as an HttpOnly cookie
            Response.Cookies.Append("AccessToken", authToken.AccessToken, new CookieOptions
            {
                HttpOnly = true,
                Secure = true,
                SameSite = SameSiteMode.Strict,
                Expires = DateTimeOffset.UtcNow.AddMinutes(30)
            });

            // Set the refresh token as an HttpOnly cookie
            Response.Cookies.Append("RefreshToken", authToken.RefreshToken, new CookieOptions
            {
                HttpOnly = true,
                Secure = true,
                SameSite = SameSiteMode.Strict,
                Expires = DateTimeOffset.UtcNow.AddDays(2)
            });

            return Ok();
        }

        // POST: api/Users/logout
        [Authorize]
        [HttpPost("logout")]
        public IActionResult Logout()
        {
            string? refreshToken = Request.Cookies["RefreshToken"];
            if(string.IsNullOrEmpty(refreshToken))
                return BadRequest();

            _authService.RevokeRefreshToken(refreshToken);

            // Clear the access token cookie and set it to expire immediately
            Response.Cookies.Append("AccessToken", string.Empty, new CookieOptions
            {
                HttpOnly = true,
                Secure = true,
                Expires = DateTimeOffset.UtcNow.AddSeconds(-1)
            });

            // Clear the refresh token cookie and set it to expire immediately
            Response.Cookies.Append("RefreshToken", string.Empty, new CookieOptions
            {
                HttpOnly = true,
                Secure = true,
                Expires = DateTimeOffset.UtcNow.AddSeconds(-1)
            });

            return Ok();
        }

        #endregion

        // GET: api/Users
        [Authorize]
        [HttpGet()]
        public IActionResult GetUsers()
        {
            List<User> users = _userService.GetUsers();
            if(users == null)
                return BadRequest();

            return Ok(users);
        }

        // GET: api/Users/{id}
        [Authorize]
        [HttpGet("{id}")]
        public IActionResult GetUser(int id)
        {
            User? user = _userService.GetUser(id);
            if(user == null)
                return NotFound($"User with {id} doesnt exist");
            
            return Ok(user);
        }

    }
}