< Summary - Heimdall API

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

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_Id()100%11100%
get_RoleId()100%11100%
get_ScopeId()100%11100%
get_OwnedScopeIds()100%11100%
get_DisplayName()100%11100%
get_ScopePermissionClaims()100%11100%
.ctor(...)100%11100%
get_MfaPending()100%11100%
get_ChallengeId()100%11100%
get_SubjectRightsOnly()100%11100%
get_SecurityStamp()100%11100%

File(s)

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

#LineLine coverage
 1using ArturRios.Util.WebApi.Security.Interfaces;
 2
 3namespace ArturRios.Heimdall.WebApi.Security;
 4
 5/// <summary>
 6///     The caller identity this API carries on an authenticated request, rebuilt from the token's
 7///     claims by <see cref="IdentityUserMapper" /> (UC-11, FR-AU-04). Every identifier is a
 8///     <c>PublicId</c>: internal <c>bigint</c> Ids never reach a token or the request pipeline
 9///     (NFR-15).
 10/// </summary>
 11/// <param name="Id">The person's <c>PublicId</c>.</param>
 12/// <param name="RoleId">The person's role value (see <c>Roles</c>).</param>
 13/// <param name="ScopeId">
 14///     The <c>PublicId</c> of the scope a <c>User</c> belongs to; <c>null</c> for a
 15///     <c>ScopeAdmin</c> or <c>SystemAdmin</c>.
 16/// </param>
 17/// <param name="OwnedScopeIds">
 18///     The <c>PublicId</c>s of the scopes a <c>ScopeAdmin</c> owns; empty for a <c>User</c> or
 19///     <c>SystemAdmin</c>.
 20/// </param>
 195621public sealed record IdentityUser(
 317922    Guid Id,
 358123    int RoleId,
 93424    Guid? ScopeId,
 287325    IReadOnlyCollection<Guid> OwnedScopeIds) : IAuthenticatedUser
 26{
 27    /// <summary>
 28    ///     The caller's display name, included on full authentication tokens so downstream services
 29    ///     can provision a local profile without calling Heimdall on the request path.
 30    /// </summary>
 212031    public string? DisplayName { get; init; }
 32
 33    /// <summary>
 34    ///     The names of the acting scope's permissions whose <c>IncludeAsJwtClaim</c> flag is set,
 35    ///     folded into the token at login so a downstream caller can authorize on them (UC-31…UC-35).
 36    ///     Empty for a <c>SystemAdmin</c> (no scope) and when a scope has no flagged permissions.
 37    /// </summary>
 400638    public IReadOnlyCollection<string> ScopePermissionClaims { get; init; } = [];
 39
 40    /// <summary>An identity carrying no scope claim, for a <c>SystemAdmin</c>.</summary>
 15041    public IdentityUser(Guid id, int roleId) : this(id, roleId, null, [])
 42    {
 15043    }
 44
 45    /// <summary>
 46    ///     Whether this identity comes from a UC-38 challenge token rather than a full authentication
 47    ///     token (FR-2F-07, NFR-17) — set on the token by <c>JwtTwoFactorChallengeTokenIssuer</c> and
 48    ///     read back here by <see cref="IdentityUserMapper" />. <see cref="MfaPendingGuardFilter" />
 49    ///     rejects every request where this is <c>true</c>, per FR-2F-10.
 50    /// </summary>
 432651    public bool MfaPending { get; init; }
 52
 53    /// <summary>
 54    ///     Which challenge a UC-38 challenge token stands for — set alongside <see cref="MfaPending" />
 55    ///     by <c>JwtTwoFactorChallengeTokenIssuer</c>, <c>null</c> on every other token. UC-38 honours
 56    ///     the token only while this still equals the configuration's outstanding challenge, which is
 57    ///     what makes a challenge redeemable once (FR-2F-10).
 58    /// </summary>
 222859    public Guid? ChallengeId { get; init; }
 60
 61    /// <summary>
 62    ///     Whether this identity comes from a subject-rights-only token — issued at sign-in to an
 63    ///     identity whose processing is restricted (NFR-24), by <c>JwtAuthTokenIssuer</c>.
 64    ///     <see cref="SubjectRightsOnlyGuardFilter" /> refuses such a token on every action not marked
 65    ///     <see cref="DataSubjectRightAttribute" />.
 66    /// </summary>
 411967    public bool SubjectRightsOnly { get; init; }
 68
 69    /// <summary>
 70    ///     The person's <c>SecurityStamp</c> when the token was issued (FR-AU-11), carried by every
 71    ///     person token — full, challenge and subject-rights-only — and <c>null</c> on a Google User's,
 72    ///     which has no credential of its own here to rotate. <see cref="ActorLivenessFilter" />
 73    ///     refuses a person token whose stamp is missing or no longer the person's.
 74    /// </summary>
 448975    public Guid? SecurityStamp { get; init; }
 76}