54 lines
2.5 KiB
C#
54 lines
2.5 KiB
C#
using System.Security.Claims;
|
|
using Elsa.Common;
|
|
using Elsa.Identity.Constants;
|
|
using Elsa.Identity.Entities;
|
|
using Elsa.Identity.Models;
|
|
using Elsa.Identity.Options;
|
|
using Elsa.Identity.Services;
|
|
using Microsoft.Extensions.Options;
|
|
using Microsoft.IdentityModel.JsonWebTokens;
|
|
|
|
namespace Elsa.Identity.UnitTests.Services;
|
|
|
|
public class DefaultElsaTokenServiceTests
|
|
{
|
|
[Fact(DisplayName = "Token issuance context is projected into an Elsa access token")]
|
|
public async Task IssueAccessTokenProjectsContext()
|
|
{
|
|
var clock = new TestSystemClock(new DateTimeOffset(2026, 7, 24, 12, 0, 0, TimeSpan.Zero));
|
|
var options = Microsoft.Extensions.Options.Options.Create(new IdentityTokenOptions
|
|
{
|
|
SigningKey = "external-authentication-test-signing-key",
|
|
Issuer = "https://elsa.test",
|
|
Audience = "elsa-api",
|
|
AccessTokenLifetime = TimeSpan.FromMinutes(15)
|
|
});
|
|
var service = new DefaultElsaTokenService(clock, options);
|
|
var user = new User { Id = "user-1", Name = "alice", TenantId = "tenant-a" };
|
|
var context = new TokenIssuanceContext(
|
|
user,
|
|
["operator"],
|
|
["workflows:read"],
|
|
[new Claim("department", "claims")],
|
|
"session-1");
|
|
|
|
var result = await service.IssueAccessTokenAsync(context);
|
|
var token = new JsonWebTokenHandler().ReadJsonWebToken(result.Token);
|
|
|
|
Assert.Equal(clock.UtcNow.AddMinutes(15), result.ExpiresAt);
|
|
Assert.Contains(token.Claims, x => x.Type == JwtRegisteredClaimNames.Sub && x.Value == user.Id);
|
|
Assert.Contains(token.Claims, x => x.Type == JwtRegisteredClaimNames.Name && x.Value == user.Name);
|
|
Assert.Contains(token.Claims, x => x.Type == options.Value.TenantIdClaimsType && x.Value == user.TenantId);
|
|
Assert.Contains(token.Claims, x => x.Type == ClaimTypes.Role && x.Value == "operator");
|
|
Assert.Contains(token.Claims, x => x.Type == "permissions" && x.Value == "workflows:read");
|
|
Assert.Contains(token.Claims, x => x.Type == "department" && x.Value == "claims");
|
|
Assert.Contains(token.Claims, x => x.Type == CustomClaimTypes.ExternalAuthenticationSessionId && x.Value == "session-1");
|
|
Assert.Contains(token.Claims, x => x.Type == TokenUse.ClaimType && x.Value == TokenUse.Access);
|
|
}
|
|
|
|
private sealed class TestSystemClock(DateTimeOffset utcNow) : ISystemClock
|
|
{
|
|
public DateTimeOffset UtcNow { get; } = utcNow;
|
|
}
|
|
}
|