< Summary - Heimdall API

Information
Class: ArturRios.Heimdall.WebApi.Security.PersonTokenAudiences
Assembly: ArturRios.Heimdall.WebApi
File(s): /home/runner/work/heimdall-api/heimdall-api/src/Presentation/ArturRios.Heimdall.WebApi/Security/PersonTokenAudiences.cs
Line coverage
100%
Covered lines: 4
Uncovered lines: 0
Coverable lines: 4
Total lines: 56
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage
100%
Covered methods: 4
Fully covered methods: 4
Total methods: 4
Method coverage: 100%
Full method coverage: 100%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Person()100%11100%
get_TwoFactorChallenge()100%11100%
get_SubjectRights()100%11100%
From(...)100%11100%

File(s)

/home/runner/work/heimdall-api/heimdall-api/src/Presentation/ArturRios.Heimdall.WebApi/Security/PersonTokenAudiences.cs

#LineLine coverage
 1using ArturRios.Jwt;
 2
 3namespace ArturRios.Heimdall.WebApi.Security;
 4
 5/// <summary>
 6///     The audiences of the three tokens Heimdall issues to a person: the full token's, configured as
 7///     <c>HEIMDALL_AUTH_TOKEN_AUDIENCE</c>, and the two derived from it for the tokens that are not a
 8///     sign-in — the UC-38 challenge token (NFR-17) and the subject-rights-only token (NFR-24).
 9/// </summary>
 10/// <remarks>
 11///     <para>
 12///         <b>Why the audiences differ.</b> All three are signed with the same keys under the same
 13///         issuer. What makes a challenge token or a subject-rights-only token less than a sign-in is a
 14///         claim only Heimdall reads (<c>mfaPending</c>, <c>subjectRightsOnly</c>). A consumer that
 15///         validates the signature, issuer, audience and lifetime would take either for a full token
 16///         if they shared its audience: a password alone would get past the second factor there, and a
 17///         restricted identity would act as an unrestricted one (Threat Model TH-06, TH-35). A distinct
 18///         audience makes a consumer that pins the person audience refuse both, by construction and
 19///         with no knowledge of Heimdall's claims, as it refuses application tokens.
 20///     </para>
 21///     <para>
 22///         <b>Why derived rather than configured.</b> Unlike <see cref="ApplicationTokenOptions" />, no
 23///         variable is read: a suffix on the person audience is distinct from it and from the other
 24///         suffix whatever the person audience is, so the three person audiences can never be set
 25///         equal, and there is nothing new to set. The application audience is configured, though,
 26///         and could be; <see cref="ApplicationTokenOptions.Parse" /> refuses it equal to either
 27///         derived audience at start-up. The suffixes are fixed so a consumer can name the audiences
 28///         too.
 29///     </para>
 30///     <para>
 31///         <b>Inside Heimdall.</b> <see cref="PersonTokenValidator" /> admits a bearer token only
 32///         under the configured issuer and one of these three audiences (<see cref="TokenOrigin" />),
 33///         and <see cref="IdentityUserMapper" /> holds each audience to its claim: a token is mapped
 34///         only when its audience and its <c>mfaPending</c> and <c>subjectRightsOnly</c> claims agree.
 35///     </para>
 36/// </remarks>
 37/// <param name="Person">
 38///     The audience of a full token, <c>HEIMDALL_AUTH_TOKEN_AUDIENCE</c> exactly as configured.
 39/// </param>
 1360840public sealed record PersonTokenAudiences(string Person)
 41{
 42    /// <summary>The suffix that turns the person audience into the challenge token's.</summary>
 43    public const string TwoFactorChallengeSuffix = ".2fa-challenge";
 44
 45    /// <summary>The suffix that turns the person audience into the subject-rights-only token's.</summary>
 46    public const string SubjectRightsSuffix = ".subject-rights";
 47
 48    /// <summary>The audience of a UC-38 challenge token: the person audience plus <see cref="TwoFactorChallengeSuffix" 
 401249    public string TwoFactorChallenge => Person + TwoFactorChallengeSuffix;
 50
 51    /// <summary>The audience of a subject-rights-only token: the person audience plus <see cref="SubjectRightsSuffix" /
 385152    public string SubjectRights => Person + SubjectRightsSuffix;
 53
 54    /// <summary>The audiences derived from the configuration full tokens are issued and validated with.</summary>
 89955    public static PersonTokenAudiences From(JwtConfiguration configuration) => new(configuration.Audience);
 56}