feat: Implement vulnerability token signing and verification utilities
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- Added VulnTokenSigner for signing JWT tokens with specified algorithms and keys. - Introduced VulnTokenUtilities for resolving tenant and subject claims, and sanitizing context dictionaries. - Created VulnTokenVerificationUtilities for parsing tokens, verifying signatures, and deserializing payloads. - Developed VulnWorkflowAntiForgeryTokenIssuer for issuing anti-forgery tokens with configurable options. - Implemented VulnWorkflowAntiForgeryTokenVerifier for verifying anti-forgery tokens and validating payloads. - Added AuthorityVulnerabilityExplorerOptions to manage configuration for vulnerability explorer features. - Included tests for FilesystemPackRunDispatcher to ensure proper job handling under egress policy restrictions.
This commit is contained in:
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -12,6 +13,7 @@ using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.Time.Testing;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using StellaOps.Auth.Client;
|
||||
using StellaOps.AirGap.Policy;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Auth.Client.Tests;
|
||||
@@ -73,6 +75,39 @@ public class ServiceCollectionExtensionsTests
|
||||
Assert.Contains(recordedHandlers, handler => handler.GetType().Name.Contains("PolicyHttpMessageHandler", StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EnsureEgressAllowed_InvokesPolicyWhenAuthorityProvided()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var recordingPolicy = new RecordingPolicy();
|
||||
services.AddSingleton<IEgressPolicy>(recordingPolicy);
|
||||
|
||||
using var provider = services.BuildServiceProvider();
|
||||
|
||||
var options = new StellaOpsAuthClientOptions
|
||||
{
|
||||
Authority = "https://authority.test",
|
||||
DiscoveryCacheLifetime = TimeSpan.FromMinutes(1),
|
||||
JwksCacheLifetime = TimeSpan.FromMinutes(1),
|
||||
AllowOfflineCacheFallback = false,
|
||||
};
|
||||
|
||||
options.Validate();
|
||||
|
||||
var method = typeof(ServiceCollectionExtensions)
|
||||
.GetMethod("EnsureEgressAllowed", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
|
||||
Assert.NotNull(method);
|
||||
|
||||
method!.Invoke(null, new object?[] { provider, options, "authority-discovery" });
|
||||
|
||||
Assert.Single(recordingPolicy.Requests);
|
||||
var request = recordingPolicy.Requests[0];
|
||||
Assert.Equal("StellaOpsAuthClient", request.Component);
|
||||
Assert.Equal(new Uri("https://authority.test"), request.Destination);
|
||||
Assert.Equal("authority-discovery", request.Intent);
|
||||
}
|
||||
|
||||
private static HttpResponseMessage CreateResponse(HttpStatusCode statusCode, string jsonContent)
|
||||
{
|
||||
return new HttpResponseMessage(statusCode)
|
||||
@@ -224,6 +259,37 @@ public class ServiceCollectionExtensionsTests
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class RecordingPolicy : IEgressPolicy
|
||||
{
|
||||
private readonly List<EgressRequest> requests = new();
|
||||
|
||||
public bool IsSealed => true;
|
||||
|
||||
public EgressPolicyMode Mode => EgressPolicyMode.Sealed;
|
||||
|
||||
public IReadOnlyList<EgressRequest> Requests => requests;
|
||||
|
||||
public EgressDecision Evaluate(EgressRequest request)
|
||||
{
|
||||
requests.Add(request);
|
||||
return EgressDecision.Allowed;
|
||||
}
|
||||
|
||||
public ValueTask<EgressDecision> EvaluateAsync(EgressRequest request, CancellationToken cancellationToken = default)
|
||||
=> new(Evaluate(request));
|
||||
|
||||
public void EnsureAllowed(EgressRequest request)
|
||||
{
|
||||
requests.Add(request);
|
||||
}
|
||||
|
||||
public ValueTask EnsureAllowedAsync(EgressRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
EnsureAllowed(request);
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class ThrowingTokenClient : IStellaOpsTokenClient
|
||||
{
|
||||
public int RequestCount { get; private set; }
|
||||
@@ -278,11 +344,11 @@ public class ServiceCollectionExtensionsTests
|
||||
null,
|
||||
"{}");
|
||||
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
public Task<StellaOpsTokenResult> RequestPasswordTokenAsync(string username, string password, string? scope = null, IReadOnlyDictionary<string, string>? additionalParameters = null, CancellationToken cancellationToken = default)
|
||||
=> throw new NotImplementedException();
|
||||
public Task<StellaOpsTokenResult> RequestPasswordTokenAsync(string username, string password, string? scope = null, IReadOnlyDictionary<string, string>? additionalParameters = null, CancellationToken cancellationToken = default)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public Task<JsonWebKeySet> GetJsonWebKeySetAsync(CancellationToken cancellationToken = default)
|
||||
=> Task.FromResult(new JsonWebKeySet());
|
||||
|
||||
Reference in New Issue
Block a user