< 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
2%
Covered lines: 1
Uncovered lines: 36
Coverable lines: 37
Total lines: 69
Line coverage: 2.7%
Branch coverage
0%
Covered branches: 0
Total branches: 8
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%
IssueTokensAsync()0%7280%
ConfigureTokenOptions()100%210%

File(s)

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

#LineLine coverage
 1using System.Security.Claims;
 2using Elsa.Common;
 3using Elsa.Extensions;
 4using Elsa.Identity.Constants;
 5using Elsa.Identity.Contracts;
 6using Elsa.Identity.Entities;
 7using Elsa.Identity.Models;
 8using Elsa.Identity.Options;
 9using FastEndpoints.Security;
 10using Microsoft.Extensions.Options;
 11using Microsoft.IdentityModel.JsonWebTokens;
 12
 13namespace Elsa.Identity.Services;
 14
 15/// <summary>
 16/// Default implementation of <see cref="IAccessTokenIssuer"/>.
 17/// </summary>
 318public class DefaultAccessTokenIssuer(IRoleProvider roleProvider, ISystemClock systemClock, IOptions<IdentityTokenOption
 19{
 20    /// <inheritdoc />
 21    public async ValueTask<IssuedTokens> IssueTokensAsync(User user, CancellationToken cancellationToken = default)
 22    {
 023        var roles = (await roleProvider.FindByIdsAsync(user.Roles, cancellationToken)).ToList();
 024        var permissions = roles.SelectMany(x => x.Permissions).ToList();
 025        var roleNames = roles.Select(x => x.Name).ToList();
 026        var tokenOptions = identityTokenOptions.Value;
 027        var signingKey = tokenOptions.SigningKey;
 028        var issuer = tokenOptions.Issuer;
 029        var audience = tokenOptions.Audience;
 030        var accessTokenLifetime = tokenOptions.AccessTokenLifetime;
 031        var refreshTokenLifetime = tokenOptions.RefreshTokenLifetime;
 32
 033        if (string.IsNullOrWhiteSpace(signingKey)) throw new Exception("No signing key configured");
 034        if (string.IsNullOrWhiteSpace(issuer)) throw new Exception("No issuer configured");
 035        if (string.IsNullOrWhiteSpace(audience)) throw new Exception("No audience configured");
 36
 037        var nameClaim = new Claim(JwtRegisteredClaimNames.Name, user.Name);
 038        var claims = new List<Claim>
 039        {
 040            nameClaim
 041        };
 42
 043        if (!string.IsNullOrWhiteSpace(user.TenantId))
 44        {
 045            var tenantIdClaim = new Claim(tokenOptions.TenantIdClaimsType, user.TenantId);
 046            claims.Add(tenantIdClaim);
 47        }
 48
 049        var now = systemClock.UtcNow;
 050        var accessTokenExpiresAt = now.Add(accessTokenLifetime);
 051        var refreshTokenExpiresAt = now.Add(refreshTokenLifetime);
 052        var accessToken = JwtBearer.CreateToken(options => ConfigureTokenOptions(options, accessTokenExpiresAt.UtcDateTi
 053        var refreshToken = JwtBearer.CreateToken(options => ConfigureTokenOptions(options, refreshTokenExpiresAt.UtcDate
 54
 055        return new IssuedTokens(accessToken, refreshToken);
 56
 57        void ConfigureTokenOptions(JwtCreationOptions options, DateTime expireAt, string tokenUse)
 58        {
 059            options.SigningKey = signingKey;
 060            options.ExpireAt = expireAt;
 061            options.Issuer = issuer;
 062            options.Audience = audience;
 063            options.User.Claims.AddRange(claims);
 064            options.User.Claims.Add(new Claim(TokenUse.ClaimType, tokenUse));
 065            options.User.Permissions.AddRange(permissions);
 066            options.User.Roles.AddRange(roleNames);
 067        }
 068    }
 69}