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);
}
}