< Summary

Information
Class: AsiBackbone.AspNetCore.Actors.HttpContextGovernanceActorContextResolver
Assembly: AsiBackbone.AspNetCore
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.AspNetCore/Actors/HttpContextGovernanceActorContextResolver.cs
Line coverage
95%
Covered lines: 40
Uncovered lines: 2
Coverable lines: 42
Total lines: 91
Line coverage: 95.2%
Branch coverage
77%
Covered branches: 28
Total branches: 36
Branch coverage: 77.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)50%66100%
ResolveActorContext()68.75%161688.24%
get_ResolveUnauthenticatedActor()100%22100%
ResolveActorType(...)100%66100%
FindFirstNonEmptyClaimValue(...)100%66100%

File(s)

/home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.AspNetCore/Actors/HttpContextGovernanceActorContextResolver.cs

#LineLine coverage
 1using System.Security.Claims;
 2using AsiBackbone.Core.Actors;
 3using Microsoft.AspNetCore.Http;
 4using Microsoft.Extensions.Options;
 5
 6namespace AsiBackbone.AspNetCore.Actors;
 7
 8/// <summary>
 9/// Maps the current ASP.NET Core HTTP context into a framework-neutral AsiBackbone actor context.
 10/// </summary>
 11public sealed class HttpContextGovernanceActorContextResolver : IHttpGovernanceActorContextResolver
 12{
 13    private readonly IHttpContextAccessor httpContextAccessor;
 14    private readonly HttpGovernanceActorContextOptions options;
 15
 16    /// <summary>
 17    /// Initializes a new instance of the <see cref="HttpContextGovernanceActorContextResolver" /> class.
 18    /// </summary>
 19    /// <param name="httpContextAccessor">The ASP.NET Core HTTP context accessor.</param>
 20    /// <param name="options">The actor mapping options.</param>
 4421    public HttpContextGovernanceActorContextResolver(
 4422        IHttpContextAccessor httpContextAccessor,
 4423        IOptions<HttpGovernanceActorContextOptions> options)
 24    {
 4425        this.httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
 4426        this.options = options?.Value ?? throw new ArgumentNullException(nameof(options));
 4427        this.options.Validate();
 4428    }
 29
 30    /// <inheritdoc />
 31    public IGovernanceActorContext ResolveActorContext()
 32    {
 2133        ClaimsPrincipal? user = httpContextAccessor.HttpContext?.User;
 34
 2135        if (user?.Identity?.IsAuthenticated != true)
 36        {
 737            return ResolveUnauthenticatedActor;
 38        }
 39
 1440        string? actorId = FindFirstNonEmptyClaimValue(user, options.ActorIdClaimTypes);
 1441        if (string.IsNullOrWhiteSpace(actorId))
 42        {
 143            return ResolveUnauthenticatedActor;
 44        }
 45
 1346        string? displayName = FindFirstNonEmptyClaimValue(user, options.DisplayNameClaimTypes);
 1347        GovernanceActorType actorType = ResolveActorType(user);
 48
 1349        return actorType switch
 1350        {
 251            GovernanceActorType.Service => GovernanceActorContext.Service(actorId, displayName),
 152            GovernanceActorType.System => GovernanceActorContext.System,
 353            GovernanceActorType.Agent => GovernanceActorContext.Agent(actorId, displayName),
 754            GovernanceActorType.Human => GovernanceActorContext.Human(actorId, displayName),
 055            GovernanceActorType.Unknown => GovernanceActorContext.Unknown,
 056            _ => GovernanceActorContext.Human(actorId, displayName),
 1357        };
 58    }
 59
 860    private IGovernanceActorContext ResolveUnauthenticatedActor => string.IsNullOrWhiteSpace(options.UnauthenticatedDisp
 861        ? GovernanceActorContext.Unknown
 862        : GovernanceActorContext.Human(
 863            GovernanceActorContext.UnknownActorId,
 864            options.UnauthenticatedDisplayName,
 865            isAuthenticated: false);
 66
 67    private GovernanceActorType ResolveActorType(ClaimsPrincipal user)
 68    {
 1369        string? actorTypeValue = FindFirstNonEmptyClaimValue(user, [options.ActorTypeClaimType]);
 70
 1371        return Enum.TryParse(actorTypeValue, ignoreCase: true, out GovernanceActorType actorType)
 1372            && Enum.IsDefined(actorType)
 1373            && options.AllowedActorTypesFromClaims.Contains(actorType)
 1374            ? actorType
 1375            : options.DefaultAuthenticatedActorType;
 76    }
 77
 78    private static string? FindFirstNonEmptyClaimValue(ClaimsPrincipal user, IEnumerable<string> claimTypes)
 79    {
 18180        foreach (string claimType in claimTypes.Where(static claimType => !string.IsNullOrWhiteSpace(claimType)))
 81        {
 6482            Claim? claim = user.FindFirst(claimType);
 6483            if (!string.IsNullOrWhiteSpace(claim?.Value))
 84            {
 2785                return claim.Value.Trim();
 86            }
 87        }
 88
 1389        return null;
 2790    }
 91}