Compare commits
12 Commits
165152b7cf
...
f9a73fbe0c
| Author | SHA1 | Date | |
|---|---|---|---|
| f9a73fbe0c | |||
| 282ce3a0b7 | |||
| 26f2da1313 | |||
| bc700e2cd2 | |||
| ea5389df85 | |||
| 87e1bb9187 | |||
| 68cc919bad | |||
| 374365d250 | |||
| 8c79b3a156 | |||
| 0583d07f26 | |||
| fd7744e94e | |||
| a5aac1d0ec |
6
src/ReC.Application/Common/Constants/Http.cs
Normal file
6
src/ReC.Application/Common/Constants/Http.cs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
namespace ReC.Application.Common.Constants;
|
||||||
|
|
||||||
|
public static class Http
|
||||||
|
{
|
||||||
|
public static readonly string ClientName = "HttpClient-" + Guid.NewGuid().ToString();
|
||||||
|
}
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
using MediatR;
|
using FluentValidation;
|
||||||
|
using MediatR;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using ReC.Application.Common.Behaviors;
|
using ReC.Application.Common.Behaviors;
|
||||||
|
using ReC.Application.Common.Constants;
|
||||||
using ReC.Application.Common.Options;
|
using ReC.Application.Common.Options;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using FluentValidation;
|
|
||||||
|
|
||||||
namespace ReC.Application;
|
namespace ReC.Application;
|
||||||
|
|
||||||
@@ -35,7 +36,11 @@ public static class DependencyInjection
|
|||||||
cfg.LicenseKey = configOpt.LuckyPennySoftwareLicenseKey;
|
cfg.LicenseKey = configOpt.LuckyPennySoftwareLicenseKey;
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddHttpClient();
|
services.AddHttpClient(Http.ClientName)
|
||||||
|
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
|
||||||
|
{
|
||||||
|
UseDefaultCredentials = false
|
||||||
|
});
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
using MediatR;
|
using MediatR;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using ReC.Application.Common;
|
using ReC.Application.Common;
|
||||||
|
using ReC.Application.Common.Constants;
|
||||||
using ReC.Application.Common.Dto;
|
using ReC.Application.Common.Dto;
|
||||||
using ReC.Application.Common.Exceptions;
|
using ReC.Application.Common.Exceptions;
|
||||||
using ReC.Application.OutResults.Commands;
|
using ReC.Application.OutResults.Commands;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace ReC.Application.RecActions.Commands;
|
namespace ReC.Application.RecActions.Commands;
|
||||||
@@ -27,7 +31,8 @@ public class InvokeRecActionCommandHandler(
|
|||||||
public async Task<bool> Handle(InvokeRecActionCommand request, CancellationToken cancel)
|
public async Task<bool> Handle(InvokeRecActionCommand request, CancellationToken cancel)
|
||||||
{
|
{
|
||||||
var action = request.Action;
|
var action = request.Action;
|
||||||
using var http = clientFactory.CreateClient();
|
|
||||||
|
using var http = clientFactory.CreateClient(Http.ClientName);
|
||||||
|
|
||||||
if (action.RestType is null)
|
if (action.RestType is null)
|
||||||
throw new DataIntegrityException(
|
throw new DataIntegrityException(
|
||||||
@@ -50,6 +55,70 @@ public class InvokeRecActionCommandHandler(
|
|||||||
foreach (var header in action.Headers)
|
foreach (var header in action.Headers)
|
||||||
httpReq.Headers.Add(header.Key, header.Value);
|
httpReq.Headers.Add(header.Key, header.Value);
|
||||||
|
|
||||||
|
switch (action.EndpointAuthType)
|
||||||
|
{
|
||||||
|
case "No Auth":
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "API Key":
|
||||||
|
if (action.EndpointAuthApiKey is string apiKey && action.EndpointAuthApiValue is string apiValue)
|
||||||
|
{
|
||||||
|
if (action.EndpointAuthApiKeyAddTo == "Header")
|
||||||
|
{
|
||||||
|
httpReq.Headers.Add(apiKey, apiValue);
|
||||||
|
}
|
||||||
|
else // Defaults to Query String
|
||||||
|
{
|
||||||
|
var uriBuilder = new UriBuilder(httpReq.RequestUri!);
|
||||||
|
var query = System.Web.HttpUtility.ParseQueryString(uriBuilder.Query);
|
||||||
|
query[apiKey] = apiValue;
|
||||||
|
uriBuilder.Query = query.ToString();
|
||||||
|
httpReq.RequestUri = uriBuilder.Uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Bearer Token":
|
||||||
|
case "JWT Bearer":
|
||||||
|
case "OAuth 2.0": // OAuth 2.0 uses Bearer tokens for authenticated requests
|
||||||
|
if (action.EndpointAuthToken is string authToken)
|
||||||
|
httpReq.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Basic Auth":
|
||||||
|
if (action.EndpointAuthUsername is string authUsername && action.EndpointAuthPassword is string authPassword)
|
||||||
|
{
|
||||||
|
var basicAuth = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{authUsername}:{authPassword}"));
|
||||||
|
httpReq.Headers.Authorization = new AuthenticationHeaderValue("Basic", basicAuth);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "NTLM Auth":
|
||||||
|
if (!string.IsNullOrWhiteSpace(action.EndpointAuthUsername))
|
||||||
|
{
|
||||||
|
var credentials = new NetworkCredential(
|
||||||
|
action.EndpointAuthUsername,
|
||||||
|
action.EndpointAuthPassword,
|
||||||
|
action.EndpointAuthDomain);
|
||||||
|
var credentialCache = new CredentialCache { { httpReq.RequestUri!, "NTLM", credentials } };
|
||||||
|
httpReq.Options.Set(new HttpRequestOptionsKey<CredentialCache>("Credentials"), credentialCache);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Digest Auth":
|
||||||
|
case "OAuth 1.0":
|
||||||
|
case "AWS Signature":
|
||||||
|
// These authentication methods require more complex implementations,
|
||||||
|
// often involving multi-step handshakes or specialized libraries.
|
||||||
|
// They are left as placeholders for future implementation.
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException(
|
||||||
|
$"The authentication type '{action.EndpointAuthType}' is not supported yet. " +
|
||||||
|
$"ProfileId: {action.ProfileId}, " +
|
||||||
|
$"Id: {action.Id}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
using var response = await http.SendAsync(httpReq, cancel);
|
using var response = await http.SendAsync(httpReq, cancel);
|
||||||
var resBody = await response.Content.ReadAsStringAsync(cancel);
|
var resBody = await response.Content.ReadAsStringAsync(cancel);
|
||||||
var resHeaders = response.Headers.ToDictionary();
|
var resHeaders = response.Headers.ToDictionary();
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class ReadRecActionQueryHandler(IRepository<RecActionView> repo, IMapper
|
|||||||
if (request.Invoked is bool invoked)
|
if (request.Invoked is bool invoked)
|
||||||
query = invoked ? query.Where(act => act.Root!.OutRes != null) : query.Where(act => act.Root!.OutRes == null);
|
query = invoked ? query.Where(act => act.Root!.OutRes != null) : query.Where(act => act.Root!.OutRes == null);
|
||||||
|
|
||||||
var actions = await query.ToListAsync(cancel);
|
var actions = await query.Include(act => act.EndpointAuth).ToListAsync(cancel);
|
||||||
|
|
||||||
if (actions.Count == 0)
|
if (actions.Count == 0)
|
||||||
throw new NotFoundException($"No actions found for the profile {request.ProfileId}.");
|
throw new NotFoundException($"No actions found for the profile {request.ProfileId}.");
|
||||||
|
|||||||
7
src/ReC.Domain/Constants/ErrorAction.cs
Normal file
7
src/ReC.Domain/Constants/ErrorAction.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace ReC.Domain.Constants;
|
||||||
|
|
||||||
|
public enum ErrorAction
|
||||||
|
{
|
||||||
|
Stop = 0,
|
||||||
|
Continue = 1,
|
||||||
|
}
|
||||||
@@ -10,8 +10,6 @@ public class OutRes
|
|||||||
|
|
||||||
public short? Status { get; set; }
|
public short? Status { get; set; }
|
||||||
|
|
||||||
public string? Message { get; set; }
|
|
||||||
|
|
||||||
public string? Header { get; set; }
|
public string? Header { get; set; }
|
||||||
|
|
||||||
public string? Body { get; set; }
|
public string? Body { get; set; }
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
namespace ReC.Domain.Entities;
|
using ReC.Domain.Constants;
|
||||||
|
|
||||||
|
namespace ReC.Domain.Entities;
|
||||||
|
|
||||||
public class RecAction
|
public class RecAction
|
||||||
{
|
{
|
||||||
@@ -36,7 +38,7 @@ public class RecAction
|
|||||||
|
|
||||||
public string? PostprocessingQuery { get; set; }
|
public string? PostprocessingQuery { get; set; }
|
||||||
|
|
||||||
public string? ErrorAction { get; set; }
|
public ErrorAction? ErrorAction { get; set; }
|
||||||
|
|
||||||
public string? AddedWho { get; set; }
|
public string? AddedWho { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ public class RecActionView
|
|||||||
|
|
||||||
public long? EndpointAuthId { get; set; }
|
public long? EndpointAuthId { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey("EndpointAuthId")]
|
||||||
|
public EndpointAuth? EndpointAuth { get; set; }
|
||||||
|
|
||||||
public string? EndpointAuthType { get; set; }
|
public string? EndpointAuthType { get; set; }
|
||||||
|
|
||||||
public string? EndpointAuthApiKey { get; set; }
|
public string? EndpointAuthApiKey { get; set; }
|
||||||
|
|||||||
@@ -132,7 +132,6 @@ public class RecDbContext(DbContextOptions<RecDbContext> options) : DbContext(op
|
|||||||
|
|
||||||
b.Property(e => e.ActionId).HasColumnName("ACTION_ID");
|
b.Property(e => e.ActionId).HasColumnName("ACTION_ID");
|
||||||
b.Property(e => e.Status).HasColumnName("STATUS");
|
b.Property(e => e.Status).HasColumnName("STATUS");
|
||||||
b.Property(e => e.Message).HasColumnName("MESSAGE");
|
|
||||||
b.Property(e => e.Header).HasColumnName("RESULT_HEADER");
|
b.Property(e => e.Header).HasColumnName("RESULT_HEADER");
|
||||||
b.Property(e => e.Body).HasColumnName("RESULT_BODY");
|
b.Property(e => e.Body).HasColumnName("RESULT_BODY");
|
||||||
b.Property(e => e.AddedWho).HasColumnName("ADDED_WHO");
|
b.Property(e => e.AddedWho).HasColumnName("ADDED_WHO");
|
||||||
|
|||||||
Reference in New Issue
Block a user