cambiado requisito de cabeceras en todas las llamadas y simualcion de datos en la 3 llamada para pruebas
This commit is contained in:
@@ -15,19 +15,13 @@ public sealed class OpeController : ControllerBase
|
||||
private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web);
|
||||
|
||||
private readonly OpeOptions _options;
|
||||
private readonly InternalDenunciasClient _internalApi;
|
||||
private readonly OpeFieldMapper _fieldMapper;
|
||||
private readonly ILogger<OpeController> _logger;
|
||||
|
||||
public OpeController(
|
||||
IOptions<OpeOptions> options,
|
||||
InternalDenunciasClient internalApi,
|
||||
OpeFieldMapper fieldMapper,
|
||||
ILogger<OpeController> logger)
|
||||
{
|
||||
_options = options.Value;
|
||||
_internalApi = internalApi;
|
||||
_fieldMapper = fieldMapper;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@@ -82,54 +76,25 @@ public sealed class OpeController : ControllerBase
|
||||
});
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var result = await _internalApi.GetFieldsAsync(
|
||||
lookup,
|
||||
requestContext.TransactionId,
|
||||
cancellationToken);
|
||||
// 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);
|
||||
|
||||
if (result.Status == InternalLookupStatus.NotFound || result.Fields is null)
|
||||
var testData = new Dictionary<string, OpeFieldValue>(StringComparer.Ordinal)
|
||||
{
|
||||
return Error(
|
||||
"No se ha encontrado la denuncia o expediente solicitado",
|
||||
OpeErrorCauses.ElementNotExists,
|
||||
null);
|
||||
["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(_fieldMapper.Map(result.Fields), OpeMediaTypes.GenericOperationResponse);
|
||||
}
|
||||
catch (OperationCanceledException) when (!HttpContext.RequestAborted.IsCancellationRequested)
|
||||
{
|
||||
_logger.LogWarning(
|
||||
"Timeout consultando ApiDenuncias para una OPE. TransactionId={TransactionId}",
|
||||
requestContext.TransactionId);
|
||||
return Error("Error en el conector", OpeErrorCauses.ConnectorError, null);
|
||||
}
|
||||
catch (HttpRequestException exception)
|
||||
{
|
||||
_logger.LogWarning(
|
||||
exception,
|
||||
"No se ha podido conectar con ApiDenuncias. TransactionId={TransactionId}",
|
||||
requestContext.TransactionId);
|
||||
return Error("Error en el conector", OpeErrorCauses.ConnectorError, null);
|
||||
}
|
||||
catch (InternalApiException exception)
|
||||
{
|
||||
_logger.LogWarning(
|
||||
exception,
|
||||
"ApiDenuncias ha devuelto una respuesta no utilizable. TransactionId={TransactionId}",
|
||||
requestContext.TransactionId);
|
||||
return Error("Error en el conector", OpeErrorCauses.ConnectorError, null);
|
||||
}
|
||||
catch (InvalidDataException exception)
|
||||
{
|
||||
_logger.LogError(
|
||||
exception,
|
||||
"El contrato entre ApiOPE y ApiDenuncias no coincide. TransactionId={TransactionId}",
|
||||
requestContext.TransactionId);
|
||||
return Error("Error en el conector", OpeErrorCauses.ConnectorError, null);
|
||||
}
|
||||
return Json(new OpeDataEnvelope(testData), OpeMediaTypes.GenericOperationResponse);
|
||||
}
|
||||
|
||||
private static ContentResult Error(
|
||||
|
||||
@@ -2,7 +2,6 @@ using System.Security.Claims;
|
||||
using ApiOPE.Configuration;
|
||||
using ApiOPE.Contracts;
|
||||
using ApiOPE.Services;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
@@ -31,8 +30,7 @@ public sealed class OpeAuthenticationMiddleware
|
||||
HttpContext context,
|
||||
OpeTokenValidator tokenValidator,
|
||||
OpeResponseSigner responseSigner,
|
||||
OpeRequestFileLogger requestFileLogger,
|
||||
IOptions<OpeOptions> options)
|
||||
OpeRequestFileLogger requestFileLogger)
|
||||
{
|
||||
var authentication = context.GetEndpoint()?.Metadata.GetMetadata<OpeAuthenticatedAttribute>();
|
||||
if (authentication is null)
|
||||
@@ -54,12 +52,6 @@ public sealed class OpeAuthenticationMiddleware
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ValidateOrganizationHeaders(context.Request.Headers, options.Value, out var organizationFailure))
|
||||
{
|
||||
await RejectAsync(context, organizationFailure, requestFileLogger, token, validation.RequestContext);
|
||||
return;
|
||||
}
|
||||
|
||||
OpeRequestContextStore.Set(context, validation.RequestContext);
|
||||
context.User = new ClaimsPrincipal(new ClaimsIdentity(
|
||||
[
|
||||
@@ -92,6 +84,13 @@ public sealed class OpeAuthenticationMiddleware
|
||||
validation.RequestContext.TransactionId.ToString(),
|
||||
context.TraceIdentifier,
|
||||
Fingerprint(validation.RequestContext.ClientToken),
|
||||
context.Connection.RemoteIpAddress?.ToString(),
|
||||
ReadHeader(context.Request.Headers, OrganizationIdHeaderName),
|
||||
ReadHeader(context.Request.Headers, OrganizationDir3HeaderName),
|
||||
ReadHeader(context.Request.Headers, OrganizationCifHeaderName),
|
||||
ReadHeader(context.Request.Headers, "Content-Type"),
|
||||
ReadHeader(context.Request.Headers, "Accept"),
|
||||
ReadHeader(context.Request.Headers, "User-Agent"),
|
||||
null));
|
||||
}
|
||||
}
|
||||
@@ -118,6 +117,13 @@ public sealed class OpeAuthenticationMiddleware
|
||||
requestContext?.TransactionId.ToString(),
|
||||
context.TraceIdentifier,
|
||||
string.IsNullOrWhiteSpace(token) ? null : Fingerprint(token),
|
||||
context.Connection.RemoteIpAddress?.ToString(),
|
||||
ReadHeader(context.Request.Headers, OrganizationIdHeaderName),
|
||||
ReadHeader(context.Request.Headers, OrganizationDir3HeaderName),
|
||||
ReadHeader(context.Request.Headers, OrganizationCifHeaderName),
|
||||
ReadHeader(context.Request.Headers, "Content-Type"),
|
||||
ReadHeader(context.Request.Headers, "Accept"),
|
||||
ReadHeader(context.Request.Headers, "User-Agent"),
|
||||
reason));
|
||||
|
||||
await OpeResponseWriter.WriteErrorAsync(
|
||||
@@ -132,26 +138,10 @@ public sealed class OpeAuthenticationMiddleware
|
||||
private static string Fingerprint(string value)
|
||||
=> Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(value)))[..12];
|
||||
|
||||
private static bool ValidateOrganizationHeaders(
|
||||
IHeaderDictionary headers,
|
||||
OpeOptions options,
|
||||
out string failureReason)
|
||||
{
|
||||
var valid = MatchesHeader(headers, OrganizationIdHeaderName, options.OrganizationId) &&
|
||||
MatchesHeader(headers, OrganizationDir3HeaderName, options.OrganizationDir3) &&
|
||||
MatchesHeader(headers, OrganizationCifHeaderName, options.OrganizationCif);
|
||||
|
||||
failureReason = valid
|
||||
? string.Empty
|
||||
: "Las cabeceras de organizacion no corresponden al conector configurado.";
|
||||
return valid;
|
||||
}
|
||||
|
||||
private static bool MatchesHeader(IHeaderDictionary headers, string name, string expected)
|
||||
{
|
||||
return TryGetSingleHeader(headers, name, out var value) &&
|
||||
string.Equals(value, expected, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
private static string? ReadHeader(IHeaderDictionary headers, string name)
|
||||
=> headers.TryGetValue(name, out var values) && values.Count > 0
|
||||
? string.Join(",", values.ToArray()).Trim()
|
||||
: null;
|
||||
|
||||
private static bool TryGetSingleHeader(
|
||||
IHeaderDictionary headers,
|
||||
|
||||
@@ -59,6 +59,13 @@ public sealed record OpeRequestLogEntry(
|
||||
string? TransactionId,
|
||||
string? RequestId,
|
||||
string? ClientTokenFingerprint,
|
||||
string? RemoteIp,
|
||||
string? OrganizationId,
|
||||
string? OrganizationDir3,
|
||||
string? OrganizationCif,
|
||||
string? ContentType,
|
||||
string? Accept,
|
||||
string? UserAgent,
|
||||
string? FailureReason)
|
||||
{
|
||||
public string ToDisplayLine()
|
||||
@@ -69,8 +76,20 @@ public sealed record OpeRequestLogEntry(
|
||||
Path,
|
||||
$"HTTP {StatusCode}",
|
||||
Result,
|
||||
$"ip={Clean(RemoteIp)}",
|
||||
$"orgId={Clean(OrganizationId)}",
|
||||
$"dir3={Clean(OrganizationDir3)}",
|
||||
$"cif={Clean(OrganizationCif)}",
|
||||
$"contentType={Clean(ContentType)}",
|
||||
$"accept={Clean(Accept)}",
|
||||
$"userAgent={Clean(UserAgent)}",
|
||||
$"transaccion={TransactionId ?? "-"}",
|
||||
$"peticion={RequestId ?? "-"}",
|
||||
$"cliente={ClientTokenFingerprint ?? "-"}",
|
||||
$"motivo={FailureReason ?? "-"}");
|
||||
$"motivo={Clean(FailureReason)}");
|
||||
|
||||
private static string Clean(string? value)
|
||||
=> string.IsNullOrWhiteSpace(value)
|
||||
? "-"
|
||||
: value.Replace("\r", " ").Replace("\n", " ").Trim();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user