Core.Thalos.Service.API/Core.Thalos.Service.API/Controllers/UserController.cs
2025-08-29 16:02:45 -06:00

296 lines
15 KiB
C#

using Asp.Versioning;
using Core.Thalos.Application.UseCases.Users.Input;
using Core.Thalos.Application.UseCases.Users.Ports;
using Core.Thalos.BuildingBlocks;
using Lib.Architecture.BuildingBlocks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Core.Thalos.Service.API.Controllers
{
/// <summary>
/// Handles all requests for user.
/// </summary>
[ApiVersion("1.0")]
[Route("api/v{api-version:apiVersion}/[controller]")]
[Produces("application/json")]
[ApiController]
public class UserController : ControllerBase
{
private readonly IComponentHandler<GetUserRequest> getUserHandler;
private readonly IComponentHandler<GetUserByEmailRequest> getUserByEmailHandler;
private readonly IComponentHandler<GetAllUsersRequest> getAllUsersHandler;
private readonly IComponentHandler<CreateUserRequest> createUserHandler;
private readonly IComponentHandler<UpdateUserRequest> updateUserHandler;
private readonly IComponentHandler<DeleteUserRequest> deleteUserHandler;
private readonly IComponentHandler<ChangeUserStatusRequest> ChangeUserStatusHandler;
private readonly IComponentHandler<LoginUserRequest> loginUserHandler;
private readonly IComponentHandler<LogoutUserRequest> logoutUserHandler;
private readonly IComponentHandler<ValidateUserExistenceRequest> validateUserHandler;
private readonly IComponentHandler<GetTokenAdapterRequest> getTokenAdapterHandler;
private readonly IUserPort port;
/// <summary>
/// Creates a new instance of UserController.
/// </summary>
public UserController(
IComponentHandler<GetUserRequest> getUserHandler,
IComponentHandler<GetUserByEmailRequest> getUserByEmailHandler,
IComponentHandler<GetAllUsersRequest> getAllUsersHandler,
IComponentHandler<CreateUserRequest> createUserHandler,
IComponentHandler<UpdateUserRequest> updateUserHandler,
IComponentHandler<DeleteUserRequest> deleteUserHandler,
IComponentHandler<ChangeUserStatusRequest> changeUserStatusHandler,
IComponentHandler<LoginUserRequest> loginUserHandler,
IComponentHandler<LogoutUserRequest> logoutUserHandler,
IComponentHandler<ValidateUserExistenceRequest> validateUserHandler,
IComponentHandler<GetTokenAdapterRequest> getTokenAdapterHandler,
IUserPort port
)
{
this.createUserHandler = createUserHandler;
this.updateUserHandler = updateUserHandler;
this.deleteUserHandler = deleteUserHandler;
this.ChangeUserStatusHandler = changeUserStatusHandler;
this.getAllUsersHandler = getAllUsersHandler;
this.getUserHandler = getUserHandler;
this.getUserByEmailHandler = getUserByEmailHandler;
this.loginUserHandler = loginUserHandler;
this.logoutUserHandler = logoutUserHandler;
this.validateUserHandler = validateUserHandler;
this.getTokenAdapterHandler = getTokenAdapterHandler;
this.port = port;
}
/// <summary>
/// Gets all the users.
/// </summary>
[HttpGet]
[Route("GetAll")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[Authorize(AuthenticationSchemes = Schemes.DefaultScheme)]
[Permission("UserManagement.Read")]
public async Task<IActionResult> GetAllUsersAsync(CancellationToken cancellationToken)
{
await getAllUsersHandler.ExecuteAsync(new GetAllUsersRequest { }, cancellationToken).ConfigureAwait(false);
return port.ViewModel;
}
/// <summary>
/// Gets the user by mongo identifier.
/// </summary>
[HttpPost]
[Route("GetById")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[Authorize(AuthenticationSchemes = Schemes.DefaultScheme)]
[Permission("UserManagement.Read")]
public async Task<IActionResult> GetUserById([FromBody] GetUserRequest request, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(request._Id)) { return BadRequest("Invalid user mongo identifier"); }
await getUserHandler.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
return port.ViewModel;
}
/// <summary>
/// Gets the user by email.
/// </summary>
[HttpPost]
[Route("GetByEmail")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[Authorize(AuthenticationSchemes = $"{Schemes.DefaultScheme}, {Schemes.GoogleScheme}")]
public async Task<IActionResult> GetUserByEmail([FromBody] GetUserByEmailRequest request, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(request.Email)) { return BadRequest("Invalid user email"); }
await getUserByEmailHandler.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
return port.ViewModel;
}
/// <summary>
/// Creates a new user.
/// </summary>
[HttpPost]
[Route("Create")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[Authorize(AuthenticationSchemes = Schemes.DefaultScheme)]
[Permission("UserManagement.Write")]
public async Task<IActionResult> CreateUserAsync([FromBody] CreateUserRequest newUser, CancellationToken cancellationToken = default)
{
await createUserHandler.ExecuteAsync(newUser, cancellationToken).ConfigureAwait(false);
return port.ViewModel;
}
/// <summary>
/// Updates a full user by mongo identifier.
/// </summary>
[HttpPut("Update")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[Authorize(AuthenticationSchemes = Schemes.DefaultScheme)]
[Permission("UserManagement.Write")]
public async Task<IActionResult> UpdateUserAsync([FromBody] UpdateUserRequest request,
CancellationToken cancellationToken = default)
{
await updateUserHandler.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
return port.ViewModel;
}
/// <summary>
/// Deletes a full user by mongo identifier.
/// </summary>
[HttpDelete("Delete")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[Authorize(AuthenticationSchemes = Schemes.DefaultScheme)]
[Permission("UserManagement.Write")]
public async Task<IActionResult> DeleteUserAsync([FromBody] DeleteUserRequest request,
CancellationToken cancellationToken = default)
{
await deleteUserHandler.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
return port.ViewModel;
}
/// <summary>
/// Logs in the user.
/// </summary>
[HttpPatch("LoginUser")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[Authorize(AuthenticationSchemes = $"{Schemes.DefaultScheme}, {Schemes.GoogleScheme}")]
public async Task<IActionResult> LoginUserAsync([FromBody] LoginUserRequest request, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(request.Email)) { return BadRequest("Invalid user email"); }
await loginUserHandler.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
return port.ViewModel;
}
/// <summary>
/// Logs in the user.
/// </summary>
[HttpPatch("LogOutUser")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> LogOutUserSessionAsync([FromBody] LogoutUserRequest request, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(request.Email)) { return BadRequest("Invalid user email"); }
await logoutUserHandler.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
return port.ViewModel;
}
/// <summary>
/// Changes the status of the user.
/// </summary>
[HttpPatch]
[Route("ChangeStatus")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[Authorize(AuthenticationSchemes = Schemes.DefaultScheme)]
[Permission("UserManagement.Write")]
public async Task<IActionResult> ChangeUserStatusAsync([FromBody] ChangeUserStatusRequest request, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(request._Id)) { return BadRequest("Invalid user mongo identifier"); }
await ChangeUserStatusHandler.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
return port.ViewModel;
}
/// <summary>
/// Validates if a user exists on the database.
/// </summary>
[HttpPost]
[Route("ValidateExistence")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[AllowAnonymous]
public async Task<IActionResult> ValidateUserExistenceAsync([FromBody] ValidateUserExistenceRequest request, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(request.Email)) { return BadRequest("Invalid user email"); }
await validateUserHandler.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
return port.ViewModel;
}
/// <summary>
/// Gets a token for the user, including roles, permissions, and modules.
/// </summary>
[HttpPost]
[Route("GetTokenAdapter")]
[ProducesResponseType(typeof(TokenAdapter), StatusCodes.Status200OK)]
[Authorize(AuthenticationSchemes = $"{Schemes.DefaultScheme}, {Schemes.GoogleScheme}")]
public async Task<IActionResult> GetTokenAdapter([FromBody] GetTokenAdapterRequest request, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(request.Email)) { return BadRequest("Invalid user email"); }
await getTokenAdapterHandler.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
return port.ViewModel;
}
}
}