Core.Thalos.Service.API/Core.Cerberos.Service.API/Controllers/UserController.cs
Sergio Matias Urquin 7d760b589e Add project files.
2025-04-29 18:56:29 -06:00

433 lines
22 KiB
C#

using Asp.Versioning;
using Core.Cerberos.Adapters;
using Core.Cerberos.Adapters.Attributes;
using Core.Cerberos.Adapters.Common.Constants;
using Core.Cerberos.Application.UseCases.Users.Input;
using Core.Cerberos.Application.UseCases.Users.Ports;
using Lib.Architecture.BuildingBlocks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Core.Cerberos.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<ChangeUserStatusRequest> ChangeUserStatusHandler;
private readonly IComponentHandler<AddCompanyToUserRequest> addCompanyToUserHandler;
private readonly IComponentHandler<RemoveCompanyFromUserRequest> removeCompanyFromUserHandler;
private readonly IComponentHandler<AddProjectToUserRequest> addProjectToUserHandler;
private readonly IComponentHandler<RemoveProjectFromUserRequest> removeProjectFromUserHandler;
private readonly IComponentHandler<LoginUserRequest> loginUserHandler;
private readonly IComponentHandler<LogoutUserRequest> logoutUserHandler;
private readonly IComponentHandler<ValidateUserExistenceRequest> validateUserHandler;
private readonly IComponentHandler<GetTokenAdapterRequest> getTokenAdapterHandler;
private readonly IComponentHandler<GetConsentFormPDFRequest> getConsentFormPDFHandler;
private readonly IComponentHandler<AcceptUserConsentFormRequest> acceptUserConsentFormHandler;
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<ChangeUserStatusRequest> changeUserStatusHandler,
IComponentHandler<AddCompanyToUserRequest> addCompanyToUserHandler,
IComponentHandler<RemoveCompanyFromUserRequest> removeCompanyFromUserHandler,
IComponentHandler<AddProjectToUserRequest> addProjectToUserHandler,
IComponentHandler<RemoveProjectFromUserRequest> removeProjectFromUserHandler,
IComponentHandler<LoginUserRequest> loginUserHandler,
IComponentHandler<LogoutUserRequest> logoutUserHandler,
IComponentHandler<ValidateUserExistenceRequest> validateUserHandler,
IComponentHandler<GetTokenAdapterRequest> getTokenAdapterHandler,
IComponentHandler<GetConsentFormPDFRequest> getConsentFormPDFHandler,
IComponentHandler<AcceptUserConsentFormRequest> acceptUserConsentFormHandler,
IUserPort port
)
{
this.createUserHandler = createUserHandler;
this.updateUserHandler = updateUserHandler;
this.ChangeUserStatusHandler = changeUserStatusHandler;
this.getAllUsersHandler = getAllUsersHandler;
this.getUserHandler = getUserHandler;
this.getUserByEmailHandler = getUserByEmailHandler;
this.addCompanyToUserHandler = addCompanyToUserHandler;
this.removeCompanyFromUserHandler = removeCompanyFromUserHandler;
this.addProjectToUserHandler = addProjectToUserHandler;
this.removeProjectFromUserHandler = removeProjectFromUserHandler;
this.loginUserHandler = loginUserHandler;
this.logoutUserHandler = logoutUserHandler;
this.validateUserHandler = validateUserHandler;
this.getTokenAdapterHandler = getTokenAdapterHandler;
this.getConsentFormPDFHandler = getConsentFormPDFHandler;
this.acceptUserConsentFormHandler = acceptUserConsentFormHandler;
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.HeathScheme)]
[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 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.HeathScheme)]
[Permission("UserManagement.Read")]
public async Task<IActionResult> GetUserById([FromBody] GetUserRequest request, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(request.Id)) { return BadRequest("Invalid user 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.HeathScheme}, {Schemes.AzureScheme}")]
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.HeathScheme)]
[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 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.HeathScheme)]
[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>
/// 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.HeathScheme}, {Schemes.AzureScheme}")]
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.HeathScheme)]
[Permission("UserManagement.Write")]
public async Task<IActionResult> ChangeUserStatusAsync([FromBody] ChangeUserStatusRequest request, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(request.Id)) { return BadRequest("Invalid user identifier"); }
await ChangeUserStatusHandler.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
return port.ViewModel;
}
/// <summary>
/// Adds a company to the user's list of companies.
/// </summary>
[HttpPost]
[Route("AddCompany")]
[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.HeathScheme)]
[Permission("UserManagement.Write")]
public async Task<IActionResult> AddCompanyToUserAsync([FromBody] AddCompanyToUserRequest request,
CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(request.UserId)) { return BadRequest("Invalid user identifier"); }
if (string.IsNullOrEmpty(request.CompanyId)) { return BadRequest("Invalid company identifier"); }
await addCompanyToUserHandler.ExecuteAsync(request, cancellationToken);
return port.ViewModel;
}
/// <summary>
/// Removes a company from the user's list of companies.
/// </summary>
[HttpDelete]
[Route("RemoveCompany")]
[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.HeathScheme)]
[Permission("UserManagement.Write")]
public async Task<IActionResult> RemoveCompanyFromUserAsync([FromBody] RemoveCompanyFromUserRequest request,
CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(request.UserId)) { return BadRequest("Invalid user identifier"); }
if (string.IsNullOrEmpty(request.CompanyId)) { return BadRequest("Invalid company identifier"); }
await removeCompanyFromUserHandler.ExecuteAsync(request, cancellationToken);
return port.ViewModel;
}
/// <summary>
/// Adds a project to the user's list of projects.
/// </summary>
[HttpPost]
[Route("AddProject")]
[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.HeathScheme)]
[Permission("UserManagement.Write")]
public async Task<IActionResult> AddProjectToUserAsync([FromBody] AddProjectToUserRequest request,
CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(request.UserId)) { return BadRequest("Invalid user identifier"); }
if (string.IsNullOrEmpty(request.ProjectId)) { return BadRequest("Invalid project identifier"); }
await addProjectToUserHandler.ExecuteAsync(request, cancellationToken);
return port.ViewModel;
}
/// <summary>
/// Removes a project from the user's list of projects.
/// </summary>
[HttpDelete]
[Route("RemoveProject")]
[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.HeathScheme)]
[Permission("UserManagement.Write")]
public async Task<IActionResult> RemoveProjectFromUserAsync([FromBody] RemoveProjectFromUserRequest request,
CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(request.UserId)) { return BadRequest("Invalid user identifier"); }
if (string.IsNullOrEmpty(request.ProjectId)) { return BadRequest("Invalid project identifier"); }
await removeProjectFromUserHandler.ExecuteAsync(request, cancellationToken);
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.HeathScheme}, {Schemes.AzureScheme}")]
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;
}
/// <summary>
/// Get Consent Form PDF.
/// </summary>
[HttpGet]
[Route("GetConsentFormPDF")]
[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.HeathScheme)]
[Permission("UserManagement.Read")]
public async Task<IActionResult> GetConsentFormPDFAsync(CancellationToken cancellationToken)
{
await getConsentFormPDFHandler.ExecuteAsync(new GetConsentFormPDFRequest { }, cancellationToken).ConfigureAwait(false);
return port.ViewModel;
}
/// <summary>
/// Accept user consent form.
/// </summary>
[HttpPatch("AcceptUserConsentForm")]
[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.HeathScheme}, {Schemes.AzureScheme}")]
public async Task<IActionResult> AcceptUserConsentFormAsync(CancellationToken cancellationToken)
{
await acceptUserConsentFormHandler.ExecuteAsync(new AcceptUserConsentFormRequest { }, cancellationToken).ConfigureAwait(false);
return port.ViewModel;
}
}
}