using System; using System.Threading.Tasks; using AutoMapper; using DevHive.Services.Models.User; using DevHive.Web.Models.User; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using DevHive.Common.Models.Identity; using DevHive.Services.Interfaces; using DevHive.Common.Jwt.Interfaces; using NSwag.Annotations; namespace DevHive.Web.Controllers { /// /// All endpoints for integration with the User /// [ApiController] [Route("/api/[controller]")] [OpenApiController("User Controller")] public class UserController : ControllerBase { private readonly IUserService _userService; private readonly IMapper _userMapper; private readonly IJwtService _jwtService; public UserController(IUserService userService, IMapper mapper, IJwtService jwtService) { this._userService = userService; this._userMapper = mapper; this._jwtService = jwtService; } #region Authentication /// /// Login endpoint for the DevHive Social Platform /// /// Login model with username and password /// A JWT Token for further validation [HttpPost] [AllowAnonymous] [Route("Login")] [OpenApiTags("Authorization")] public async Task Login([FromBody] LoginWebModel loginModel) { LoginServiceModel loginServiceModel = this._userMapper.Map(loginModel); TokenModel tokenModel = await this._userService.LoginUser(loginServiceModel); TokenWebModel tokenWebModel = this._userMapper.Map(tokenModel); return new OkObjectResult(tokenWebModel); } /// /// Register a new User in the DevHive Social Platform /// /// Register model with the new data to provide /// A JWT Token for further validation [HttpPost] [AllowAnonymous] [Route("Register")] [OpenApiTag("Authorization")] public async Task Register([FromBody] RegisterWebModel registerModel) { RegisterServiceModel registerServiceModel = this._userMapper.Map(registerModel); TokenModel tokenModel = await this._userService.RegisterUser(registerServiceModel); TokenWebModel tokenWebModel = this._userMapper.Map(tokenModel); return new CreatedResult("Register", tokenWebModel); } #endregion #region Read /// /// Get a User's information using the Guid /// /// User's Id /// The JWT Token, contained in the header and used for validation /// A full User's read model [HttpGet] [Authorize(Roles = "User,Admin")] public async Task GetById(Guid id, [FromHeader] string authorization) { if (!this._jwtService.ValidateToken(id, authorization)) return new UnauthorizedResult(); UserServiceModel userServiceModel = await this._userService.GetUserById(id); UserWebModel userWebModel = this._userMapper.Map(userServiceModel); return new OkObjectResult(userWebModel); } /// /// Get a User's profile using his username. Does NOT require authorization /// /// User's username /// A trimmed version of the full User's read model [HttpGet] [Route("GetUser")] [AllowAnonymous] public async Task GetUser(string username) { UserServiceModel friendServiceModel = await this._userService.GetUserByUsername(username); UserWebModel friend = this._userMapper.Map(friendServiceModel); return new OkObjectResult(friend); } #endregion #region Update /// /// Full update on User's data. A PUSTINQK can only edit his account /// /// The User's Id /// A full User update model /// The JWT Token, contained in the header and used for validation /// A full User's read model [HttpPut] [Authorize(Roles = "User,Admin")] public async Task Update(Guid id, [FromBody] UpdateUserWebModel updateUserWebModel, [FromHeader] string authorization) { if (!this._jwtService.ValidateToken(id, authorization)) return new UnauthorizedResult(); UpdateUserServiceModel updateUserServiceModel = this._userMapper.Map(updateUserWebModel); updateUserServiceModel.Id = id; UserServiceModel userServiceModel = await this._userService.UpdateUser(updateUserServiceModel); UserWebModel userWebModel = this._userMapper.Map(userServiceModel); return new AcceptedResult("UpdateUser", userWebModel); } #endregion #region Friends [HttpPost] [Route("AddFriend")] [Authorize(Roles = "User,Admin")] public async Task AddFriend(Guid id, [FromBody] UpdateFriendWebModel updateFriendWebModel, [FromHeader] string authorization) { if (!this._jwtService.ValidateToken(id, authorization)) return new UnauthorizedResult(); UpdateFriendServiceModel updateFriendServiceModel = this._userMapper.Map(updateFriendWebModel); bool result = await this._userService.AddFriend(id, updateFriendServiceModel); if (!result) return new BadRequestObjectResult("Could not add User as a friend"); return new OkResult(); } #endregion #region Delete /// /// Delete a User with his Id. A PUSTINQK can only delete his account. An Admin can delete all accounts /// /// The User's Id /// The JWT Token, contained in the header and used for validation /// Ok, BadRequest or Unauthorized [HttpDelete] [Authorize(Roles = "User,Admin")] public async Task Delete(Guid id, [FromHeader] string authorization) { if (!this._jwtService.ValidateToken(id, authorization)) return new UnauthorizedResult(); bool result = await this._userService.DeleteUser(id); if (!result) return new BadRequestObjectResult("Could not delete User"); return new OkResult(); } #endregion /// /// We don't talk about that, NIGGA! /// /// /// [HttpPost] [OpenApiIgnore] [Authorize(Roles = "User,Admin")] [Route("SuperSecretPromotionToAdmin")] public async Task SuperSecretPromotionToAdmin(Guid userId) { return new OkObjectResult(await this._userService.SuperSecretPromotionToAdmin(userId)); } } }