< Summary

Information
Class: Elsa.ExternalAuthentication.Models.ConnectionObservation
Assembly: Elsa.ExternalAuthentication
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.ExternalAuthentication/Models/ExternalAuthenticationModels.cs
Line coverage
100%
Covered lines: 10
Uncovered lines: 0
Coverable lines: 10
Total lines: 326
Line coverage: 100%
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%
get_ConnectionId()100%11100%
get_TestedMaterialRevision()100%11100%
get_ObservedAt()100%11100%
get_Status()100%11100%
get_Category()100%11100%
get_Duration()100%11100%
get_Summary()100%11100%
get_Warnings()100%11100%
get_CorrelationId()100%11100%

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{
 139    public AuthenticationClient()
 140    {
 141    }
 142
 143    public AuthenticationClient(
 144        string ClientId,
 145        string DisplayName,
 146        AuthenticationClientType ClientType,
 147        IReadOnlySet<Uri> CallbackUris,
 148        IReadOnlySet<Uri> LogoutCallbackUris,
 149        IReadOnlySet<string> AllowedOrigins,
 150        IReadOnlySet<string> AllowedReturnPathPrefixes,
 151        SecretBinding? SecretBinding,
 152        bool IsEnabled)
 153    {
 154        this.ClientId = ClientId;
 155        this.DisplayName = DisplayName;
 156        this.ClientType = ClientType;
 157        this.CallbackUris = CallbackUris.ToHashSet();
 158        this.LogoutCallbackUris = LogoutCallbackUris.ToHashSet();
 159        this.AllowedOrigins = AllowedOrigins.ToHashSet(StringComparer.Ordinal);
 160        this.AllowedReturnPathPrefixes = AllowedReturnPathPrefixes.ToHashSet(StringComparer.Ordinal);
 161        this.SecretBinding = SecretBinding;
 162        this.IsEnabled = IsEnabled;
 163    }
 164
 165    public string ClientId { get; init; } = "";
 166    public string DisplayName { get; init; } = "";
 167    public AuthenticationClientType ClientType { get; init; }
 168    public HashSet<Uri> CallbackUris { get; init; } = new();
 169    public HashSet<Uri> LogoutCallbackUris { get; init; } = new();
 170    public HashSet<string> AllowedOrigins { get; init; } = new(StringComparer.Ordinal);
 171    public HashSet<string> AllowedReturnPathPrefixes { get; init; } = new(StringComparer.Ordinal);
 172    public SecretBinding? SecretBinding { get; init; }
 173    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    {
 186        ClientId = this.ClientId;
 187        DisplayName = this.DisplayName;
 188        ClientType = this.ClientType;
 189        CallbackUris = this.CallbackUris;
 190        LogoutCallbackUris = this.LogoutCallbackUris;
 191        AllowedOrigins = this.AllowedOrigins;
 192        AllowedReturnPathPrefixes = this.AllowedReturnPathPrefixes;
 193        SecretBinding = this.SecretBinding;
 194        IsEnabled = this.IsEnabled;
 195    }
 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
 7271public sealed record ConnectionObservation(
 11272    string ConnectionId,
 8273    string TestedMaterialRevision,
 5274    DateTimeOffset ObservedAt,
 5275    ConnectionObservationStatus Status,
 3276    string Category,
 1277    TimeSpan Duration,
 4278    string Summary,
 1279    IReadOnlyCollection<string> Warnings,
 8280    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}