< Summary

Information
Class: AsiBackbone.AspNetCore.Endpoints.EndpointGovernanceOptions
Assembly: AsiBackbone.AspNetCore
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.AspNetCore/Endpoints/EndpointGovernanceOptions.cs
Line coverage
88%
Covered lines: 8
Uncovered lines: 1
Coverable lines: 9
Total lines: 116
Line coverage: 88.8%
Branch coverage
87%
Covered branches: 7
Total branches: 8
Branch coverage: 87.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Validate()50%2283.33%
ValidateStatusCode(...)100%66100%

File(s)

/home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.AspNetCore/Endpoints/EndpointGovernanceOptions.cs

#LineLine coverage
 1using Microsoft.AspNetCore.Http;
 2
 3namespace AsiBackbone.AspNetCore.Endpoints;
 4
 5/// <summary>
 6/// Provides options for ergonomic ASP.NET Core endpoint governance integration.
 7/// </summary>
 8public sealed class EndpointGovernanceOptions
 9{
 10    /// <summary>
 11    /// Gets or sets the policy version attached to generated endpoint governance evaluation contexts.
 12    /// </summary>
 13    public string? PolicyVersion { get; set; }
 14
 15    /// <summary>
 16    /// Gets or sets the policy hash attached to generated endpoint governance evaluation contexts.
 17    /// </summary>
 18    public string? PolicyHash { get; set; }
 19
 20    /// <summary>
 21    /// Gets or sets the endpoint metadata mode used for governance evaluation contexts, decision receipt, acknowledgmen
 22    /// </summary>
 23    /// <remarks>
 24    /// The default keeps complete endpoint metadata for traceability. High-throughput hosts may choose
 25    /// <see cref="EndpointGovernanceMetadataMode.Reduced" /> to forward only the endpoint operation name
 26    /// through the hot path after they have confirmed host policies do not require the omitted metadata values.
 27    /// </remarks>
 28    public EndpointGovernanceMetadataMode MetadataMode { get; set; } = EndpointGovernanceMetadataMode.Full;
 29
 30    /// <summary>
 31    /// Gets or sets a value indicating whether policy metadata should fail closed when no policy evaluator is configure
 32    /// </summary>
 33    public bool FailClosedWhenPolicyEvaluatorMissing { get; set; } = true;
 34
 35    /// <summary>
 36    /// Gets or sets a value indicating whether capability metadata should fail closed when no capability validator is c
 37    /// </summary>
 38    public bool FailClosedWhenCapabilityValidatorMissing { get; set; } = true;
 39
 40    /// <summary>
 41    /// Gets or sets a value indicating whether audit metadata should fail closed when no host-owned decision receipt si
 42    /// </summary>
 43    public bool FailClosedWhenAuditSinkMissing { get; set; } = true;
 44
 45    /// <summary>
 46    /// Gets or sets the HTTP status code used when endpoint governance is missing required host configuration.
 47    /// </summary>
 48    public int ConfigurationFailureStatusCode { get; set; } = StatusCodes.Status500InternalServerError;
 49
 50    /// <summary>
 51    /// Gets or sets the HTTP status code used when endpoint capability validation fails before policy evaluation return
 52    /// </summary>
 53    public int CapabilityFailureStatusCode { get; set; } = StatusCodes.Status403Forbidden;
 54
 55    /// <summary>
 56    /// Gets or sets the HTTP status code used when a governance decision requires acknowledgment and the endpoint reque
 57    /// </summary>
 58    public int AcknowledgmentChallengeStatusCode { get; set; } = StatusCodes.Status428PreconditionRequired;
 59
 60    /// <summary>
 61    /// Gets or sets a value indicating whether selected endpoints without AsiBackbone governance metadata should fail c
 62    /// </summary>
 63    public bool RequireGovernanceMetadata { get; set; }
 64
 65    /// <summary>
 66    /// Gets or sets a value indicating whether local-development ProblemDetails diagnostics should be emitted for endpo
 67    /// </summary>
 68    public bool EnableDevelopmentDiagnostics { get; set; }
 69
 70    /// <summary>
 71    /// Gets or sets the documentation base URL used when development diagnostics include a troubleshooting link.
 72    /// </summary>
 73    public string? DevelopmentDiagnosticsDocumentationBaseUrl { get; set; }
 74
 75    /// <summary>
 76    /// Gets a collection of metadata keys whose values should be redacted from development diagnostics.
 77    /// </summary>
 78    public ISet<string> DevelopmentDiagnosticsRedactedMetadataKeys { get; } = new HashSet<string>(StringComparer.Ordinal
 79
 80    /// <summary>
 81    /// Gets or sets a value indicating whether non-sensitive metadata values may be included in development diagnostics
 82    /// </summary>
 83    public bool IncludeDevelopmentDiagnosticsMetadataValues { get; set; } = true;
 84
 85    /// <summary>
 86    /// Gets or sets an optional factory for the generic 403 response used by middleware when no explicit failure result
 87    /// </summary>
 88    /// <remarks>
 89    /// Leave this unset for the low-allocation, bodyless default 403 response. Hosts that prefer richer API responses
 90    /// may provide a safe factory, such as a ProblemDetails result, while avoiding sensitive governance details.
 91    /// </remarks>
 92    public Func<HttpContext, IResult>? DefaultForbiddenResultFactory { get; set; }
 93
 94    /// <summary>
 95    /// Validates endpoint governance options.
 96    /// </summary>
 97    public void Validate()
 98    {
 5999        if (!Enum.IsDefined(MetadataMode))
 100        {
 0101            throw new InvalidOperationException($"{nameof(MetadataMode)} must be a defined endpoint governance metadata 
 102        }
 103
 59104        ValidateStatusCode(ConfigurationFailureStatusCode, nameof(ConfigurationFailureStatusCode));
 58105        ValidateStatusCode(CapabilityFailureStatusCode, nameof(CapabilityFailureStatusCode));
 57106        ValidateStatusCode(AcknowledgmentChallengeStatusCode, nameof(AcknowledgmentChallengeStatusCode));
 57107    }
 108
 109    private static void ValidateStatusCode(int statusCode, string propertyName)
 110    {
 174111        if (statusCode is < 100 or > 599)
 112        {
 2113            throw new InvalidOperationException($"{propertyName} must be a valid HTTP status code.");
 114        }
 172115    }
 116}