Files
Antifraude.Net/Antifraude.Net/ApiOPE/Controllers/OpeController.cs

130 lines
4.3 KiB
C#

using System.Text.Json;
using ApiOPE.Configuration;
using ApiOPE.Contracts;
using ApiOPE.Security;
using ApiOPE.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
namespace ApiOPE.Controllers;
[ApiController]
[Route("")]
public sealed class OpeController : ControllerBase
{
private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web);
private readonly OpeOptions _options;
private readonly ILogger<OpeController> _logger;
public OpeController(
IOptions<OpeOptions> options,
ILogger<OpeController> logger)
{
_options = options.Value;
_logger = logger;
}
[HttpGet("versions/current")]
[OpeAuthenticated("/versions/current", versionOptional: true)]
[Produces(OpeMediaTypes.Version)]
public IActionResult GetCurrentVersion()
=> Json(new OpeVersionResponse(_options.Version), OpeMediaTypes.Version);
[HttpGet]
[OpeAuthenticated("/")]
[Produces(OpeMediaTypes.Bookmarks)]
public IActionResult GetBookmarks()
{
var genericOperationUrl = $"{_options.PublicBaseUrl.TrimEnd('/')}/genericoperations";
return Json(
new Dictionary<string, string>(StringComparer.Ordinal)
{
["generic-operation"] = genericOperationUrl
},
OpeMediaTypes.Bookmarks);
}
[HttpPost("genericoperations")]
[OpeAuthenticated("/genericoperations")]
[RequestSizeLimit(64 * 1024)]
[Produces(OpeMediaTypes.GenericOperationResponse)]
[ProducesResponseType(typeof(OpeErrorResponse), StatusCodes.Status412PreconditionFailed)]
public async Task<IActionResult> ExecuteGenericOperation(CancellationToken cancellationToken)
{
var requestContext = OpeRequestContextStore.Get(HttpContext)
?? throw new InvalidOperationException("No existe contexto de autenticacion OPE.");
var parsedRequest = await GenericOperationRequestReader.ReadAsync(Request, cancellationToken);
if (!parsedRequest.IsValid)
{
return Error(
"Existen errores en los campos",
OpeErrorCauses.FieldErrors,
parsedRequest.Errors);
}
var identifier = parsedRequest.Request!.Data["FIELD_0"].Value;
if (!DenunciaLookupParser.TryParse(identifier, out var lookup) || lookup is null)
{
return Error(
"Existen errores en los campos",
OpeErrorCauses.FieldErrors,
new Dictionary<string, string>(StringComparer.Ordinal)
{
["FIELD_0"] = OpeFieldErrors.UnexpectedFormat
});
}
// Respuesta temporal de pruebas: no consulta la API interna ni exige
// que el expediente exista. FIELD_0 conserva exactamente el valor
// recibido y el resto de campos devuelve un valor ficticio.
_logger.LogInformation(
"Respuesta OPE de prueba para el expediente solicitado {Expediente}. TransactionId={TransactionId}",
identifier,
requestContext.TransactionId);
var testData = new Dictionary<string, OpeFieldValue>(StringComparer.Ordinal)
{
["FIELD_0"] = new OpeFieldValue("STRING", identifier)
};
for (var index = 1; index < _options.OutputFields.Count; index++)
{
testData[$"FIELD_{index}"] = new OpeFieldValue("STRING", "dato de prueba");
}
return Json(new OpeDataEnvelope(testData), OpeMediaTypes.GenericOperationResponse);
}
private static ContentResult Error(
string message,
string cause,
IReadOnlyDictionary<string, string>? data)
{
var response = new OpeErrorResponse(
StatusCodes.Status412PreconditionFailed,
message,
new OpeTypedInfo(null, null, null, cause),
data);
return Json(
response,
OpeMediaTypes.Error,
StatusCodes.Status412PreconditionFailed);
}
private static ContentResult Json<T>(
T value,
string contentType,
int statusCode = StatusCodes.Status200OK)
{
return new ContentResult
{
Content = JsonSerializer.Serialize(value, JsonOptions),
ContentType = contentType,
StatusCode = statusCode
};
}
}