< Summary

Information
Class: AsiBackbone.AspNetCore.Actors.HttpContextAsiBackboneActorContextResolver
Assembly: AsiBackbone.AspNetCore
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.AspNetCore/Actors/HttpContextAsiBackboneActorContextResolver.cs
Line coverage
95%
Covered lines: 40
Uncovered lines: 2
Coverable lines: 42
Total lines: 91
Line coverage: 95.2%
Branch coverage
75%
Covered branches: 27
Total branches: 36
Branch coverage: 75%
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.23%
get_ResolveUnauthenticatedActor()50%22100%
ResolveActorType(...)100%66100%
FindFirstNonEmptyClaimValue(...)100%66100%

File(s)

/home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.AspNetCore/Actors/HttpContextAsiBackboneActorContextResolver.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 HttpContextAsiBackboneActorContextResolver : IAsiBackboneHttpActorContextResolver
 12{
 13    private readonly IHttpContextAccessor httpContextAccessor;
 14    private readonly AsiBackboneHttpActorContextOptions options;
 15
 16    /// <summary>
 17    /// Initializes a new instance of the <see cref="HttpContextAsiBackboneActorContextResolver" /> class.
 18    /// </summary>
 19    /// <param name="httpContextAccessor">The ASP.NET Core HTTP context accessor.</param>
 20    /// <param name="options">The actor mapping options.</param>
 3821    public HttpContextAsiBackboneActorContextResolver(
 3822        IHttpContextAccessor httpContextAccessor,
 3823        IOptions<AsiBackboneHttpActorContextOptions> options)
 24    {
 3825        this.httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
 3826        this.options = options?.Value ?? throw new ArgumentNullException(nameof(options));
 3827        this.options.Validate();
 3828    }
 29
 30    /// <inheritdoc />
 31    public IAsiBackboneActorContext ResolveActorContext()
 32    {
 1733        ClaimsPrincipal? user = httpContextAccessor.HttpContext?.User;
 34
 1735        if (user?.Identity?.IsAuthenticated != true)
 36        {
 437            return ResolveUnauthenticatedActor;
 38        }
 39
 1340        string? actorId = FindFirstNonEmptyClaimValue(user, options.ActorIdClaimTypes);
 1341        if (string.IsNullOrWhiteSpace(actorId))
 42        {
 143            return ResolveUnauthenticatedActor;
 44        }
 45
 1246        string? displayName = FindFirstNonEmptyClaimValue(user, options.DisplayNameClaimTypes);
 1247        AsiBackboneActorType actorType = ResolveActorType(user);
 48
 1249        return actorType switch
 1250        {
 251            AsiBackboneActorType.Service => AsiBackboneActorContext.Service(actorId, displayName),
 152            AsiBackboneActorType.System => AsiBackboneActorContext.System,
 353            AsiBackboneActorType.Agent => AsiBackboneActorContext.Agent(actorId, displayName),
 654            AsiBackboneActorType.Human => AsiBackboneActorContext.Human(actorId, displayName),
 055            AsiBackboneActorType.Unknown => AsiBackboneActorContext.Unknown,
 056            _ => AsiBackboneActorContext.Human(actorId, displayName),
 1257        };
 58    }
 59
 560    private IAsiBackboneActorContext ResolveUnauthenticatedActor => string.IsNullOrWhiteSpace(options.UnauthenticatedDis
 561        ? AsiBackboneActorContext.Unknown
 562        : AsiBackboneActorContext.Human(
 563            AsiBackboneActorContext.UnknownActorId,
 564            options.UnauthenticatedDisplayName,
 565            isAuthenticated: false);
 66
 67    private AsiBackboneActorType ResolveActorType(ClaimsPrincipal user)
 68    {
 1269        string? actorTypeValue = FindFirstNonEmptyClaimValue(user, [options.ActorTypeClaimType]);
 70
 1271        return Enum.TryParse(actorTypeValue, ignoreCase: true, out AsiBackboneActorType actorType)
 1272            && Enum.IsDefined(actorType)
 1273            && options.AllowedActorTypesFromClaims.Contains(actorType)
 1274            ? actorType
 1275            : options.DefaultAuthenticatedActorType;
 76    }
 77
 78    private static string? FindFirstNonEmptyClaimValue(ClaimsPrincipal user, IEnumerable<string> claimTypes)
 79    {
 28280        foreach (string claimType in claimTypes.Where(static claimType => !string.IsNullOrWhiteSpace(claimType)))
 81        {
 7882            Claim? claim = user.FindFirst(claimType);
 7883            if (!string.IsNullOrWhiteSpace(claim?.Value))
 84            {
 2685                return claim.Value.Trim();
 86            }
 87        }
 88
 1189        return null;
 2690    }
 91}