< Summary

Information
Class: AsiBackbone.Core.Evaluation.AsiBackbonePolicyEvaluatorOptions
Assembly: AsiBackbone.Core
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Core/Evaluation/AsiBackbonePolicyEvaluatorOptions.cs
Line coverage
100%
Covered lines: 72
Uncovered lines: 0
Coverable lines: 72
Total lines: 231
Line coverage: 100%
Branch coverage
100%
Covered branches: 14
Total branches: 14
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Core/Evaluation/AsiBackbonePolicyEvaluatorOptions.cs

#LineLine coverage
 1namespace AsiBackbone.Core.Evaluation;
 2
 3/// <summary>
 4/// Provides host-configurable options for the default AsiBackbone policy evaluator.
 5/// </summary>
 6/// <remarks>
 7/// Options remain mutable while a host is configuring them. The default evaluator validates and freezes the supplied
 8/// instance during construction so later caller mutation cannot change evaluator behavior. Configure a separate options
 9/// instance for each evaluator posture that must differ.
 10/// </remarks>
 11public sealed class AsiBackbonePolicyEvaluatorOptions
 12{
 13    private const string DefaultNoConstraintsReasonMessage =
 14        "No policy constraints were registered or supplied for evaluation.";
 15
 16    private const string DefaultConstraintExceptionReasonMessage =
 17        "A policy constraint failed during evaluation. The operation was denied by the evaluator failure policy.";
 18
 19    private const string DefaultThreatContributorExceptionReasonMessage =
 20        "A threat model contributor failed during evaluation. The operation was denied by the evaluator failure policy."
 21    private bool isFrozen;
 22
 23    /// <summary>
 24    /// Gets the default machine-readable reason code used when strict empty-policy evaluation denies execution.
 25    /// </summary>
 26    public const string DefaultNoConstraintsReasonCode = "asibackbone.policy.no_constraints";
 27
 28    /// <summary>
 29    /// Gets the default machine-readable reason code used when constraint exception evaluation denies execution.
 30    /// </summary>
 31    public const string DefaultConstraintExceptionReasonCode = "asibackbone.policy.constraint_exception";
 32
 33    /// <summary>
 34    /// Gets the default machine-readable reason code used when threat contributor exception evaluation denies execution
 35    /// </summary>
 36    public const string DefaultThreatContributorExceptionReasonCode = "asibackbone.threat.contributor_exception";
 37
 38    /// <summary>
 39    /// Gets or sets a value indicating whether evaluation should deny when no constraints are registered or supplied.
 40    /// </summary>
 41    public bool DenyWhenNoConstraints
 42    {
 4743        get;
 44        set
 45        {
 3946            ThrowIfFrozen();
 3747            field = value;
 3748        }
 30949    } = true;
 50
 51    /// <summary>
 52    /// Gets or sets a value indicating whether evaluation should stop after the first denied constraint result.
 53    /// </summary>
 54    public bool ShortCircuitOnFirstDenial
 55    {
 72056        get;
 57        set
 58        {
 2259            ThrowIfFrozen();
 2260            field = value;
 2261        }
 62    }
 63
 64    /// <summary>
 65    /// Gets or sets a value indicating whether constraint exceptions should be converted into denied governance decisio
 66    /// </summary>
 67    public bool TreatConstraintExceptionAsDenial
 68    {
 4069        get;
 70        set
 71        {
 4772            ThrowIfFrozen();
 4773            field = value;
 4774        }
 30975    } = true;
 76
 77    /// <summary>
 78    /// Gets or sets a value indicating whether threat contributor exceptions should be converted into denied governance
 79    /// </summary>
 80    public bool TreatThreatContributorExceptionAsDenial
 81    {
 3282        get;
 83        set
 84        {
 4985            ThrowIfFrozen();
 4986            field = value;
 4987        }
 30988    } = true;
 89
 90    /// <summary>
 91    /// Gets or sets a value indicating whether threat assessment outcomes should be protected from being downgraded to 
 92    /// </summary>
 93    public bool PreventThreatAssessmentAllowDowngrade
 94    {
 5295        get;
 96        set
 97        {
 5198            ThrowIfFrozen();
 5199            field = value;
 51100        }
 309101    } = true;
 102
 103    /// <summary>
 104    /// Gets or sets the machine-readable reason code used when <see cref="DenyWhenNoConstraints" /> denies an empty pol
 105    /// </summary>
 106    public string NoConstraintsReasonCode
 107    {
 326108        get;
 109        set
 110        {
 10111            ThrowIfFrozen();
 10112            field = value;
 10113        }
 309114    } = DefaultNoConstraintsReasonCode;
 115
 116    /// <summary>
 117    /// Gets or sets the reason message used when <see cref="DenyWhenNoConstraints" /> denies an empty policy.
 118    /// </summary>
 119    public string NoConstraintsReasonMessage
 120    {
 318121        get;
 122        set
 123        {
 10124            ThrowIfFrozen();
 10125            field = value;
 10126        }
 309127    } = DefaultNoConstraintsReasonMessage;
 128
 129    /// <summary>
 130    /// Gets or sets the machine-readable reason code used when <see cref="TreatConstraintExceptionAsDenial" /> denies a
 131    /// </summary>
 132    public string ConstraintExceptionReasonCode
 133    {
 310134        get;
 135        set
 136        {
 10137            ThrowIfFrozen();
 10138            field = value;
 10139        }
 309140    } = DefaultConstraintExceptionReasonCode;
 141
 142    /// <summary>
 143    /// Gets or sets the reason message used when <see cref="TreatConstraintExceptionAsDenial" /> denies a constraint ex
 144    /// </summary>
 145    public string ConstraintExceptionReasonMessage
 146    {
 302147        get;
 148        set
 149        {
 10150            ThrowIfFrozen();
 10151            field = value;
 10152        }
 309153    } = DefaultConstraintExceptionReasonMessage;
 154
 155    /// <summary>
 156    /// Gets or sets the machine-readable reason code used when <see cref="TreatThreatContributorExceptionAsDenial" /> d
 157    /// </summary>
 158    public string ThreatContributorExceptionReasonCode
 159    {
 289160        get;
 161        set
 162        {
 2163            ThrowIfFrozen();
 2164            field = value;
 2165        }
 309166    } = DefaultThreatContributorExceptionReasonCode;
 167
 168    /// <summary>
 169    /// Gets or sets the reason message used when <see cref="TreatThreatContributorExceptionAsDenial" /> denies a contri
 170    /// </summary>
 171    public string ThreatContributorExceptionReasonMessage
 172    {
 287173        get;
 174        set
 175        {
 2176            ThrowIfFrozen();
 2177            field = value;
 2178        }
 309179    } = DefaultThreatContributorExceptionReasonMessage;
 180
 181    /// <summary>
 182    /// Validates evaluator options and freezes the instance for evaluator use.
 183    /// </summary>
 184    /// <remarks>
 185    /// The method is idempotent. After successful validation, attempts to change any option throw an
 186    /// <see cref="InvalidOperationException" /> so a constructed evaluator cannot observe configuration drift.
 187    /// </remarks>
 188    public void Validate()
 189    {
 311190        if (string.IsNullOrWhiteSpace(NoConstraintsReasonCode))
 191        {
 8192            throw new InvalidOperationException($"{nameof(NoConstraintsReasonCode)} must not be empty.");
 193        }
 194
 303195        if (string.IsNullOrWhiteSpace(NoConstraintsReasonMessage))
 196        {
 8197            throw new InvalidOperationException($"{nameof(NoConstraintsReasonMessage)} must not be empty.");
 198        }
 199
 295200        if (string.IsNullOrWhiteSpace(ConstraintExceptionReasonCode))
 201        {
 8202            throw new InvalidOperationException($"{nameof(ConstraintExceptionReasonCode)} must not be empty.");
 203        }
 204
 287205        if (string.IsNullOrWhiteSpace(ConstraintExceptionReasonMessage))
 206        {
 8207            throw new InvalidOperationException($"{nameof(ConstraintExceptionReasonMessage)} must not be empty.");
 208        }
 209
 279210        if (string.IsNullOrWhiteSpace(ThreatContributorExceptionReasonCode))
 211        {
 2212            throw new InvalidOperationException($"{nameof(ThreatContributorExceptionReasonCode)} must not be empty.");
 213        }
 214
 277215        if (string.IsNullOrWhiteSpace(ThreatContributorExceptionReasonMessage))
 216        {
 2217            throw new InvalidOperationException($"{nameof(ThreatContributorExceptionReasonMessage)} must not be empty.")
 218        }
 219
 275220        isFrozen = true;
 275221    }
 222
 223    private void ThrowIfFrozen()
 224    {
 252225        if (isFrozen)
 226        {
 2227            throw new InvalidOperationException(
 2228                "Evaluator options cannot be changed after they have been validated for evaluator construction.");
 229        }
 250230    }
 231}