< Summary

Information
Class: Elsa.Identity.Services.DefaultAccessTokenIssuer
Assembly: Elsa.Identity
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Identity/Services/DefaultAccessTokenIssuer.cs
Line coverage
26%
Covered lines: 5
Uncovered lines: 14
Coverable lines: 19
Total lines: 61
Line coverage: 26.3%
Branch coverage
0%
Covered branches: 0
Total branches: 4
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
.ctor(...)100%210%
IssueTokensAsync()0%2040%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Identity/Services/DefaultAccessTokenIssuer.cs

#LineLine coverage
 1using Elsa.Common;
 2using Elsa.Extensions;
 3using Elsa.Identity.Contracts;
 4using Elsa.Identity.Entities;
 5using Elsa.Identity.Models;
 6using Elsa.Identity.Options;
 7using Microsoft.Extensions.DependencyInjection;
 8using Microsoft.Extensions.Options;
 9
 10namespace Elsa.Identity.Services;
 11
 12/// <summary>
 13/// Default implementation of <see cref="IAccessTokenIssuer"/>.
 14/// </summary>
 15public class DefaultAccessTokenIssuer : IAccessTokenIssuer
 16{
 17    private readonly IRoleProvider _roleProvider;
 18    private readonly IElsaTokenService _tokenService;
 19    private readonly IPermissionStampCalculator? _stampCalculator;
 20
 21    /// <summary>
 22    /// Initializes a new instance of the <see cref="DefaultAccessTokenIssuer"/> class.
 23    /// </summary>
 24    [ActivatorUtilitiesConstructor]
 525    public DefaultAccessTokenIssuer(IRoleProvider roleProvider, IElsaTokenService tokenService, IPermissionStampCalculat
 26    {
 527        _roleProvider = roleProvider;
 528        _tokenService = tokenService;
 529        _stampCalculator = stampCalculator;
 530    }
 31
 32    /// <summary>
 33    /// Initializes a new instance using the legacy constructor shape.
 34    /// </summary>
 35    public DefaultAccessTokenIssuer(IRoleProvider roleProvider, ISystemClock systemClock, IOptions<IdentityTokenOptions>
 036        : this(roleProvider, new DefaultElsaTokenService(systemClock, identityTokenOptions))
 37    {
 038    }
 39
 40    /// <inheritdoc />
 41    public async ValueTask<IssuedTokens> IssueTokensAsync(User user, CancellationToken cancellationToken = default)
 42    {
 043        var roles = (await _roleProvider.FindByIdsAsync(user.Roles, cancellationToken)).ToList();
 044        var permissions = roles.SelectMany(x => x.Permissions).ToList();
 045        var roleNames = roles.Select(x => x.Name).ToList();
 46
 47        // The stamp is derived from the same roles that produced these permissions, so it changes exactly
 48        // when the grants do. Issued unconditionally; only validation is gated by configuration, which
 49        // means turning the feature on does not invalidate tokens already in flight.
 050        var stamp = _stampCalculator is null ? null : await _stampCalculator.ComputeAsync(user, cancellationToken);
 051        var additionalClaims = stamp is null
 052            ? Array.Empty<System.Security.Claims.Claim>()
 053            : [new System.Security.Claims.Claim(PermissionStampCalculator.ClaimType, stamp)];
 54
 055        var context = new TokenIssuanceContext(user, roleNames, permissions, additionalClaims);
 056        var accessToken = await _tokenService.IssueAccessTokenAsync(context, cancellationToken);
 057        var refreshToken = await _tokenService.IssueRefreshTokenAsync(context, cancellationToken);
 58
 059        return new IssuedTokens(accessToken.Token, refreshToken.Token);
 060    }
 61}