using Galaeth.ApiServer.Constants; using Galaeth.ApiServer.Models; using Galaeth.Services.Dtos; using Galaeth.Services.Interfaces; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using MyCSharp.HttpUserAgentParser.AspNetCore; using Toycloud.AspNetCore.Mvc.ModelBinding; namespace Galaeth.ApiServer.Controllers; /// /// Authentication API endpoints. /// [ApiController] [Authorize] [Route("v1/auth")] public class AuthenticationController : ApiController { private readonly IAuthenticationService _authenticationService; private readonly IHttpUserAgentParserAccessor _httpUserAgentParserAccessor; /// /// Initializes a new instance of the class. /// /// Instance of . /// Instance of . public AuthenticationController( IAuthenticationService authenticationService, IHttpUserAgentParserAccessor httpUserAgentParserAccessor) { _authenticationService = authenticationService; _httpUserAgentParserAccessor = httpUserAgentParserAccessor; } /// /// Process an authentication (login) request. /// /// Instance of . /// If successful, instance of . [AllowAnonymous] [HttpPost("login")] public async Task Authenticate([FromBodyOrDefault] AuthenticateRequest request) { if (request is null) { return MissingBodyResult(); } var userAgent = _httpUserAgentParserAccessor.Get(Request.HttpContext); if (userAgent is null) { return FailureResult(ApiErrorCodes.UnsupportedUserAgent, "Could not determine user agent"); } var session = await _authenticationService.AuthenticateUser(new AuthenticateUserDto() { Username = request.Username, Password = request.Password, IpAddress = ClientIpAddress(), UserAgent = userAgent.Value, }); return SuccessResult(session); } /// /// Process a refresh token request for user authentication. /// /// Instance of . /// If successful, instance of . [AllowAnonymous] [HttpPost("refresh")] public async Task RefreshSession([FromBodyOrDefault] RefreshUserAuthRequest userAuthRequest) { if (userAuthRequest is null) { return MissingBodyResult(); } var userAgent = _httpUserAgentParserAccessor.Get(Request.HttpContext); if (userAgent is null) { return FailureResult(ApiErrorCodes.UnsupportedUserAgent, "Could not determine user agent"); } var session = await _authenticationService.AuthenticateUser(new RefreshAuthenticationDto() { RefreshToken = userAuthRequest.RefreshToken, IpAddress = ClientIpAddress(), UserAgent = userAgent.Value, }); return SuccessResult(session); } /// /// User's request to change their own password. /// /// Instance of . [HttpPost("pwd")] public async Task ChangePassword([FromBodyOrDefault] ChangePasswordRequest request) { if (request is null) { return MissingBodyResult(); } var userAgent = _httpUserAgentParserAccessor.Get(Request.HttpContext); if (userAgent is null) { return FailureResult(ApiErrorCodes.UnsupportedUserAgent, "Could not determine user agent"); } var newTokens = await _authenticationService.ChangeUserPassword(new ChangePasswordDto() { OldPassword = request.OldPassword, NewPassword = request.NewPassword, UserAgent = userAgent.Value, IpAddress = ClientIpAddress(), }); return SuccessResult(newTokens); } }