< Summary

Information
Class: Elsa.Connections.Models.ConnectionAccessCredential
Assembly: Elsa.Connections
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Connections/Models/CredentialMaterial.cs
Line coverage
84%
Covered lines: 16
Uncovered lines: 3
Coverable lines: 19
Total lines: 94
Line coverage: 84.2%
Branch coverage
78%
Covered branches: 11
Total branches: 14
Branch coverage: 78.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_AccessToken()100%11100%
get_ApiKey()100%11100%
get_Kind()100%11100%
get_ExpiresAt()100%22100%
.ctor(...)100%11100%
.ctor(...)75%141275%
ToString()100%11100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Connections/Models/CredentialMaterial.cs

#LineLine coverage
 1using System.Text.Json;
 2using System.Text.Json.Serialization;
 3
 4namespace Elsa.Connections.Models;
 5
 6public enum ConnectionCredentialKind
 7{
 8    OAuth = 0,
 9    ApiKey = 1
 10}
 11
 12/// <summary>Token material is serialized into the encrypted Secrets value and must remain short-lived in memory.</summa
 13public sealed class CredentialMaterial(string accessToken, string refreshToken, DateTimeOffset accessTokenExpiresAt)
 14{
 15    [JsonIgnore]
 16    public string AccessToken { get; } = accessToken;
 17
 18    [JsonIgnore]
 19    public string RefreshToken { get; } = refreshToken;
 20
 21    [JsonIgnore]
 22    public DateTimeOffset AccessTokenExpiresAt { get; } = accessTokenExpiresAt;
 23
 24    public override string ToString() => "CredentialMaterial { Redacted = true }";
 25}
 26
 27/// <summary>Credential handed to an authorized consumer. Refresh material remains inside lifecycle management.</summary
 28[JsonConverter(typeof(ConnectionAccessCredentialJsonConverter))]
 29public sealed class ConnectionAccessCredential
 30{
 31    private readonly DateTimeOffset? _expiresAt;
 32
 33    [JsonIgnore]
 3034    public string AccessToken { get; }
 35
 36    [JsonIgnore]
 437    public string? ApiKey { get; }
 38
 2739    public ConnectionCredentialKind Kind { get; }
 40
 41    /// <summary>Gets the OAuth expiry. API-key credentials are explicitly non-expiring and have no expiry value.</summa
 1042    public DateTimeOffset ExpiresAt => _expiresAt ?? throw new InvalidOperationException("API-key credentials do not hav
 43
 44    public ConnectionAccessCredential(string accessToken, DateTimeOffset expiresAt)
 1245        : this(ConnectionCredentialKind.OAuth, accessToken, expiresAt)
 46    {
 1247    }
 48
 3449    public ConnectionAccessCredential(ConnectionCredentialKind kind, string value, DateTimeOffset? expiresAt)
 50    {
 3451        if (string.IsNullOrWhiteSpace(value))
 52        {
 053            throw new ArgumentException("Credential value is required.", nameof(value));
 54        }
 55
 3456        if (kind == ConnectionCredentialKind.OAuth && !expiresAt.HasValue)
 57        {
 058            throw new ArgumentException("OAuth credentials require an expiry.", nameof(expiresAt));
 59        }
 60
 3461        if (kind == ConnectionCredentialKind.ApiKey && expiresAt.HasValue)
 62        {
 063            throw new ArgumentException("API-key credentials do not have an expiry.", nameof(expiresAt));
 64        }
 65
 3466        Kind = kind;
 3467        AccessToken = value;
 3468        ApiKey = kind == ConnectionCredentialKind.ApiKey ? value : null;
 3469        _expiresAt = expiresAt;
 3470    }
 71
 472    public override string ToString() => "ConnectionAccessCredential { Redacted = true }";
 73}
 74
 75internal sealed class ConnectionAccessCredentialJsonConverter : JsonConverter<ConnectionAccessCredential>
 76{
 77    public override ConnectionAccessCredential Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions
 78        throw new JsonException("Connection access credentials are write-only.");
 79
 80    public override void Write(Utf8JsonWriter writer, ConnectionAccessCredential value, JsonSerializerOptions options)
 81    {
 82        writer.WriteStartObject();
 83        writer.WriteNumber(GetName(nameof(ConnectionAccessCredential.Kind)), (int)value.Kind);
 84
 85        if (value.Kind == ConnectionCredentialKind.OAuth)
 86        {
 87            writer.WriteString(GetName(nameof(ConnectionAccessCredential.ExpiresAt)), value.ExpiresAt);
 88        }
 89
 90        writer.WriteEndObject();
 91
 92        string GetName(string name) => options.PropertyNamingPolicy?.ConvertName(name) ?? name;
 93    }
 94}