using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System; using System.Threading.Tasks; using Timeline.Models.Http; using Timeline.Services; using Timeline.Services.Mapper; using Timeline.Services.Token; using Timeline.Services.User; namespace Timeline.Controllers { /// /// Operation about tokens. /// [Route("token")] [ApiController] [ProducesErrorResponseType(typeof(CommonResponse))] public class TokenController : MyControllerBase { private readonly IUserService _userService; private readonly IUserTokenService _userTokenService; private readonly IGenericMapper _mapper; private readonly IClock _clock; public TokenController(IUserService userService, IUserTokenService userTokenService, IGenericMapper mapper, IClock clock) { _userService = userService; _userTokenService = userTokenService; _mapper = mapper; _clock = clock; } /// /// Create a new token for a user. /// /// Result of token creation. [HttpPost("create")] [AllowAnonymous] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task> Create([FromBody] HttpCreateTokenRequest request) { try { DateTime? expireTime = null; if (request.Expire is not null) expireTime = _clock.GetCurrentTime().AddDays(request.Expire.Value); var userId = await _userService.VerifyCredential(request.Username, request.Password); var token = await _userTokenService.CreateTokenAsync(userId, expireTime); var user = await _userService.GetUserAsync(userId); return new HttpCreateTokenResponse { Token = token, User = await _mapper.MapAsync(user, Url, User) }; } catch (EntityNotExistException) { return BadRequestWithCommonResponse(ErrorCodes.TokenController.CreateBadCredential, Resource.MessageTokenCreateBadCredential); } catch (BadPasswordException) { return BadRequestWithCommonResponse(ErrorCodes.TokenController.CreateBadCredential, Resource.MessageTokenCreateBadCredential); } } /// /// Verify a token. /// /// Result of token verification. [HttpPost("verify")] [AllowAnonymous] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task> Verify([FromBody] HttpVerifyTokenRequest request) { try { var tokenInfo = await _userTokenService.ValidateTokenAsync(request.Token); var user = await _userService.GetUserAsync(tokenInfo.UserId); return new HttpVerifyTokenResponse { User = await _mapper.MapAsync(user, Url, User) }; } catch (UserTokenExpiredException) { return BadRequestWithCommonResponse(ErrorCodes.TokenController.VerifyExpired, Resource.MessageTokenVerifyExpired); } catch (UserTokenException) { return BadRequestWithCommonResponse(ErrorCodes.TokenController.VerifyInvalid, Resource.MessageTokenVerifyInvalid); } } } }