94 lines
4.5 KiB
C#
94 lines
4.5 KiB
C#
using System;
|
|
using System.Net.Http;
|
|
|
|
namespace StellaOps.AirGap.Policy;
|
|
|
|
/// <summary>
|
|
/// Provides helpers for creating <see cref="HttpClient"/> instances that respect the configured <see cref="IEgressPolicy"/>.
|
|
/// </summary>
|
|
public static class EgressHttpClientFactory
|
|
{
|
|
/// <summary>
|
|
/// Creates an <see cref="HttpClient"/> after validating the supplied egress request against the policy.
|
|
/// </summary>
|
|
/// <param name="egressPolicy">The policy used to validate outbound requests.</param>
|
|
/// <param name="request">Describes the destination and intent for the outbound call.</param>
|
|
/// <param name="configure">Optional configuration hook applied to the newly created client.</param>
|
|
/// <returns>An <see cref="HttpClient"/> that has been pre-authorised by the policy.</returns>
|
|
public static HttpClient Create(IEgressPolicy egressPolicy, EgressRequest request, Action<HttpClient>? configure = null)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(egressPolicy);
|
|
|
|
egressPolicy.EnsureAllowed(request);
|
|
|
|
var client = new HttpClient();
|
|
configure?.Invoke(client);
|
|
return client;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates an <see cref="HttpClient"/> from a caller-provided factory after validating the supplied egress request.
|
|
/// </summary>
|
|
/// <param name="egressPolicy">The policy used to validate outbound requests.</param>
|
|
/// <param name="request">Describes the destination and intent for the outbound call.</param>
|
|
/// <param name="clientFactory">Factory used to supply a configured client (for example, from IHttpClientFactory).</param>
|
|
/// <param name="configure">Optional configuration hook applied to the newly created client.</param>
|
|
/// <returns>An <see cref="HttpClient"/> that has been pre-authorised by the policy.</returns>
|
|
public static HttpClient Create(
|
|
IEgressPolicy egressPolicy,
|
|
EgressRequest request,
|
|
Func<HttpClient> clientFactory,
|
|
Action<HttpClient>? configure = null)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(egressPolicy);
|
|
ArgumentNullException.ThrowIfNull(clientFactory);
|
|
|
|
egressPolicy.EnsureAllowed(request);
|
|
|
|
var client = clientFactory();
|
|
if (client is null)
|
|
{
|
|
throw new InvalidOperationException("EgressHttpClientFactory received a null HttpClient from the factory.");
|
|
}
|
|
|
|
configure?.Invoke(client);
|
|
return client;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates and configures an <see cref="HttpClient"/> after validating the supplied egress request against the policy.
|
|
/// </summary>
|
|
/// <param name="egressPolicy">The policy used to validate outbound requests.</param>
|
|
/// <param name="component">Component initiating the request.</param>
|
|
/// <param name="destination">Destination that will be contacted.</param>
|
|
/// <param name="intent">Intent label describing why the request is needed.</param>
|
|
/// <param name="configure">Optional configuration hook applied to the newly created client.</param>
|
|
/// <returns>An <see cref="HttpClient"/> that has been pre-authorised by the policy.</returns>
|
|
public static HttpClient Create(
|
|
IEgressPolicy egressPolicy,
|
|
string component,
|
|
Uri destination,
|
|
string intent,
|
|
Action<HttpClient>? configure = null)
|
|
=> Create(egressPolicy, new EgressRequest(component, destination, intent), configure);
|
|
|
|
/// <summary>
|
|
/// Creates a configured <see cref="HttpClient"/> using a caller-provided factory after policy validation.
|
|
/// </summary>
|
|
/// <param name="egressPolicy">The policy used to validate outbound requests.</param>
|
|
/// <param name="component">Component initiating the request.</param>
|
|
/// <param name="destination">Destination that will be contacted.</param>
|
|
/// <param name="intent">Intent label describing why the request is needed.</param>
|
|
/// <param name="clientFactory">Factory used to supply a configured client.</param>
|
|
/// <param name="configure">Optional configuration hook applied to the newly created client.</param>
|
|
/// <returns>An <see cref="HttpClient"/> that has been pre-authorised by the policy.</returns>
|
|
public static HttpClient Create(
|
|
IEgressPolicy egressPolicy,
|
|
string component,
|
|
Uri destination,
|
|
string intent,
|
|
Func<HttpClient> clientFactory,
|
|
Action<HttpClient>? configure = null)
|
|
=> Create(egressPolicy, new EgressRequest(component, destination, intent), clientFactory, configure);
|
|
}
|