< Summary

Information
Class: Elsa.ExternalAuthentication.Stores.InMemory.InMemoryAuthorizationGrantStore
Assembly: Elsa.ExternalAuthentication
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.ExternalAuthentication/Stores/InMemory/InMemoryAuthorizationGrantStore.cs
Line coverage
91%
Covered lines: 33
Uncovered lines: 3
Coverable lines: 36
Total lines: 65
Line coverage: 91.6%
Branch coverage
62%
Covered branches: 5
Total branches: 8
Branch coverage: 62.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
SaveAsync(...)50%2285.71%
TryTakeAsync(...)66.66%6681.81%
Clone(...)100%11100%
.ctor(...)100%11100%
get_Grant()100%11100%
get_IsConsumed()100%11100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.ExternalAuthentication/Stores/InMemory/InMemoryAuthorizationGrantStore.cs

#LineLine coverage
 1using Elsa.Common;
 2using Elsa.ExternalAuthentication.Contracts;
 3using Elsa.ExternalAuthentication.Models;
 4
 5namespace Elsa.ExternalAuthentication.Stores.InMemory;
 6
 317public sealed class InMemoryAuthorizationGrantStore(ISystemClock clock) : IAuthorizationGrantStore
 8{
 319    private readonly object _syncRoot = new();
 3110    private readonly Dictionary<string, GrantEntry> _entries = new(StringComparer.Ordinal);
 11
 12    public ValueTask SaveAsync(AuthorizationGrant grant, CancellationToken cancellationToken = default)
 13    {
 1114        cancellationToken.ThrowIfCancellationRequested();
 15
 1116        lock (_syncRoot)
 17        {
 1118            if (_entries.ContainsKey(grant.CodeHash))
 019                throw new InvalidOperationException("An authorization grant already exists for the supplied code hash.")
 20
 1121            _entries[grant.CodeHash] = new GrantEntry(Clone(grant));
 1122        }
 23
 1124        return ValueTask.CompletedTask;
 25    }
 26
 27    public ValueTask<TakeResult<AuthorizationGrant>> TryTakeAsync(string codeHash, CancellationToken cancellationToken =
 28    {
 2129        cancellationToken.ThrowIfCancellationRequested();
 30
 2131        lock (_syncRoot)
 32        {
 2133            if (!_entries.TryGetValue(codeHash, out var entry))
 034                return ValueTask.FromResult<TakeResult<AuthorizationGrant>>(new TakeResult<AuthorizationGrant>.NotFound(
 35
 2136            if (entry.Grant.ExpiresAt <= clock.UtcNow)
 037                return ValueTask.FromResult<TakeResult<AuthorizationGrant>>(new TakeResult<AuthorizationGrant>.Expired()
 38
 2139            if (entry.IsConsumed)
 1740                return ValueTask.FromResult<TakeResult<AuthorizationGrant>>(new TakeResult<AuthorizationGrant>.AlreadyCo
 41
 442            entry.IsConsumed = true;
 443            return ValueTask.FromResult<TakeResult<AuthorizationGrant>>(new TakeResult<AuthorizationGrant>.Taken(Clone(e
 44        }
 2145    }
 46
 1547    private static AuthorizationGrant Clone(AuthorizationGrant grant) => new()
 1548    {
 1549        CodeHash = grant.CodeHash,
 1550        ClientId = grant.ClientId,
 1551        CallbackUri = grant.CallbackUri,
 1552        TenantId = grant.TenantId,
 1553        UserId = grant.UserId,
 1554        ExternalSessionId = grant.ExternalSessionId,
 1555        PkceChallenge = grant.PkceChallenge,
 1556        ExpiresAt = grant.ExpiresAt,
 1557        ConsumedAt = grant.ConsumedAt
 1558    };
 59
 1160    private sealed class GrantEntry(AuthorizationGrant grant)
 61    {
 3662        public AuthorizationGrant Grant { get; } = grant;
 2563        public bool IsConsumed { get; set; }
 64    }
 65}