< Summary

Information
Class: Elsa.ExternalAuthentication.Models.AuthenticationClient
Assembly: Elsa.ExternalAuthentication
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.ExternalAuthentication/Models/ExternalAuthenticationModels.cs
Line coverage
75%
Covered lines: 31
Uncovered lines: 10
Coverable lines: 41
Total lines: 326
Line coverage: 75.6%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
.ctor(...)100%11100%
get_ClientId()100%11100%
get_DisplayName()100%11100%
get_ClientType()100%11100%
get_CallbackUris()100%11100%
get_LogoutCallbackUris()100%11100%
get_AllowedOrigins()100%11100%
get_AllowedReturnPathPrefixes()100%11100%
get_SecretBinding()100%11100%
get_IsEnabled()100%11100%
Deconstruct(...)100%210%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.ExternalAuthentication/Models/ExternalAuthenticationModels.cs

#LineLine coverage
 1using System.Text.Json;
 2
 3namespace Elsa.ExternalAuthentication.Models;
 4
 5public enum ConnectionSourceOwnership
 6{
 7    Configuration,
 8    Database
 9}
 10
 11public enum ConnectionScopeKind
 12{
 13    Host,
 14    DefaultTenant,
 15    Tenant
 16}
 17
 18public enum ConnectionLifecycle
 19{
 20    Draft,
 21    Disabled,
 22    Enabled,
 23    Archived
 24}
 25
 26public enum ConnectionValidity
 27{
 28    Unknown,
 29    Valid,
 30    Invalid
 31}
 32
 33public enum AuthenticationClientType
 34{
 35    Confidential,
 36    Public
 37}
 38
 39public enum BrokerTransactionPurpose
 40{
 41    ExternalSignIn,
 42    LocalSignIn,
 43    Preview,
 44    UpstreamLogout
 45}
 46
 47public enum UpstreamLogoutMode
 48{
 49    Disabled,
 50    UserChoice,
 51    Always
 52}
 53
 54public enum ConnectionObservationStatus
 55{
 56    Succeeded,
 57    Failed,
 58    Warning
 59}
 60
 61public enum LoginMethodKind
 62{
 63    Local,
 64    External
 65}
 66
 67public enum BrowserCredentialPersistence
 68{
 69    Memory,
 70    SessionStorage,
 71    DurableStorage
 72}
 73
 74public sealed record ConnectionScope(ConnectionScopeKind Kind, string TenantId)
 75{
 76    public const string HostTenantId = "*";
 77    public const string DefaultTenantId = "";
 78
 79    public static ConnectionScope Host { get; } = new(ConnectionScopeKind.Host, HostTenantId);
 80    public static ConnectionScope DefaultTenant { get; } = new(ConnectionScopeKind.DefaultTenant, DefaultTenantId);
 81}
 82
 83public enum SecretBindingOwnership
 84{
 85    External,
 86    Managed
 87}
 88
 89public sealed record SecretBinding(string ResolverType, string Reference, string? ExpectedType = null, string? ExpectedS
 90
 91public sealed record SecretBindingState(bool IsConfigured, bool IsResolvable);
 92public sealed record SecretBindingPresentation(string Ownership, bool IsConfigured, bool IsResolvable);
 93
 94public sealed record PolicySelection(string Type, int SettingsVersion, JsonElement Settings);
 95
 96public sealed record GrantSourceSelection(string Type, int SettingsVersion, JsonElement Settings, int Order);
 97
 98public sealed record ClaimProjection(
 99    IReadOnlySet<string> AllowedClaimTypes,
 100    IReadOnlySet<string> RedactedClaimTypes,
 101    int MaximumClaimCount,
 102    int MaximumValueLength,
 103    int MaximumTotalBytes)
 104{
 105    public static ClaimProjection Empty { get; } = new(new HashSet<string>(StringComparer.Ordinal), new HashSet<string>(
 106}
 107
 108public sealed class IdentityProviderConnection
 109{
 110    public string Id { get; set; } = null!;
 111    public string TenantId { get; set; } = null!;
 112    public string Key { get; set; } = null!;
 113    public string AdapterType { get; set; } = null!;
 114    public int AdapterSettingsVersion { get; set; }
 115    public JsonElement AdapterSettings { get; set; }
 116    public IDictionary<string, SecretBinding> SecretBindings { get; set; } = new Dictionary<string, SecretBinding>(Strin
 117    public string DisplayName { get; set; } = null!;
 118    public string? IconId { get; set; }
 119    public int DisplayOrder { get; set; }
 120    public bool IsPreferred { get; set; }
 121    public bool IsEnabled { get; set; }
 122    /// <summary>When configuration-owned, explicitly shadows a database-owned connection with the same scoped key.</sum
 123    public bool OverridesConfigurationConnection { get; set; }
 124    public DateTimeOffset? ArchivedAt { get; set; }
 125    public PolicySelection? UnlinkedPolicy { get; set; }
 126    public ICollection<GrantSourceSelection> PermissionGrantSources { get; set; } = new List<GrantSourceSelection>();
 127    public ClaimProjection ClaimProjection { get; set; } = ClaimProjection.Empty;
 128    public UpstreamLogoutMode UpstreamLogoutMode { get; set; }
 129    public long Revision { get; set; }
 130    public string MaterialRevision { get; set; } = null!;
 131    public DateTimeOffset CreatedAt { get; set; }
 132    public DateTimeOffset UpdatedAt { get; set; }
 133}
 134
 135public sealed record ExternalIdentity(string Issuer, string Subject, IReadOnlyDictionary<string, IReadOnlyCollection<str
 136
 137public sealed record AuthenticationClient
 138{
 1139    public AuthenticationClient()
 140    {
 1141    }
 142
 31143    public AuthenticationClient(
 31144        string ClientId,
 31145        string DisplayName,
 31146        AuthenticationClientType ClientType,
 31147        IReadOnlySet<Uri> CallbackUris,
 31148        IReadOnlySet<Uri> LogoutCallbackUris,
 31149        IReadOnlySet<string> AllowedOrigins,
 31150        IReadOnlySet<string> AllowedReturnPathPrefixes,
 31151        SecretBinding? SecretBinding,
 31152        bool IsEnabled)
 153    {
 31154        this.ClientId = ClientId;
 31155        this.DisplayName = DisplayName;
 31156        this.ClientType = ClientType;
 31157        this.CallbackUris = CallbackUris.ToHashSet();
 31158        this.LogoutCallbackUris = LogoutCallbackUris.ToHashSet();
 31159        this.AllowedOrigins = AllowedOrigins.ToHashSet(StringComparer.Ordinal);
 31160        this.AllowedReturnPathPrefixes = AllowedReturnPathPrefixes.ToHashSet(StringComparer.Ordinal);
 31161        this.SecretBinding = SecretBinding;
 31162        this.IsEnabled = IsEnabled;
 31163    }
 164
 119165    public string ClientId { get; init; } = "";
 64166    public string DisplayName { get; init; } = "";
 43167    public AuthenticationClientType ClientType { get; init; }
 91168    public HashSet<Uri> CallbackUris { get; init; } = new();
 69169    public HashSet<Uri> LogoutCallbackUris { get; init; } = new();
 74170    public HashSet<string> AllowedOrigins { get; init; } = new(StringComparer.Ordinal);
 90171    public HashSet<string> AllowedReturnPathPrefixes { get; init; } = new(StringComparer.Ordinal);
 39172    public SecretBinding? SecretBinding { get; init; }
 64173    public bool IsEnabled { get; init; }
 174
 175    public void Deconstruct(
 176        out string ClientId,
 177        out string DisplayName,
 178        out AuthenticationClientType ClientType,
 179        out IReadOnlySet<Uri> CallbackUris,
 180        out IReadOnlySet<Uri> LogoutCallbackUris,
 181        out IReadOnlySet<string> AllowedOrigins,
 182        out IReadOnlySet<string> AllowedReturnPathPrefixes,
 183        out SecretBinding? SecretBinding,
 184        out bool IsEnabled)
 185    {
 0186        ClientId = this.ClientId;
 0187        DisplayName = this.DisplayName;
 0188        ClientType = this.ClientType;
 0189        CallbackUris = this.CallbackUris;
 0190        LogoutCallbackUris = this.LogoutCallbackUris;
 0191        AllowedOrigins = this.AllowedOrigins;
 0192        AllowedReturnPathPrefixes = this.AllowedReturnPathPrefixes;
 0193        SecretBinding = this.SecretBinding;
 0194        IsEnabled = this.IsEnabled;
 0195    }
 196}
 197
 198public sealed class BrokerTransaction
 199{
 200    public string HandleHash { get; set; } = null!;
 201    public BrokerTransactionPurpose Purpose { get; set; }
 202    public string ClientId { get; set; } = null!;
 203    public Uri CallbackUri { get; set; } = null!;
 204    public string ReturnPath { get; set; } = null!;
 205    /// <summary>
 206    /// Caller-owned opaque state returned only to the registered callback URI.
 207    /// </summary>
 208    public string? ClientState { get; set; }
 209    public string TenantId { get; set; } = null!;
 210    public string? ConnectionId { get; set; }
 211    /// <summary>Logical callback key, retained alongside the immutable in-flight record ID.</summary>
 212    public string? ConnectionKey { get; set; }
 213    public string? ConnectionMaterialRevision { get; set; }
 214    public string? SecretGenerationFingerprint { get; set; }
 215    public string PkceChallenge { get; set; } = null!;
 216    public string? ProviderNonce { get; set; }
 217    public byte[] ProtectedPayload { get; set; } = [];
 218    public DateTimeOffset ExpiresAt { get; set; }
 219    public DateTimeOffset? ConsumedAt { get; set; }
 220}
 221
 222public sealed class AuthorizationGrant
 223{
 224    public string CodeHash { get; set; } = null!;
 225    public string ClientId { get; set; } = null!;
 226    public Uri CallbackUri { get; set; } = null!;
 227    public string TenantId { get; set; } = null!;
 228    public string UserId { get; set; } = null!;
 229    public string? ExternalSessionId { get; set; }
 230    public string PkceChallenge { get; set; } = null!;
 231    public DateTimeOffset ExpiresAt { get; set; }
 232    public DateTimeOffset? ConsumedAt { get; set; }
 233}
 234
 235public sealed class ExternalAuthenticationSession
 236{
 237    public string Id { get; set; } = null!;
 238    public string AuthenticationClientId { get; set; } = null!;
 239    public string TenantId { get; set; } = null!;
 240    public string UserId { get; set; } = null!;
 241    /// <summary>Normalized logical connection key resolved in the session target tenant.</summary>
 242    public string ConnectionKey { get; set; } = null!;
 243    public string ConnectionMaterialRevision { get; set; } = null!;
 244    public string? SecretGenerationFingerprint { get; set; }
 245    public string Issuer { get; set; } = null!;
 246    public string SubjectHash { get; set; } = null!;
 247    public IReadOnlyCollection<PermissionGrant> ExternalGrants { get; set; } = [];
 248    public DateTimeOffset StartedAt { get; set; }
 249    public DateTimeOffset LastRefreshedAt { get; set; }
 250    public DateTimeOffset ExpiresAt { get; set; }
 251    public DateTimeOffset RefreshExpiresAt { get; set; }
 252    /// <summary>The hash of the currently issued refresh token, or <see langword="null"/> until one is issued.</summary
 253    public string? CurrentRefreshTokenHash { get; set; }
 254    public long RefreshGeneration { get; set; }
 255    public DateTimeOffset? RevokedAt { get; set; }
 256    public string? RevocationReason { get; set; }
 257    /// <summary>Data-protected upstream ID-token/logout hint retained only for enabled upstream logout.</summary>
 258    public byte[]? ProtectedUpstreamLogoutHint { get; set; }
 259}
 260
 261/// <summary>Restricts administrative session queries to a single tenant and safe metadata fields.</summary>
 262public sealed class ExternalAuthenticationSessionFilter
 263{
 264    public string TenantId { get; set; } = null!;
 265    public string? UserId { get; set; }
 266    public string? ConnectionKey { get; set; }
 267    /// <summary><c>active</c>, <c>revoked</c>, or null for both.</summary>
 268    public string? Status { get; set; }
 269}
 270
 271public sealed record ConnectionObservation(
 272    string ConnectionId,
 273    string TestedMaterialRevision,
 274    DateTimeOffset ObservedAt,
 275    ConnectionObservationStatus Status,
 276    string Category,
 277    TimeSpan Duration,
 278    string Summary,
 279    IReadOnlyCollection<string> Warnings,
 280    string CorrelationId);
 281
 282public sealed record LoginMethod(string Id, string Key, LoginMethodKind Kind, string DisplayName, string? IconId, int Or
 283
 284public sealed record ExternalIdentityLink(string Id, string TenantId, string ConnectionKey, string Issuer, string Subjec
 285
 286public sealed class ExternalIdentityLinkFilter
 287{
 288    public string TenantId { get; set; } = null!;
 289    public string? UserId { get; set; }
 290    public string? ConnectionKey { get; set; }
 291}
 292
 293public sealed record PreviewResult(
 294    string HandleHash,
 295    string AdministratorId,
 296    string TenantId,
 297    string ConnectionId,
 298    string MaterialRevision,
 299    string Issuer,
 300    string MaskedSubject,
 301    IReadOnlyDictionary<string, IReadOnlyCollection<string>> ProjectedClaims,
 302    string PolicyDecision,
 303    IReadOnlyCollection<PermissionGrant> PermissionProjection,
 304    IReadOnlyCollection<string> Warnings,
 305    DateTimeOffset ExpiresAt,
 306    DateTimeOffset? ConsumedAt);
 307
 308public sealed class ConnectionFilter
 309{
 310    public string? Search { get; set; }
 311    public ConnectionSourceOwnership? Ownership { get; set; }
 312    public ConnectionScope? Scope { get; set; }
 313    public string? AdapterType { get; set; }
 314    public bool? IsEnabled { get; set; }
 315    public bool? IsArchived { get; set; }
 316}
 317
 318public abstract record ConnectionMutationResult
 319{
 320    private ConnectionMutationResult() { }
 321    public sealed record Created(IdentityProviderConnection Connection) : ConnectionMutationResult;
 322    public sealed record Updated(IdentityProviderConnection Connection) : ConnectionMutationResult;
 323    public sealed record NotFound : ConnectionMutationResult;
 324    public sealed record DuplicateKey : ConnectionMutationResult;
 325    public sealed record RevisionConflict(long CurrentRevision) : ConnectionMutationResult;
 326}