< Summary

Information
Class: Elsa.Identity.Services.DefaultElsaTokenService
Assembly: Elsa.Identity
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Identity/Services/DefaultElsaTokenService.cs
Line coverage
91%
Covered lines: 32
Uncovered lines: 3
Coverable lines: 35
Total lines: 76
Line coverage: 91.4%
Branch coverage
70%
Covered branches: 7
Total branches: 10
Branch coverage: 70%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
IssueAccessTokenAsync(...)100%11100%
IssueRefreshTokenAsync(...)100%11100%
IssueTokenAsync(...)70%101090.62%

File(s)

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

#LineLine coverage
 1using System.Security.Claims;
 2using Elsa.Common;
 3using Elsa.Identity.Constants;
 4using Elsa.Identity.Contracts;
 5using Elsa.Identity.Models;
 6using Elsa.Identity.Options;
 7using Microsoft.Extensions.Options;
 8using Microsoft.IdentityModel.JsonWebTokens;
 9using Microsoft.IdentityModel.Tokens;
 10
 11namespace Elsa.Identity.Services;
 12
 13/// <summary>
 14/// Creates signed Elsa JWTs from trusted issuance data.
 15/// </summary>
 516public sealed class DefaultElsaTokenService(ISystemClock systemClock, IOptions<IdentityTokenOptions> identityTokenOption
 17{
 18    /// <inheritdoc />
 19    public ValueTask<IssuedAccessToken> IssueAccessTokenAsync(TokenIssuanceContext context, CancellationToken cancellati
 20    {
 221        return IssueTokenAsync(context, TokenUse.Access, identityTokenOptions.Value.AccessTokenLifetime, cancellationTok
 22    }
 23
 24    /// <inheritdoc />
 25    public ValueTask<IssuedAccessToken> IssueRefreshTokenAsync(TokenIssuanceContext context, CancellationToken cancellat
 26    {
 127        return IssueTokenAsync(context, TokenUse.Refresh, identityTokenOptions.Value.RefreshTokenLifetime, cancellationT
 28    }
 29
 30    private ValueTask<IssuedAccessToken> IssueTokenAsync(
 31        TokenIssuanceContext context,
 32        string tokenUse,
 33        TimeSpan lifetime,
 34        CancellationToken cancellationToken)
 35    {
 336        cancellationToken.ThrowIfCancellationRequested();
 337        var tokenOptions = identityTokenOptions.Value;
 38
 339        if (string.IsNullOrWhiteSpace(tokenOptions.SigningKey))
 040            throw new InvalidOperationException("No signing key configured");
 341        if (string.IsNullOrWhiteSpace(tokenOptions.Issuer))
 042            throw new InvalidOperationException("No issuer configured");
 343        if (string.IsNullOrWhiteSpace(tokenOptions.Audience))
 044            throw new InvalidOperationException("No audience configured");
 45
 346        var claims = new List<Claim>
 347        {
 348            new(JwtRegisteredClaimNames.Sub, context.User.Id),
 349            new(JwtRegisteredClaimNames.Name, context.User.Name)
 350        };
 351        claims.AddRange(context.AdditionalClaims);
 52
 353        if (!string.IsNullOrWhiteSpace(context.User.TenantId))
 154            claims.Add(new Claim(tokenOptions.TenantIdClaimsType, context.User.TenantId));
 55
 356        if (!string.IsNullOrWhiteSpace(context.ExternalAuthenticationSessionId))
 157            claims.Add(new Claim(CustomClaimTypes.ExternalAuthenticationSessionId, context.ExternalAuthenticationSession
 58
 359        var expiresAt = systemClock.UtcNow.Add(lifetime);
 460        claims.AddRange(context.Roles.Select(x => new Claim(ClaimTypes.Role, x)));
 461        claims.AddRange(context.Permissions.Select(x => new Claim("permissions", x)));
 362        claims.Add(new Claim(TokenUse.ClaimType, tokenUse));
 63
 364        var descriptor = new SecurityTokenDescriptor
 365        {
 366            Subject = new ClaimsIdentity(claims),
 367            Expires = expiresAt.UtcDateTime,
 368            Issuer = tokenOptions.Issuer,
 369            Audience = tokenOptions.Audience,
 370            SigningCredentials = new SigningCredentials(tokenOptions.CreateSecurityKey(), SecurityAlgorithms.HmacSha256S
 371        };
 372        var token = new JsonWebTokenHandler().CreateToken(descriptor);
 73
 374        return ValueTask.FromResult(new IssuedAccessToken(token, expiresAt));
 75    }
 76}