galaeth-draft/Galaeth.ApiServer/Controllers/AuthenticationController.cs

129 lines
4.3 KiB
C#
Raw Normal View History

2024-11-17 10:31:01 +01:00
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;
/// <summary>
/// Authentication API endpoints.
/// </summary>
[ApiController]
[Authorize]
[Route("v1/auth")]
public class AuthenticationController : ApiController
{
private readonly IAuthenticationService _authenticationService;
private readonly IHttpUserAgentParserAccessor _httpUserAgentParserAccessor;
/// <summary>
/// Initializes a new instance of the <see cref="AuthenticationController"/> class.
/// </summary>
/// <param name="authenticationService">Instance of <see cref="IAuthenticationService"/>.</param>
/// <param name="httpUserAgentParserAccessor">Instance of <see cref="IHttpUserAgentParserAccessor"/>.</param>
public AuthenticationController(
IAuthenticationService authenticationService,
IHttpUserAgentParserAccessor httpUserAgentParserAccessor)
{
_authenticationService = authenticationService;
_httpUserAgentParserAccessor = httpUserAgentParserAccessor;
}
/// <summary>
/// Process an authentication (login) request.
/// </summary>
/// <param name="request">Instance of <see cref="AuthenticateRequest"/>.</param>
/// <returns>If successful, instance of <see cref="AccessTokensDto"/>.</returns>
[AllowAnonymous]
[HttpPost("login")]
public async Task<IActionResult> 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);
}
/// <summary>
/// Process a refresh token request for user authentication.
/// </summary>
/// <param name="userAuthRequest">Instance of <see cref="RefreshUserAuthRequest"/>.</param>
/// <returns>If successful, instance of <see cref="AccessTokensDto"/>.</returns>
[AllowAnonymous]
[HttpPost("refresh")]
public async Task<IActionResult> 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);
}
/// <summary>
/// User's request to change their own password.
/// </summary>
/// <param name="request">Instance of <see cref="ChangePasswordRequest"/>.</param>
[HttpPost("pwd")]
public async Task<IActionResult> 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);
}
}