using Asp.Versioning; using Core.Cerberos.Adapters; using Core.Cerberos.Adapters.Common.Constants; using Core.Cerberos.Adapters.Contracts; using Core.Cerberos.Application.UseCases.Users.Input; using Core.Cerberos.External.Clients.Cerberos.Requests.Users; using LSA.Dashboard.External.Clients.Dashboard; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Core.Cerberos.BFF.Api.Controllers { /// /// Handles all requests for Authentication. /// [ApiVersion(MimeTypes.ApplicationVersion)] [Route("api/v{api-version:apiVersion}/[controller]")] [Produces(MimeTypes.ApplicationJson)] [Consumes(MimeTypes.ApplicationJson)] [ApiController] public class AuthenticationController(ICerberosServiceClient cerberosServiceClient, ILogger logger, ITokenService tokenService) : BaseController(logger) { /// /// Get token for user. /// /// A representing /// the asynchronous execution of the service. /// The Token was generated. /// The service internal error. [HttpGet] [Route(Routes.GenerateToken)] [ProducesResponseType(typeof(UserAdapter), StatusCodes.Status200OK)] [Authorize(AuthenticationSchemes = Schemes.AzureScheme)] public async Task GenerateTokenService(CancellationToken cancellationToken) { try { logger.LogInformation($"{nameof(GenerateTokenService)} - Request received - Payload: {null}"); var tokenAdapter = new TokenAdapter(); var email = tokenService.GetEmailClaim(this.HttpContext); if (string.IsNullOrEmpty(email)) return BadRequest("An error ocurred while desearializing the token"); var tokenResult = await Handle(() => cerberosServiceClient.GetTokenAdapterService(new GetTokenAdapterRequest { Email = email }, cancellationToken)).ConfigureAwait(false); if (tokenResult is ObjectResult tokenOkResult && tokenOkResult.StatusCode == 200) tokenAdapter = tokenOkResult.Value as TokenAdapter; else return tokenResult; if (tokenAdapter is not null && tokenAdapter.User is not null) { tokenAdapter.User.Token = tokenService.GenerateAccessToken(tokenAdapter); await Handle(() => cerberosServiceClient.LoginUserService(new LoginUserRequest { Email = email }, cancellationToken)).ConfigureAwait(false); return Ok(tokenAdapter.User); } else { return BadRequest("An error ocurred"); } } catch (Exception ex) { logger.LogError($"{nameof(GenerateTokenService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload : {null}"); throw; } } /// /// Refreshes the custom access token. /// /// A representing /// the asynchronous execution of the service. /// The user with it's new token. /// The service internal error. [HttpGet] [Route(Routes.RefreshToken)] [ProducesResponseType(typeof(UserAdapter), StatusCodes.Status200OK)] [Authorize(AuthenticationSchemes = Schemes.HeathScheme)] public async Task RefreshCustomTokenAsync(CancellationToken cancellationToken) { var tokenAdapter = new TokenAdapter(); var email = tokenService.GetEmailClaim(this.HttpContext); var tokenResult = await Handle(() => cerberosServiceClient.GetTokenAdapterService(new GetTokenAdapterRequest { Email = email }, cancellationToken)).ConfigureAwait(false); if (tokenResult is ObjectResult tokenOkResult && tokenOkResult.StatusCode == 200) { tokenAdapter = tokenOkResult.Value as TokenAdapter; if (tokenAdapter != null) { var result = tokenService.RefreshAccessToken(HttpContext, tokenAdapter); return result; } } else return tokenResult; return new UnauthorizedObjectResult("Error in refreshToken"); } } }