< Summary

Class:MUNity.BlazorServer.Areas.Identity.RevalidatingIdentityAuthenticationStateProvider<T>
Assembly:MUNity.BlazorServer
File(s):C:\Users\aeuke\source\repos\PeerConradi\munity\src\MUNity.BlazorServer\Areas\Identity\RevalidatingIdentityAuthenticationStateProvider.cs
Covered lines:0
Uncovered lines:34
Coverable lines:34
Total lines:74
Line coverage:0% (0 of 34)
Covered branches:0
Total branches:10
Branch coverage:0% (0 of 10)
Covered methods:0
Total methods:4
Method coverage:0% (0 of 4)

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)100%10%
get_RevalidationInterval()100%10%
ValidateAuthenticationStateAsync()0%60%
ValidateSecurityStampAsync()0%40%

File(s)

C:\Users\aeuke\source\repos\PeerConradi\munity\src\MUNity.BlazorServer\Areas\Identity\RevalidatingIdentityAuthenticationStateProvider.cs

#LineLine coverage
 1using Microsoft.AspNetCore.Components;
 2using Microsoft.AspNetCore.Components.Authorization;
 3using Microsoft.AspNetCore.Components.Server;
 4using Microsoft.AspNetCore.Identity;
 5using Microsoft.Extensions.DependencyInjection;
 6using Microsoft.Extensions.Logging;
 7using Microsoft.Extensions.Options;
 8using System;
 9using System.Security.Claims;
 10using System.Threading;
 11using System.Threading.Tasks;
 12
 13namespace MUNity.BlazorServer.Areas.Identity;
 14
 15public class RevalidatingIdentityAuthenticationStateProvider<TUser>
 16    : RevalidatingServerAuthenticationStateProvider where TUser : class
 17{
 18    private readonly IServiceScopeFactory _scopeFactory;
 19    private readonly IdentityOptions _options;
 20
 21    public RevalidatingIdentityAuthenticationStateProvider(
 22        ILoggerFactory loggerFactory,
 23        IServiceScopeFactory scopeFactory,
 24        IOptions<IdentityOptions> optionsAccessor)
 025        : base(loggerFactory)
 026    {
 027        _scopeFactory = scopeFactory;
 028        _options = optionsAccessor.Value;
 029    }
 30
 031    protected override TimeSpan RevalidationInterval => TimeSpan.FromMinutes(30);
 32
 33    protected override async Task<bool> ValidateAuthenticationStateAsync(
 34        AuthenticationState authenticationState, CancellationToken cancellationToken)
 035    {
 36        // Get the user manager from a new scope to ensure it fetches fresh data
 037        var scope = _scopeFactory.CreateScope();
 38        try
 039        {
 040            var userManager = scope.ServiceProvider.GetRequiredService<UserManager<TUser>>();
 041            return await ValidateSecurityStampAsync(userManager, authenticationState.User);
 42        }
 43        finally
 044        {
 045            if (scope is IAsyncDisposable asyncDisposable)
 046            {
 047                await asyncDisposable.DisposeAsync();
 048            }
 49            else
 050            {
 051                scope.Dispose();
 052            }
 053        }
 054    }
 55
 56    private async Task<bool> ValidateSecurityStampAsync(UserManager<TUser> userManager, ClaimsPrincipal principal)
 057    {
 058        var user = await userManager.GetUserAsync(principal);
 059        if (user == null)
 060        {
 061            return false;
 62        }
 063        else if (!userManager.SupportsUserSecurityStamp)
 064        {
 065            return true;
 66        }
 67        else
 068        {
 069            var principalStamp = principal.FindFirstValue(_options.ClaimsIdentity.SecurityStampClaimType);
 070            var userStamp = await userManager.GetSecurityStampAsync(user);
 071            return principalStamp == userStamp;
 72        }
 073    }
 74}