using ApplicationLayer.Services.Applicants.Models; using ApplicationLayer.Services.AuthServices.Common; using ApplicationLayer.Services.AuthServices.LoginService; using ApplicationLayer.Services.AuthServices.RegisterService; using ApplicationLayer.Services.AuthServices.Requests; using ApplicationLayer.Services.Users; using ApplicationLayer.Services.Users.Models; using ApplicationLayer.Services.Users.Requests; using FluentValidation; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using SchengenVisaApi.Common; namespace SchengenVisaApi.Controllers; /// Controller for user-auth and registration [ApiController] [Route("users")] public class UsersController( IRegisterService registerService, ILoginService loginService, IUsersService usersService, IValidator registerApplicantRequestValidator, IValidator changeUserAuthDataRequestValidator, IValidator registerRequestValidator) : ControllerBase { /// Adds applicant with user account [HttpPost("register")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task Register(RegisterApplicantRequest request, CancellationToken cancellationToken) { await registerApplicantRequestValidator.ValidateAndThrowAsync(request, cancellationToken); await registerService.RegisterApplicant(request, cancellationToken); return Ok(); } /// Adds approving authority with user account /// Accessible only for admins [HttpPost("authorities")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [Authorize(policy: PolicyConstants.AdminPolicy)] public async Task RegisterAuthority(RegisterRequest request, CancellationToken cancellationToken) { await registerRequestValidator.ValidateAndThrowAsync(request, cancellationToken); await registerService.RegisterAuthority(request, cancellationToken); return Ok(); } /// Returns JWT-token for authentication [HttpGet("login")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] public async Task Login(string email, string password, CancellationToken cancellationToken) { var loginRequest = new LoginRequest { AuthData = new() { Email = email, Password = password } }; var result = await loginService.LoginAsync(loginRequest, cancellationToken); return Ok(result); } /// Returns list of authority accounts /// Accessible only for admins [HttpGet("authorities")] [ProducesResponseType>(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [Authorize(policy: PolicyConstants.AdminPolicy)] public async Task GetAuthorityAccounts(CancellationToken cancellationToken) { var result = await usersService.GetAuthoritiesAccountsAsync(cancellationToken); return Ok(result); } /// Changes authority's account authentication data /// Accessible only for admins [HttpPut("authorities")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [Authorize(policy: PolicyConstants.AdminPolicy)] public async Task ChangeAuthorityAuthData(ChangeUserAuthDataRequest request, CancellationToken cancellationToken) { await changeUserAuthDataRequestValidator.ValidateAndThrowAsync(request, cancellationToken); await usersService.ChangeAuthorityAuthDataAsync(request, cancellationToken); return Ok(); } /// Removes authority's account /// Accessible only for admins [HttpDelete("authorities/{authorityAccountId:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [Authorize(policy: PolicyConstants.AdminPolicy)] public async Task RemoveAuthorityAccount(Guid authorityAccountId, CancellationToken cancellationToken) { await usersService.RemoveAuthorityAccount(authorityAccountId, cancellationToken); return Ok(); } /// Returns applicant info [HttpGet("applicant")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [Authorize(policy: PolicyConstants.ApplicantPolicy)] public async Task GetApplicant(CancellationToken cancellationToken) { var result = await usersService.GetAuthenticatedApplicant(cancellationToken); return Ok(result); } }